blob: c6af6ca4ba1d00fb989ebc80a461a0f73d344f89 [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)
shane.xb.qianc673b802024-12-20 19:36:40 +010045" 2024 Dec 20 by Vim Project: change style continued (#16266)
Travis Sheltone34d0e32024-07-30 21:08:56 +020046" }}}
Luca Saccarolac363ca12024-12-19 20:16:18 +010047" Former Maintainer: Charles E Campbell
Bram Moolenaar5b8d8fd2005-08-16 23:01:50 +000048" GetLatestVimScripts: 1075 1 :AutoInstall: netrw.vim
Bram Moolenaare0fa3742016-02-20 15:47:01 +010049" Copyright: Copyright (C) 2016 Charles E. Campbell {{{1
Bram Moolenaar572cb562005-08-05 21:35:02 +000050" Permission is hereby granted to use and distribute this code,
51" with or without modifications, provided that this copyright
52" notice is copied with it. Like anything else that's free,
Bram Moolenaar1afcace2005-11-25 19:54:28 +000053" netrw.vim, netrwPlugin.vim, and netrwSettings.vim are provided
Bram Moolenaar446cb832008-06-24 21:56:24 +000054" *as is* and come with no warranty of any kind, either
Bram Moolenaar1afcace2005-11-25 19:54:28 +000055" expressed or implied. By using this plugin, you agree that
56" in no event will the copyright holder be liable for any damages
57" resulting from the use of this software.
Bram Moolenaar91359012019-11-30 17:57:03 +010058"
59" Note: the code here was started in 1999 under a much earlier version of vim. The directory browsing
60" code was written using vim v6, which did not have Lists (Lists were first offered with vim-v7).
61"
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +020062"redraw!|call DechoSep()|call inputsave()|call input("Press <cr> to continue")|call inputrestore()
Bram Moolenaar071d4272004-06-13 20:20:40 +000063"
Bram Moolenaar5b8d8fd2005-08-16 23:01:50 +000064" But be doers of the Word, and not only hearers, deluding your own selves {{{1
Bram Moolenaar071d4272004-06-13 20:20:40 +000065" (James 1:22 RSV)
66" =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Bram Moolenaar9964e462007-05-05 17:54:07 +000067" Load Once: {{{1
Bram Moolenaar1afcace2005-11-25 19:54:28 +000068if &cp || exists("g:loaded_netrw")
69 finish
70endif
Bram Moolenaar85850f32019-07-19 22:05:51 +020071
72" Check that vim has patches that netrw requires.
73" Patches needed for v7.4: 1557, and 213.
74" (netrw will benefit from vim's having patch#656, too)
75let s:needspatches=[1557,213]
76if exists("s:needspatches")
Luca Saccarolac363ca12024-12-19 20:16:18 +010077 for ptch in s:needspatches
78 if v:version < 704 || (v:version == 704 && !has("patch".ptch))
79 if !exists("s:needpatch{ptch}")
80 unsilent echomsg "***sorry*** this version of netrw requires vim v7.4 with patch#".ptch
81 endif
82 let s:needpatch{ptch}= 1
83 finish
84 endif
85 endfor
Bram Moolenaar13600302014-05-22 18:26:40 +020086endif
Bram Moolenaar85850f32019-07-19 22:05:51 +020087
Bram Moolenaarb7398fe2023-05-14 18:50:25 +010088let g:loaded_netrw = "v173"
Bram Moolenaar446cb832008-06-24 21:56:24 +000089
Bram Moolenaar1afcace2005-11-25 19:54:28 +000090let s:keepcpo= &cpo
Bram Moolenaara6878372014-03-22 21:02:50 +010091setl cpo&vim
Bram Moolenaar85850f32019-07-19 22:05:51 +020092"DechoFuncName 1
Bram Moolenaar8d043172014-01-23 14:24:41 +010093"DechoRemOn
Bram Moolenaara0f849e2015-10-30 14:37:44 +010094"call Decho("doing autoload/netrw.vim version ".g:loaded_netrw,'~'.expand("<slnum>"))
Bram Moolenaar071d4272004-06-13 20:20:40 +000095
Bram Moolenaarafeb4fa2006-02-01 21:51:12 +000096" ======================
97" Netrw Variables: {{{1
98" ======================
99
Bram Moolenaar071d4272004-06-13 20:20:40 +0000100" ---------------------------------------------------------------------
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200101" netrw#ErrorMsg: {{{2
102" 0=note = s:NOTE
103" 1=warning = s:WARNING
104" 2=error = s:ERROR
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100105" Usage: netrw#ErrorMsg(s:NOTE | s:WARNING | s:ERROR,"some message",error-number)
106" netrw#ErrorMsg(s:NOTE | s:WARNING | s:ERROR,["message1","message2",...],error-number)
107" (this function can optionally take a list of messages)
Bram Moolenaar29634562020-01-09 21:46:04 +0100108" Dec 2, 2019 : max errnum currently is 106
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200109fun! netrw#ErrorMsg(level,msg,errnum)
Luca Saccarolac363ca12024-12-19 20:16:18 +0100110 " 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 +0200111
112 if a:level < g:netrw_errorlvl
Luca Saccarolac363ca12024-12-19 20:16:18 +0100113 " call Dret("netrw#ErrorMsg : suppressing level=".a:level." since g:netrw_errorlvl=".g:netrw_errorlvl)
114 return
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200115 endif
116
117 if a:level == 1
Luca Saccarolac363ca12024-12-19 20:16:18 +0100118 let level= "**warning** (netrw) "
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200119 elseif a:level == 2
Luca Saccarolac363ca12024-12-19 20:16:18 +0100120 let level= "**error** (netrw) "
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200121 else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100122 let level= "**note** (netrw) "
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200123 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +0100124 " call Decho("level=".level,'~'.expand("<slnum>"))
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200125
Damienb4d11642024-08-15 22:00:45 +0200126 if g:netrw_use_errorwindow == 2 && exists("*popup_atcursor")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100127 " use popup window
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100128 if type(a:msg) == 3
Luca Saccarolac363ca12024-12-19 20:16:18 +0100129 let msg = [level]+a:msg
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100130 else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100131 let msg= level.a:msg
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100132 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +0100133 let s:popuperr_id = popup_atcursor(msg,{})
134 let s:popuperr_text= ""
135 elseif g:netrw_use_errorwindow
136 " (default) netrw creates a one-line window to show error/warning
137 " messages (reliably displayed)
138
139 " record current window number
140 let s:winBeforeErr= winnr()
141 " call Decho("s:winBeforeErr=".s:winBeforeErr,'~'.expand("<slnum>"))
142
143 " getting messages out reliably is just plain difficult!
144 " This attempt splits the current window, creating a one line window.
145 if bufexists("NetrwMessage") && bufwinnr("NetrwMessage") > 0
146 " call Decho("write to NetrwMessage buffer",'~'.expand("<slnum>"))
147 exe bufwinnr("NetrwMessage")."wincmd w"
148 " call Decho("setl ma noro",'~'.expand("<slnum>"))
149 setl ma noro
150 if type(a:msg) == 3
151 for msg in a:msg
152 NetrwKeepj call setline(line("$")+1,level.msg)
153 endfor
154 else
155 NetrwKeepj call setline(line("$")+1,level.a:msg)
156 endif
157 NetrwKeepj $
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100158 else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100159 " call Decho("create a NetrwMessage buffer window",'~'.expand("<slnum>"))
160 bo 1split
161 sil! call s:NetrwEnew()
162 sil! NetrwKeepj call s:NetrwOptionsSafe(1)
163 setl bt=nofile
164 NetrwKeepj file NetrwMessage
165 " call Decho("setl ma noro",'~'.expand("<slnum>"))
166 setl ma noro
167 if type(a:msg) == 3
168 for msg in a:msg
169 NetrwKeepj call setline(line("$")+1,level.msg)
170 endfor
171 else
172 NetrwKeepj call setline(line("$"),level.a:msg)
173 endif
174 NetrwKeepj $
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100175 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +0100176 " call Decho("wrote msg<".level.a:msg."> to NetrwMessage win#".winnr(),'~'.expand("<slnum>"))
177 if &fo !~ '[ta]'
178 syn clear
179 syn match netrwMesgNote "^\*\*note\*\*"
180 syn match netrwMesgWarning "^\*\*warning\*\*"
181 syn match netrwMesgError "^\*\*error\*\*"
182 hi link netrwMesgWarning WarningMsg
183 hi link netrwMesgError Error
184 endif
185 " call Decho("setl noma ro bh=wipe",'~'.expand("<slnum>"))
186 setl ro nomod noma bh=wipe
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200187
188 else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100189 " (optional) netrw will show messages using echomsg. Even if the
190 " message doesn't appear, at least it'll be recallable via :messages
191 " redraw!
192 if a:level == s:WARNING
193 echohl WarningMsg
194 elseif a:level == s:ERROR
195 echohl Error
196 endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100197
Luca Saccarolac363ca12024-12-19 20:16:18 +0100198 if type(a:msg) == 3
199 for msg in a:msg
200 unsilent echomsg level.msg
201 endfor
202 else
203 unsilent echomsg level.a:msg
204 endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100205
Luca Saccarolac363ca12024-12-19 20:16:18 +0100206 " call Decho("echomsg ***netrw*** ".a:msg,'~'.expand("<slnum>"))
207 echohl None
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200208 endif
209
Luca Saccarolac363ca12024-12-19 20:16:18 +0100210 " call Dret("netrw#ErrorMsg")
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200211endfun
212
213" ---------------------------------------------------------------------
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100214" s:NetrwInit: initializes variables if they haven't been defined {{{2
Bram Moolenaar5c736222010-01-06 20:54:52 +0100215" Loosely, varname = value.
216fun s:NetrwInit(varname,value)
Luca Saccarolac363ca12024-12-19 20:16:18 +0100217 " call Decho("varname<".a:varname."> value=".a:value,'~'.expand("<slnum>"))
Bram Moolenaar5c736222010-01-06 20:54:52 +0100218 if !exists(a:varname)
Luca Saccarolac363ca12024-12-19 20:16:18 +0100219 if type(a:value) == 0
220 exe "let ".a:varname."=".a:value
221 elseif type(a:value) == 1 && a:value =~ '^[{[]'
222 exe "let ".a:varname."=".a:value
223 elseif type(a:value) == 1
224 exe "let ".a:varname."="."'".a:value."'"
225 else
226 exe "let ".a:varname."=".a:value
227 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100228 endif
229endfun
230
231" ---------------------------------------------------------------------
Bram Moolenaar9964e462007-05-05 17:54:07 +0000232" Netrw Constants: {{{2
Bram Moolenaar85850f32019-07-19 22:05:51 +0200233call s:NetrwInit("g:netrw_dirhistcnt",0)
Bram Moolenaar9964e462007-05-05 17:54:07 +0000234if !exists("s:LONGLIST")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100235 call s:NetrwInit("s:THINLIST",0)
236 call s:NetrwInit("s:LONGLIST",1)
237 call s:NetrwInit("s:WIDELIST",2)
238 call s:NetrwInit("s:TREELIST",3)
239 call s:NetrwInit("s:MAXLIST" ,4)
Bram Moolenaar9964e462007-05-05 17:54:07 +0000240endif
241
Damien7c754112024-08-15 21:58:57 +0200242let s:NOTE = 0
243let s:WARNING = 1
244let s:ERROR = 2
245call s:NetrwInit("g:netrw_errorlvl", s:NOTE)
246
Bram Moolenaar9964e462007-05-05 17:54:07 +0000247" ---------------------------------------------------------------------
Bram Moolenaar85850f32019-07-19 22:05:51 +0200248" Default option values: {{{2
249let g:netrw_localcopycmdopt = ""
250let g:netrw_localcopydircmdopt = ""
251let g:netrw_localmkdiropt = ""
252let g:netrw_localmovecmdopt = ""
Bram Moolenaar85850f32019-07-19 22:05:51 +0200253
254" ---------------------------------------------------------------------
Bram Moolenaarafeb4fa2006-02-01 21:51:12 +0000255" Default values for netrw's global protocol variables {{{2
Damienb4d11642024-08-15 22:00:45 +0200256if exists("*popup_atcursor")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100257 \ && has("syntax")
258 \ && exists("g:syntax_on")
259 \ && has("mouse")
Bram Moolenaar1d59aa12020-09-19 18:50:13 +0200260 call s:NetrwInit("g:netrw_use_errorwindow",2)
261else
262 call s:NetrwInit("g:netrw_use_errorwindow",1)
263endif
Bram Moolenaaradc21822011-04-01 18:03:16 +0200264
Bram Moolenaar1afcace2005-11-25 19:54:28 +0000265if !exists("g:netrw_dav_cmd")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100266 if executable("cadaver")
267 let g:netrw_dav_cmd = "cadaver"
268 elseif executable("curl")
269 let g:netrw_dav_cmd = "curl"
270 else
271 let g:netrw_dav_cmd = ""
272 endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000273endif
Bram Moolenaar1afcace2005-11-25 19:54:28 +0000274if !exists("g:netrw_fetch_cmd")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100275 if executable("fetch")
276 let g:netrw_fetch_cmd = "fetch -o"
277 else
278 let g:netrw_fetch_cmd = ""
279 endif
Bram Moolenaar1afcace2005-11-25 19:54:28 +0000280endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100281if !exists("g:netrw_file_cmd")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100282 if executable("elinks")
283 call s:NetrwInit("g:netrw_file_cmd","elinks")
284 elseif executable("links")
285 call s:NetrwInit("g:netrw_file_cmd","links")
286 endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100287endif
Bram Moolenaar1afcace2005-11-25 19:54:28 +0000288if !exists("g:netrw_ftp_cmd")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100289 let g:netrw_ftp_cmd = "ftp"
Bram Moolenaar1afcace2005-11-25 19:54:28 +0000290endif
Bram Moolenaaradc21822011-04-01 18:03:16 +0200291let s:netrw_ftp_cmd= g:netrw_ftp_cmd
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200292if !exists("g:netrw_ftp_options")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100293 let g:netrw_ftp_options= "-i -n"
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200294endif
Bram Moolenaar1afcace2005-11-25 19:54:28 +0000295if !exists("g:netrw_http_cmd")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100296 if executable("wget")
297 let g:netrw_http_cmd = "wget"
298 call s:NetrwInit("g:netrw_http_xcmd","-q -O")
299 elseif executable("curl")
300 let g:netrw_http_cmd = "curl"
301 call s:NetrwInit("g:netrw_http_xcmd","-L -o")
302 elseif executable("elinks")
303 let g:netrw_http_cmd = "elinks"
304 call s:NetrwInit("g:netrw_http_xcmd","-source >")
305 elseif executable("fetch")
306 let g:netrw_http_cmd = "fetch"
307 call s:NetrwInit("g:netrw_http_xcmd","-o")
308 elseif executable("links")
309 let g:netrw_http_cmd = "links"
310 call s:NetrwInit("g:netrw_http_xcmd","-http.extra-header ".shellescape("Accept-Encoding: identity", 1)." -source >")
311 else
312 let g:netrw_http_cmd = ""
313 endif
Bram Moolenaar1afcace2005-11-25 19:54:28 +0000314endif
Bram Moolenaar8d043172014-01-23 14:24:41 +0100315call s:NetrwInit("g:netrw_http_put_cmd","curl -T")
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100316call s:NetrwInit("g:netrw_keepj","keepj")
Bram Moolenaar5c736222010-01-06 20:54:52 +0100317call s:NetrwInit("g:netrw_rcp_cmd" , "rcp")
318call s:NetrwInit("g:netrw_rsync_cmd", "rsync")
Bram Moolenaar85850f32019-07-19 22:05:51 +0200319call s:NetrwInit("g:netrw_rsync_sep", "/")
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200320if !exists("g:netrw_scp_cmd")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100321 if executable("scp")
322 call s:NetrwInit("g:netrw_scp_cmd" , "scp -q")
323 elseif executable("pscp")
324 call s:NetrwInit("g:netrw_scp_cmd", 'pscp -q')
325 else
326 call s:NetrwInit("g:netrw_scp_cmd" , "scp -q")
327 endif
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200328endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100329call s:NetrwInit("g:netrw_sftp_cmd" , "sftp")
330call s:NetrwInit("g:netrw_ssh_cmd" , "ssh")
Bram Moolenaar1afcace2005-11-25 19:54:28 +0000331
Nir Lichtman1e34b952024-05-08 19:19:34 +0200332if has("win32")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100333 \ && exists("g:netrw_use_nt_rcp")
334 \ && g:netrw_use_nt_rcp
335 \ && executable( $SystemRoot .'/system32/rcp.exe')
336 let s:netrw_has_nt_rcp = 1
337 let s:netrw_rcpmode = '-b'
Bram Moolenaar9964e462007-05-05 17:54:07 +0000338else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100339 let s:netrw_has_nt_rcp = 0
340 let s:netrw_rcpmode = ''
Bram Moolenaar1afcace2005-11-25 19:54:28 +0000341endif
342
343" ---------------------------------------------------------------------
Bram Moolenaarafeb4fa2006-02-01 21:51:12 +0000344" Default values for netrw's global variables {{{2
Bram Moolenaar446cb832008-06-24 21:56:24 +0000345" Cygwin Detection ------- {{{3
346if !exists("g:netrw_cygwin")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100347 if has("win32unix") && &shell =~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$'
348 let g:netrw_cygwin= 1
349 else
350 let g:netrw_cygwin= 0
351 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +0000352endif
Bram Moolenaarafeb4fa2006-02-01 21:51:12 +0000353" Default values - a-c ---------- {{{3
Bram Moolenaar5c736222010-01-06 20:54:52 +0100354call s:NetrwInit("g:netrw_alto" , &sb)
355call s:NetrwInit("g:netrw_altv" , &spr)
356call s:NetrwInit("g:netrw_banner" , 1)
357call s:NetrwInit("g:netrw_browse_split", 0)
Bram Moolenaar13600302014-05-22 18:26:40 +0200358call s:NetrwInit("g:netrw_bufsettings" , "noma nomod nonu nobl nowrap ro nornu")
Bram Moolenaar5c736222010-01-06 20:54:52 +0100359call s:NetrwInit("g:netrw_chgwin" , -1)
Bram Moolenaar89a9c152021-08-29 21:55:35 +0200360call s:NetrwInit("g:netrw_clipboard" , 1)
Bram Moolenaar5c736222010-01-06 20:54:52 +0100361call s:NetrwInit("g:netrw_compress" , "gzip")
362call s:NetrwInit("g:netrw_ctags" , "ctags")
Bram Moolenaaradc21822011-04-01 18:03:16 +0200363if exists("g:netrw_cursorline") && !exists("g:netrw_cursor")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100364 call netrw#ErrorMsg(s:NOTE,'g:netrw_cursorline is deprecated; use g:netrw_cursor instead',77)
365 let g:netrw_cursor= g:netrw_cursorline
Bram Moolenaar446cb832008-06-24 21:56:24 +0000366endif
Bram Moolenaaradc21822011-04-01 18:03:16 +0200367call s:NetrwInit("g:netrw_cursor" , 2)
368let s:netrw_usercul = &cursorline
369let s:netrw_usercuc = &cursorcolumn
Bram Moolenaar89a9c152021-08-29 21:55:35 +0200370"call Decho("(netrw) COMBAK: cuc=".&l:cuc." cul=".&l:cul." initialization of s:netrw_cu[cl]")
Bram Moolenaar8d043172014-01-23 14:24:41 +0100371call s:NetrwInit("g:netrw_cygdrive","/cygdrive")
Bram Moolenaar446cb832008-06-24 21:56:24 +0000372" Default values - d-g ---------- {{{3
Bram Moolenaarff034192013-04-24 18:51:19 +0200373call s:NetrwInit("s:didstarstar",0)
Bram Moolenaar85850f32019-07-19 22:05:51 +0200374call s:NetrwInit("g:netrw_dirhistcnt" , 0)
Christian Brabandtcacfccf2024-11-23 13:28:01 +0100375let s:xz_opt = has('unix') ? "XZ_OPT=-T0" :
Luca Saccarolac363ca12024-12-19 20:16:18 +0100376 \ (has("win32") && &shell =~? '\vcmd(\.exe)?$' ?
377 \ "setx XZ_OPT=-T0 &&" : "")
Christian Brabandtcacfccf2024-11-23 13:28:01 +0100378call s:NetrwInit("g:netrw_decompress ", "{"
Luca Saccarolac363ca12024-12-19 20:16:18 +0100379 \ .."'.lz4': 'lz4 -d',"
380 \ .."'.lzo': 'lzop -d',"
381 \ .."'.lz': 'lzip -dk',"
382 \ .."'.7z': '7za x',"
383 \ .."'.001': '7za x',"
384 \ .."'.zip': 'unzip',"
385 \ .."'.bz': 'bunzip2 -k',"
386 \ .."'.bz2': 'bunzip2 -k',"
387 \ .."'.gz': 'gunzip -k',"
388 \ .."'.lzma': 'unlzma -T0 -k',"
389 \ .."'.xz': 'unxz -T0 -k',"
390 \ .."'.zst': 'zstd -T0 -d',"
391 \ .."'.Z': 'uncompress -k',"
392 \ .."'.tar': 'tar -xvf',"
393 \ .."'.tar.bz': 'tar -xvjf',"
394 \ .."'.tar.bz2': 'tar -xvjf',"
395 \ .."'.tbz': 'tar -xvjf',"
396 \ .."'.tbz2': 'tar -xvjf',"
397 \ .."'.tar.gz': 'tar -xvzf',"
398 \ .."'.tgz': 'tar -xvzf',"
399 \ .."'.tar.lzma': '"..s:xz_opt.." tar -xvf --lzma',"
400 \ .."'.tlz': '"..s:xz_opt.." tar -xvf --lzma',"
401 \ .."'.tar.xz': '"..s:xz_opt.." tar -xvfJ',"
402 \ .."'.txz': '"..s:xz_opt.." tar -xvfJ',"
403 \ .."'.tar.zst': '"..s:xz_opt.." tar -xvf --use-compress-program=unzstd',"
404 \ .."'.tzst': '"..s:xz_opt.." tar -xvf --use-compress-program=unzstd',"
405 \ .."'.rar': '"..(executable("unrar")?"unrar x -ad":"rar x -ad").."'"
406 \ .."}")
Christian Brabandtcacfccf2024-11-23 13:28:01 +0100407unlet s:xz_opt
Bram Moolenaar5c736222010-01-06 20:54:52 +0100408call s:NetrwInit("g:netrw_dirhistmax" , 10)
409call s:NetrwInit("g:netrw_fastbrowse" , 1)
410call 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 +0000411if !exists("g:netrw_ftp_list_cmd")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100412 if has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin)
413 let g:netrw_ftp_list_cmd = "ls -lF"
414 let g:netrw_ftp_timelist_cmd = "ls -tlF"
415 let g:netrw_ftp_sizelist_cmd = "ls -slF"
416 else
417 let g:netrw_ftp_list_cmd = "dir"
418 let g:netrw_ftp_timelist_cmd = "dir"
419 let g:netrw_ftp_sizelist_cmd = "dir"
420 endif
Bram Moolenaarc0197e22004-09-13 20:26:32 +0000421endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100422call s:NetrwInit("g:netrw_ftpmode",'binary')
Bram Moolenaarafeb4fa2006-02-01 21:51:12 +0000423" Default values - h-lh ---------- {{{3
Bram Moolenaar5c736222010-01-06 20:54:52 +0100424call s:NetrwInit("g:netrw_hide",1)
Bram Moolenaar9964e462007-05-05 17:54:07 +0000425if !exists("g:netrw_ignorenetrc")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100426 if &shell =~ '\c\<\%(cmd\|4nt\)\.exe$'
427 let g:netrw_ignorenetrc= 1
428 else
429 let g:netrw_ignorenetrc= 0
430 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +0000431endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100432call s:NetrwInit("g:netrw_keepdir",1)
Bram Moolenaar1afcace2005-11-25 19:54:28 +0000433if !exists("g:netrw_list_cmd")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100434 if g:netrw_scp_cmd =~ '^pscp' && executable("pscp")
435 if exists("g:netrw_list_cmd_options")
436 let g:netrw_list_cmd= g:netrw_scp_cmd." -ls USEPORT HOSTNAME: ".g:netrw_list_cmd_options
437 else
438 let g:netrw_list_cmd= g:netrw_scp_cmd." -ls USEPORT HOSTNAME:"
439 endif
440 elseif executable(g:netrw_ssh_cmd)
441 " provide a scp-based default listing command
442 if exists("g:netrw_list_cmd_options")
443 let g:netrw_list_cmd= g:netrw_ssh_cmd." USEPORT HOSTNAME ls -FLa ".g:netrw_list_cmd_options
444 else
445 let g:netrw_list_cmd= g:netrw_ssh_cmd." USEPORT HOSTNAME ls -FLa"
446 endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100447 else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100448 " call Decho(g:netrw_ssh_cmd." is not executable",'~'.expand("<slnum>"))
449 let g:netrw_list_cmd= ""
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100450 endif
Bram Moolenaar1afcace2005-11-25 19:54:28 +0000451endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100452call s:NetrwInit("g:netrw_list_hide","")
Bram Moolenaarafeb4fa2006-02-01 21:51:12 +0000453" Default values - lh-lz ---------- {{{3
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200454if exists("g:netrw_local_copycmd")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100455 let g:netrw_localcopycmd= g:netrw_local_copycmd
456 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 +0200457endif
Bram Moolenaar97d62492012-11-15 21:28:22 +0100458if !exists("g:netrw_localcmdshell")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100459 let g:netrw_localcmdshell= ""
Bram Moolenaar97d62492012-11-15 21:28:22 +0100460endif
Bram Moolenaar446cb832008-06-24 21:56:24 +0000461if !exists("g:netrw_localcopycmd")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100462 if has("win32")
463 if g:netrw_cygwin
464 let g:netrw_localcopycmd= "cp"
465 else
466 let g:netrw_localcopycmd = expand("$COMSPEC", v:true)
467 let g:netrw_localcopycmdopt= " /c copy"
468 endif
469 elseif has("unix") || has("macunix")
470 let g:netrw_localcopycmd= "cp"
Bram Moolenaar446cb832008-06-24 21:56:24 +0000471 else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100472 let g:netrw_localcopycmd= ""
Bram Moolenaar446cb832008-06-24 21:56:24 +0000473 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +0000474endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100475if !exists("g:netrw_localcopydircmd")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100476 if has("win32")
477 if g:netrw_cygwin
478 let g:netrw_localcopydircmd = "cp"
479 let g:netrw_localcopydircmdopt= " -R"
480 else
481 let g:netrw_localcopydircmd = expand("$COMSPEC", v:true)
482 let g:netrw_localcopydircmdopt= " /c xcopy /e /c /h /i /k"
483 endif
484 elseif has("unix")
485 let g:netrw_localcopydircmd = "cp"
486 let g:netrw_localcopydircmdopt= " -R"
487 elseif has("macunix")
488 let g:netrw_localcopydircmd = "cp"
489 let g:netrw_localcopydircmdopt= " -R"
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100490 else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100491 let g:netrw_localcopydircmd= ""
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100492 endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100493endif
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200494if exists("g:netrw_local_mkdir")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100495 let g:netrw_localmkdir= g:netrw_local_mkdir
496 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 +0200497endif
Nir Lichtman1e34b952024-05-08 19:19:34 +0200498if has("win32")
Bram Moolenaar13600302014-05-22 18:26:40 +0200499 if g:netrw_cygwin
Luca Saccarolac363ca12024-12-19 20:16:18 +0100500 call s:NetrwInit("g:netrw_localmkdir","mkdir")
Bram Moolenaar13600302014-05-22 18:26:40 +0200501 else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100502 let g:netrw_localmkdir = expand("$COMSPEC", v:true)
503 let g:netrw_localmkdiropt= " /c mkdir"
Bram Moolenaar13600302014-05-22 18:26:40 +0200504 endif
505else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100506 call s:NetrwInit("g:netrw_localmkdir","mkdir")
Bram Moolenaar13600302014-05-22 18:26:40 +0200507endif
Bram Moolenaar15146672011-10-20 22:22:38 +0200508call s:NetrwInit("g:netrw_remote_mkdir","mkdir")
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200509if exists("g:netrw_local_movecmd")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100510 let g:netrw_localmovecmd= g:netrw_local_movecmd
511 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 +0200512endif
Bram Moolenaar446cb832008-06-24 21:56:24 +0000513if !exists("g:netrw_localmovecmd")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100514 if has("win32")
515 if g:netrw_cygwin
516 let g:netrw_localmovecmd= "mv"
517 else
518 let g:netrw_localmovecmd = expand("$COMSPEC", v:true)
519 let g:netrw_localmovecmdopt= " /c move"
520 endif
521 elseif has("unix") || has("macunix")
522 let g:netrw_localmovecmd= "mv"
Bram Moolenaar446cb832008-06-24 21:56:24 +0000523 else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100524 let g:netrw_localmovecmd= ""
Bram Moolenaar446cb832008-06-24 21:56:24 +0000525 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +0000526endif
Bram Moolenaar29634562020-01-09 21:46:04 +0100527" following serves as an example for how to insert a version&patch specific test
528"if v:version < 704 || (v:version == 704 && !has("patch1107"))
529"endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100530call s:NetrwInit("g:netrw_liststyle" , s:THINLIST)
531" sanity checks
Bram Moolenaar9964e462007-05-05 17:54:07 +0000532if g:netrw_liststyle < 0 || g:netrw_liststyle >= s:MAXLIST
Luca Saccarolac363ca12024-12-19 20:16:18 +0100533 let g:netrw_liststyle= s:THINLIST
Bram Moolenaar1afcace2005-11-25 19:54:28 +0000534endif
Bram Moolenaar9964e462007-05-05 17:54:07 +0000535if g:netrw_liststyle == s:LONGLIST && g:netrw_scp_cmd !~ '^pscp'
Luca Saccarolac363ca12024-12-19 20:16:18 +0100536 let g:netrw_list_cmd= g:netrw_list_cmd." -l"
Bram Moolenaar1afcace2005-11-25 19:54:28 +0000537endif
Bram Moolenaarafeb4fa2006-02-01 21:51:12 +0000538" Default values - m-r ---------- {{{3
Bram Moolenaar5c736222010-01-06 20:54:52 +0100539call s:NetrwInit("g:netrw_markfileesc" , '*./[\~')
540call s:NetrwInit("g:netrw_maxfilenamelen", 32)
541call s:NetrwInit("g:netrw_menu" , 1)
542call s:NetrwInit("g:netrw_mkdir_cmd" , g:netrw_ssh_cmd." USEPORT HOSTNAME mkdir")
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +0200543call s:NetrwInit("g:netrw_mousemaps" , (exists("+mouse") && &mouse =~# '[anh]'))
Bram Moolenaar5c736222010-01-06 20:54:52 +0100544call s:NetrwInit("g:netrw_retmap" , 0)
545if has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin)
Luca Saccarolac363ca12024-12-19 20:16:18 +0100546 call s:NetrwInit("g:netrw_chgperm" , "chmod PERM FILENAME")
Nir Lichtman1e34b952024-05-08 19:19:34 +0200547elseif has("win32")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100548 call s:NetrwInit("g:netrw_chgperm" , "cacls FILENAME /e /p PERM")
Bram Moolenaar5c736222010-01-06 20:54:52 +0100549else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100550 call s:NetrwInit("g:netrw_chgperm" , "chmod PERM FILENAME")
Bram Moolenaar446cb832008-06-24 21:56:24 +0000551endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100552call s:NetrwInit("g:netrw_preview" , 0)
553call s:NetrwInit("g:netrw_scpport" , "-P")
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100554call s:NetrwInit("g:netrw_servername" , "NETRWSERVER")
Bram Moolenaar5c736222010-01-06 20:54:52 +0100555call s:NetrwInit("g:netrw_sshport" , "-p")
556call s:NetrwInit("g:netrw_rename_cmd" , g:netrw_ssh_cmd." USEPORT HOSTNAME mv")
557call s:NetrwInit("g:netrw_rm_cmd" , g:netrw_ssh_cmd." USEPORT HOSTNAME rm")
558call s:NetrwInit("g:netrw_rmdir_cmd" , g:netrw_ssh_cmd." USEPORT HOSTNAME rmdir")
Bram Moolenaara6878372014-03-22 21:02:50 +0100559call s:NetrwInit("g:netrw_rmf_cmd" , g:netrw_ssh_cmd." USEPORT HOSTNAME rm -f ")
560" Default values - q-s ---------- {{{3
561call s:NetrwInit("g:netrw_quickhelp",0)
562let s:QuickHelp= ["-:go up dir D:delete R:rename s:sort-by x:special",
Luca Saccarolac363ca12024-12-19 20:16:18 +0100563 \ "(create new) %:file d:directory",
564 \ "(windows split&open) o:horz v:vert p:preview",
565 \ "i:style qf:file info O:obtain r:reverse",
566 \ "(marks) mf:mark file mt:set target mm:move mc:copy",
567 \ "(bookmarks) mb:make mB:delete qb:list gb:go to",
568 \ "(history) qb:list u:go up U:go down",
569 \ "(targets) mt:target Tb:use bookmark Th:use history"]
Bram Moolenaar5c736222010-01-06 20:54:52 +0100570" g:netrw_sepchr: picking a character that doesn't appear in filenames that can be used to separate priority from filename
571call s:NetrwInit("g:netrw_sepchr" , (&enc == "euc-jp")? "\<Char-0x01>" : "\<Char-0xff>")
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100572if !exists("g:netrw_keepj") || g:netrw_keepj == "keepj"
Luca Saccarolac363ca12024-12-19 20:16:18 +0100573 call s:NetrwInit("s:netrw_silentxfer" , (exists("g:netrw_silent") && g:netrw_silent != 0)? "sil keepj " : "keepj ")
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100574else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100575 call s:NetrwInit("s:netrw_silentxfer" , (exists("g:netrw_silent") && g:netrw_silent != 0)? "sil " : " ")
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100576endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100577call s:NetrwInit("g:netrw_sort_by" , "name") " alternatives: date , size
578call s:NetrwInit("g:netrw_sort_options" , "")
579call s:NetrwInit("g:netrw_sort_direction", "normal") " alternative: reverse (z y x ...)
Bram Moolenaar1afcace2005-11-25 19:54:28 +0000580if !exists("g:netrw_sort_sequence")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100581 if has("unix")
582 let g:netrw_sort_sequence= '[\/]$,\<core\%(\.\d\+\)\=\>,\.h$,\.c$,\.cpp$,\~\=\*$,*,\.o$,\.obj$,\.info$,\.swp$,\.bak$,\~$'
583 else
584 let g:netrw_sort_sequence= '[\/]$,\.h$,\.c$,\.cpp$,*,\.o$,\.obj$,\.info$,\.swp$,\.bak$,\~$'
585 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +0000586endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100587call s:NetrwInit("g:netrw_special_syntax" , 0)
588call s:NetrwInit("g:netrw_ssh_browse_reject", '^total\s\+\d\+$')
Bram Moolenaara6878372014-03-22 21:02:50 +0100589call s:NetrwInit("g:netrw_use_noswf" , 1)
Bram Moolenaare0fa3742016-02-20 15:47:01 +0100590call s:NetrwInit("g:netrw_sizestyle" ,"b")
Bram Moolenaarafeb4fa2006-02-01 21:51:12 +0000591" Default values - t-w ---------- {{{3
Bram Moolenaar5c736222010-01-06 20:54:52 +0100592call s:NetrwInit("g:netrw_timefmt","%c")
Bram Moolenaarff034192013-04-24 18:51:19 +0200593if !exists("g:netrw_xstrlen")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100594 if exists("g:Align_xstrlen")
595 let g:netrw_xstrlen= g:Align_xstrlen
596 elseif exists("g:drawit_xstrlen")
597 let g:netrw_xstrlen= g:drawit_xstrlen
598 elseif &enc == "latin1" || !has("multi_byte")
599 let g:netrw_xstrlen= 0
600 else
601 let g:netrw_xstrlen= 1
602 endif
Bram Moolenaarff034192013-04-24 18:51:19 +0200603endif
Bram Moolenaar5c736222010-01-06 20:54:52 +0100604call s:NetrwInit("g:NetrwTopLvlMenu","Netrw.")
Bram Moolenaar251e1912011-06-19 05:09:16 +0200605call s:NetrwInit("g:netrw_winsize",50)
Bram Moolenaara0f849e2015-10-30 14:37:44 +0100606call s:NetrwInit("g:netrw_wiw",1)
Bram Moolenaar5b435d62012-04-05 17:33:26 +0200607if g:netrw_winsize > 100|let g:netrw_winsize= 100|endif
Bram Moolenaar1afcace2005-11-25 19:54:28 +0000608" ---------------------------------------------------------------------
Bram Moolenaarafeb4fa2006-02-01 21:51:12 +0000609" Default values for netrw's script variables: {{{2
Bram Moolenaar5c736222010-01-06 20:54:52 +0100610call s:NetrwInit("g:netrw_fname_escape",' ?&;%')
Nir Lichtman1e34b952024-05-08 19:19:34 +0200611if has("win32")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100612 call s:NetrwInit("g:netrw_glob_escape",'*?`{[]$')
Bram Moolenaar00a927d2010-05-14 23:24:24 +0200613else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100614 call s:NetrwInit("g:netrw_glob_escape",'*[]?`{~$\')
Bram Moolenaar00a927d2010-05-14 23:24:24 +0200615endif
Bram Moolenaarff034192013-04-24 18:51:19 +0200616call s:NetrwInit("g:netrw_menu_escape",'.&? \')
Bram Moolenaar5c736222010-01-06 20:54:52 +0100617call s:NetrwInit("g:netrw_tmpfile_escape",' &;')
618call s:NetrwInit("s:netrw_map_escape","<|\n\r\\\<C-V>\"")
Bram Moolenaara6878372014-03-22 21:02:50 +0100619if has("gui_running") && (&enc == 'utf-8' || &enc == 'utf-16' || &enc == 'ucs-4')
Luca Saccarolac363ca12024-12-19 20:16:18 +0100620 let s:treedepthstring= "│ "
Bram Moolenaar8d043172014-01-23 14:24:41 +0100621else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100622 let s:treedepthstring= "| "
Bram Moolenaar8d043172014-01-23 14:24:41 +0100623endif
Bram Moolenaar85850f32019-07-19 22:05:51 +0200624call s:NetrwInit("s:netrw_posn",'{}')
Bram Moolenaar8299df92004-07-10 09:47:34 +0000625
626" BufEnter event ignored by decho when following variable is true
627" Has a side effect that doau BufReadPost doesn't work, so
628" files read by network transfer aren't appropriately highlighted.
Luca Saccarolac363ca12024-12-19 20:16:18 +0100629"let g:decho_bufenter = 1 "Decho
Bram Moolenaar071d4272004-06-13 20:20:40 +0000630
Bram Moolenaaradc21822011-04-01 18:03:16 +0200631" ======================
632" Netrw Initialization: {{{1
633" ======================
Bram Moolenaar15146672011-10-20 22:22:38 +0200634if 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 +0100635 " call Decho("installed beval events",'~'.expand("<slnum>"))
636 let &l:bexpr = "netrw#BalloonHelp()"
637 " call Decho("&l:bexpr<".&l:bexpr."> buf#".bufnr())
638 au FileType netrw setl beval
639 au WinLeave * if &ft == "netrw" && exists("s:initbeval")|let &beval= s:initbeval|endif
640 au VimEnter * let s:initbeval= &beval
641 "else " Decho
642 " if v:version < 700 | call Decho("did not install beval events: v:version=".v:version." < 700","~".expand("<slnum>")) | endif
shane.xb.qianc673b802024-12-20 19:36:40 +0100643 " if !has("balloon_eval") | call Decho("did not install beval events: does not have balloon_eval","~".expand("<slnum>")) | endif
644 " if exists("s:initbeval") | call Decho("did not install beval events: s:initbeval exists","~".expand("<slnum>")) | endif
645 " if exists("g:netrw_nobeval") | call Decho("did not install beval events: g:netrw_nobeval exists","~".expand("<slnum>")) | endif
646 " if !has("syntax") | call Decho("did not install beval events: does not have syntax highlighting","~".expand("<slnum>")) | endif
647 " 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 +0200648endif
Luca Saccarolac363ca12024-12-19 20:16:18 +0100649au WinEnter * if &ft == "netrw"|call s:NetrwInsureWinVars()|endif
Bram Moolenaaradc21822011-04-01 18:03:16 +0200650
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +0200651if g:netrw_keepj =~# "keepj"
Luca Saccarolac363ca12024-12-19 20:16:18 +0100652 com! -nargs=* NetrwKeepj keepj <args>
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100653else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100654 let g:netrw_keepj= ""
655 com! -nargs=* NetrwKeepj <args>
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100656endif
657
Bram Moolenaarafeb4fa2006-02-01 21:51:12 +0000658" ==============================
659" Netrw Utility Functions: {{{1
660" ==============================
661
Bram Moolenaaradc21822011-04-01 18:03:16 +0200662" ---------------------------------------------------------------------
Bram Moolenaara6878372014-03-22 21:02:50 +0100663" netrw#BalloonHelp: {{{2
Bram Moolenaar8d043172014-01-23 14:24:41 +0100664if v:version >= 700 && has("balloon_eval") && has("syntax") && exists("g:syntax_on") && !exists("g:netrw_nobeval")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100665 " call Decho("loading netrw#BalloonHelp()",'~'.expand("<slnum>"))
666 fun! netrw#BalloonHelp()
667 if &ft != "netrw"
668 return ""
Bram Moolenaar1d59aa12020-09-19 18:50:13 +0200669 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +0100670 if exists("s:popuperr_id") && popup_getpos(s:popuperr_id) != {}
671 " popup error window is still showing
672 " s:pouperr_id and s:popuperr_text are set up in netrw#ErrorMsg()
673 if exists("s:popuperr_text") && s:popuperr_text != "" && v:beval_text != s:popuperr_text
674 " text under mouse hasn't changed; only close window when it changes
675 call popup_close(s:popuperr_id)
676 unlet s:popuperr_text
677 else
678 let s:popuperr_text= v:beval_text
679 endif
680 let mesg= ""
681 elseif !exists("w:netrw_bannercnt") || v:beval_lnum >= w:netrw_bannercnt || (exists("g:netrw_nobeval") && g:netrw_nobeval)
682 let mesg= ""
683 elseif v:beval_text == "Netrw" || v:beval_text == "Directory" || v:beval_text == "Listing"
684 let mesg = "i: thin-long-wide-tree gh: quick hide/unhide of dot-files qf: quick file info %:open new file"
685 elseif getline(v:beval_lnum) =~ '^"\s*/'
686 let mesg = "<cr>: edit/enter o: edit/enter in horiz window t: edit/enter in new tab v:edit/enter in vert window"
687 elseif v:beval_text == "Sorted" || v:beval_text == "by"
688 let mesg = 's: sort by name, time, file size, extension r: reverse sorting order mt: mark target'
689 elseif v:beval_text == "Sort" || v:beval_text == "sequence"
690 let mesg = "S: edit sorting sequence"
691 elseif v:beval_text == "Hiding" || v:beval_text == "Showing"
692 let mesg = "a: hiding-showing-all ctrl-h: editing hiding list mh: hide/show by suffix"
693 elseif v:beval_text == "Quick" || v:beval_text == "Help"
694 let mesg = "Help: press <F1>"
695 elseif v:beval_text == "Copy/Move" || v:beval_text == "Tgt"
696 let mesg = "mt: mark target mc: copy marked file to target mm: move marked file to target"
697 else
698 let mesg= ""
699 endif
700 return mesg
701 endfun
702 "else " Decho
703 " if v:version < 700 |call Decho("did not load netrw#BalloonHelp(): vim version ".v:version." < 700 -","~".expand("<slnum>"))|endif
shane.xb.qianc673b802024-12-20 19:36:40 +0100704 " if !has("balloon_eval") |call Decho("did not load netrw#BalloonHelp(): does not have balloon eval","~".expand("<slnum>")) |endif
705 " if !has("syntax") |call Decho("did not load netrw#BalloonHelp(): syntax disabled","~".expand("<slnum>")) |endif
706 " if !exists("g:syntax_on") |call Decho("did not load netrw#BalloonHelp(): g:syntax_on n/a","~".expand("<slnum>")) |endif
707 " 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 +0200708endif
709
Bram Moolenaar071d4272004-06-13 20:20:40 +0000710" ------------------------------------------------------------------------
Bram Moolenaarff034192013-04-24 18:51:19 +0200711" netrw#Explore: launch the local browser in the directory of the current file {{{2
712" indx: == -1: Nexplore
713" == -2: Pexplore
714" == +: this is overloaded:
715" * If Nexplore/Pexplore is in use, then this refers to the
716" indx'th item in the w:netrw_explore_list[] of items which
717" matched the */pattern **/pattern *//pattern **//pattern
718" * If Hexplore or Vexplore, then this will override
719" g:netrw_winsize to specify the qty of rows or columns the
720" newly split window should have.
Bram Moolenaar8d043172014-01-23 14:24:41 +0100721" 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 +0200722" dosplit==1: the window will be split before running the local browser
723" style == 0: Explore style == 1: Explore!
724" == 2: Hexplore style == 3: Hexplore!
725" == 4: Vexplore style == 5: Vexplore!
726" == 6: Texplore
727fun! netrw#Explore(indx,dosplit,style,...)
Bram Moolenaarff034192013-04-24 18:51:19 +0200728 if !exists("b:netrw_curdir")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100729 let b:netrw_curdir= getcwd()
Bram Moolenaarff034192013-04-24 18:51:19 +0200730 endif
Bram Moolenaara6878372014-03-22 21:02:50 +0100731
732 " record current file for Rexplore's benefit
733 if &ft != "netrw"
Luca Saccarolac363ca12024-12-19 20:16:18 +0100734 let w:netrw_rexfile= expand("%:p")
Bram Moolenaara6878372014-03-22 21:02:50 +0100735 endif
736
737 " record current directory
Bram Moolenaarff034192013-04-24 18:51:19 +0200738 let curdir = simplify(b:netrw_curdir)
739 let curfiledir = substitute(expand("%:p"),'^\(.*[/\\]\)[^/\\]*$','\1','e')
Nir Lichtman1e34b952024-05-08 19:19:34 +0200740 if !exists("g:netrw_cygwin") && has("win32")
Luca Saccarolac363ca12024-12-19 20:16:18 +0100741 let curdir= substitute(curdir,'\','/','g')
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200742 endif
Bram Moolenaara6878372014-03-22 21:02:50 +0100743
744 " using completion, directories with spaces in their names (thanks, Bill Gates, for a truly dumb idea)
745 " will end up with backslashes here. Solution: strip off backslashes that precede white space and
746 " try Explore again.
747 if a:0 > 0
Luca Saccarolac363ca12024-12-19 20:16:18 +0100748 if a:1 =~ "\\\s" && !filereadable(s:NetrwFile(a:1)) && !isdirectory(s:NetrwFile(a:1))
749 let a1 = substitute(a:1, '\\\(\s\)', '\1', 'g')
750 if a1 != a:1
751 call netrw#Explore(a:indx, a:dosplit, a:style, a1)
752 return
753 endif
Damien9d57ea52024-07-22 20:23:48 +0200754 endif
Bram Moolenaara6878372014-03-22 21:02:50 +0100755 endif
Bram Moolenaarff034192013-04-24 18:51:19 +0200756
757 " save registers
Bram Moolenaar89a9c152021-08-29 21:55:35 +0200758 if has("clipboard") && g:netrw_clipboard
Luca Saccarolac363ca12024-12-19 20:16:18 +0100759 " call Decho("(netrw#Explore) save @* and @+",'~'.expand("<slnum>"))
760 sil! let keepregstar = @*
761 sil! let keepregplus = @+
Bram Moolenaara6878372014-03-22 21:02:50 +0100762 endif
Bram Moolenaarff034192013-04-24 18:51:19 +0200763 sil! let keepregslash= @/
764
Bram Moolenaar8d043172014-01-23 14:24:41 +0100765 " if dosplit
766 " -or- file has been modified AND file not hidden when abandoned
767 " -or- Texplore used
768 if a:dosplit || (&modified && &hidden == 0 && &bufhidden != "hide") || a:style == 6
Luca Saccarolac363ca12024-12-19 20:16:18 +0100769 call s:SaveWinVars()
770 let winsz= g:netrw_winsize
771 if a:indx > 0
772 let winsz= a:indx
773 endif
Bram Moolenaarff034192013-04-24 18:51:19 +0200774
Luca Saccarolac363ca12024-12-19 20:16:18 +0100775 if a:style == 0 " Explore, Sexplore
776 let winsz= (winsz > 0)? (winsz*winheight(0))/100 : -winsz
777 if winsz == 0|let winsz= ""|endif
778 exe "noswapfile ".(g:netrw_alto ? "below " : "above ").winsz."wincmd s"
Bram Moolenaarff034192013-04-24 18:51:19 +0200779
Luca Saccarolac363ca12024-12-19 20:16:18 +0100780 elseif a:style == 1 " Explore!, Sexplore!
781 let winsz= (winsz > 0)? (winsz*winwidth(0))/100 : -winsz
782 if winsz == 0|let winsz= ""|endif
783 exe "keepalt noswapfile ".(g:netrw_altv ? "rightbelow " : "leftabove ").winsz."wincmd v"
Bram Moolenaarff034192013-04-24 18:51:19 +0200784
Luca Saccarolac363ca12024-12-19 20:16:18 +0100785 elseif a:style == 2 " Hexplore
786 let winsz= (winsz > 0)? (winsz*winheight(0))/100 : -winsz
787 if winsz == 0|let winsz= ""|endif
788 exe "keepalt noswapfile ".(g:netrw_alto ? "below " : "above ").winsz."wincmd s"
Bram Moolenaarff034192013-04-24 18:51:19 +0200789
Luca Saccarolac363ca12024-12-19 20:16:18 +0100790 elseif a:style == 3 " Hexplore!
791 let winsz= (winsz > 0)? (winsz*winheight(0))/100 : -winsz
792 if winsz == 0|let winsz= ""|endif
793 exe "keepalt noswapfile ".(!g:netrw_alto ? "below " : "above ").winsz."wincmd s"
Bram Moolenaarff034192013-04-24 18:51:19 +0200794
Luca Saccarolac363ca12024-12-19 20:16:18 +0100795 elseif a:style == 4 " Vexplore
796 let winsz= (winsz > 0)? (winsz*winwidth(0))/100 : -winsz
797 if winsz == 0|let winsz= ""|endif
798 exe "keepalt noswapfile ".(g:netrw_altv ? "rightbelow " : "leftabove ").winsz."wincmd v"
Bram Moolenaarff034192013-04-24 18:51:19 +0200799
Luca Saccarolac363ca12024-12-19 20:16:18 +0100800 elseif a:style == 5 " Vexplore!
801 let winsz= (winsz > 0)? (winsz*winwidth(0))/100 : -winsz
802 if winsz == 0|let winsz= ""|endif
803 exe "keepalt noswapfile ".(!g:netrw_altv ? "rightbelow " : "leftabove ").winsz."wincmd v"
Bram Moolenaarff034192013-04-24 18:51:19 +0200804
Luca Saccarolac363ca12024-12-19 20:16:18 +0100805 elseif a:style == 6 " Texplore
806 call s:SaveBufVars()
807 exe "keepalt tabnew ".fnameescape(curdir)
808 call s:RestoreBufVars()
809 endif
810 call s:RestoreWinVars()
Bram Moolenaarff034192013-04-24 18:51:19 +0200811 endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100812 NetrwKeepj norm! 0
Bram Moolenaarff034192013-04-24 18:51:19 +0200813
814 if a:0 > 0
Luca Saccarolac363ca12024-12-19 20:16:18 +0100815 if a:1 =~ '^\~' && (has("unix") || (exists("g:netrw_cygwin") && g:netrw_cygwin))
816 let dirname= simplify(substitute(a:1,'\~',expand("$HOME"),''))
817 elseif a:1 == '.'
818 let dirname= simplify(exists("b:netrw_curdir")? b:netrw_curdir : getcwd())
819 if dirname !~ '/$'
820 let dirname= dirname."/"
821 endif
822 elseif a:1 =~ '\$'
823 let dirname= simplify(expand(a:1))
824 elseif a:1 !~ '^\*\{1,2}/' && a:1 !~ '^\a\{3,}://'
825 let dirname= simplify(a:1)
826 else
827 let dirname= a:1
Bram Moolenaarff034192013-04-24 18:51:19 +0200828 endif
Bram Moolenaarff034192013-04-24 18:51:19 +0200829 else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100830 " clear explore
831 call s:NetrwClearExplore()
832 return
Bram Moolenaarff034192013-04-24 18:51:19 +0200833 endif
834
Bram Moolenaarff034192013-04-24 18:51:19 +0200835 if dirname =~ '\.\./\=$'
Luca Saccarolac363ca12024-12-19 20:16:18 +0100836 let dirname= simplify(fnamemodify(dirname,':p:h'))
Bram Moolenaarff034192013-04-24 18:51:19 +0200837 elseif dirname =~ '\.\.' || dirname == '.'
Luca Saccarolac363ca12024-12-19 20:16:18 +0100838 let dirname= simplify(fnamemodify(dirname,':p'))
Bram Moolenaarff034192013-04-24 18:51:19 +0200839 endif
Bram Moolenaarff034192013-04-24 18:51:19 +0200840
841 if dirname =~ '^\*//'
Luca Saccarolac363ca12024-12-19 20:16:18 +0100842 " starpat=1: Explore *//pattern (current directory only search for files containing pattern)
843 let pattern= substitute(dirname,'^\*//\(.*\)$','\1','')
844 let starpat= 1
845 if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
Bram Moolenaarff034192013-04-24 18:51:19 +0200846
847 elseif dirname =~ '^\*\*//'
Luca Saccarolac363ca12024-12-19 20:16:18 +0100848 " starpat=2: Explore **//pattern (recursive descent search for files containing pattern)
849 let pattern= substitute(dirname,'^\*\*//','','')
850 let starpat= 2
Bram Moolenaarff034192013-04-24 18:51:19 +0200851
852 elseif dirname =~ '/\*\*/'
Luca Saccarolac363ca12024-12-19 20:16:18 +0100853 " handle .../**/.../filepat
854 let prefixdir= substitute(dirname,'^\(.\{-}\)\*\*.*$','\1','')
855 if prefixdir =~ '^/' || (prefixdir =~ '^\a:/' && has("win32"))
856 let b:netrw_curdir = prefixdir
857 else
858 let b:netrw_curdir= getcwd().'/'.prefixdir
859 endif
860 let dirname= substitute(dirname,'^.\{-}\(\*\*/.*\)$','\1','')
861 let starpat= 4
Bram Moolenaarff034192013-04-24 18:51:19 +0200862
863 elseif dirname =~ '^\*/'
Luca Saccarolac363ca12024-12-19 20:16:18 +0100864 " case starpat=3: Explore */filepat (search in current directory for filenames matching filepat)
865 let starpat= 3
Bram Moolenaarff034192013-04-24 18:51:19 +0200866
867 elseif dirname=~ '^\*\*/'
Luca Saccarolac363ca12024-12-19 20:16:18 +0100868 " starpat=4: Explore **/filepat (recursive descent search for filenames matching filepat)
869 let starpat= 4
Bram Moolenaarff034192013-04-24 18:51:19 +0200870
871 else
Luca Saccarolac363ca12024-12-19 20:16:18 +0100872 let starpat= 0
Bram Moolenaarff034192013-04-24 18:51:19 +0200873 endif
874
875 if starpat == 0 && a:indx >= 0
Luca Saccarolac363ca12024-12-19 20:16:18 +0100876 " [Explore Hexplore Vexplore Sexplore] [dirname]
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200877 if dirname == ""
Luca Saccarolac363ca12024-12-19 20:16:18 +0100878 let dirname= curfiledir
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200879 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +0100880 if dirname =~# '^scp://' || dirname =~ '^ftp://'
881 call netrw#Nread(2,dirname)
882 else
883 if dirname == ""
884 let dirname= getcwd()
885 elseif has("win32") && !g:netrw_cygwin
886 " Windows : check for a drive specifier, or else for a remote share name ('\\Foo' or '//Foo',
887 " depending on whether backslashes have been converted to forward slashes by earlier code).
888 if dirname !~ '^[a-zA-Z]:' && dirname !~ '^\\\\\w\+' && dirname !~ '^//\w\+'
889 let dirname= b:netrw_curdir."/".dirname
890 endif
891 elseif dirname !~ '^/'
892 let dirname= b:netrw_curdir."/".dirname
893 endif
894 call netrw#LocalBrowseCheck(dirname)
895 endif
896 if exists("w:netrw_bannercnt")
897 " done to handle P08-Ingelrest. :Explore will _Always_ go to the line just after the banner.
898 " If one wants to return the same place in the netrw window, use :Rex instead.
899 exe w:netrw_bannercnt
900 endif
Bram Moolenaarff034192013-04-24 18:51:19 +0200901
Bram Moolenaarff034192013-04-24 18:51:19 +0200902
shane.xb.qianc673b802024-12-20 19:36:40 +0100903 " starpat=1: Explore *//pattern (current directory only search for files containing pattern)
904 " starpat=2: Explore **//pattern (recursive descent search for files containing pattern)
905 " starpat=3: Explore */filepat (search in current directory for filenames matching filepat)
906 " starpat=4: Explore **/filepat (recursive descent search for filenames matching filepat)
Bram Moolenaarff034192013-04-24 18:51:19 +0200907 elseif a:indx <= 0
Luca Saccarolac363ca12024-12-19 20:16:18 +0100908 " Nexplore, Pexplore, Explore: handle starpat
909 if !mapcheck("<s-up>","n") && !mapcheck("<s-down>","n") && exists("b:netrw_curdir")
910 let s:didstarstar= 1
911 nnoremap <buffer> <silent> <s-up> :Pexplore<cr>
912 nnoremap <buffer> <silent> <s-down> :Nexplore<cr>
Bram Moolenaarff034192013-04-24 18:51:19 +0200913 endif
914
Luca Saccarolac363ca12024-12-19 20:16:18 +0100915 if has("path_extra")
916 if !exists("w:netrw_explore_indx")
917 let w:netrw_explore_indx= 0
Bram Moolenaara6878372014-03-22 21:02:50 +0100918 endif
Bram Moolenaarff034192013-04-24 18:51:19 +0200919
Luca Saccarolac363ca12024-12-19 20:16:18 +0100920 let indx = a:indx
921
922 if indx == -1
923 " Nexplore
924 if !exists("w:netrw_explore_list") " sanity check
925 NetrwKeepj call netrw#ErrorMsg(s:WARNING,"using Nexplore or <s-down> improperly; see help for netrw-starstar",40)
926 if has("clipboard") && g:netrw_clipboard
927 if @* != keepregstar | sil! let @* = keepregstar | endif
928 if @+ != keepregplus | sil! let @+ = keepregplus | endif
929 endif
930 sil! let @/ = keepregslash
931 return
932 endif
933 let indx= w:netrw_explore_indx
934 if indx < 0 | let indx= 0 | endif
935 if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
936 let curfile= w:netrw_explore_list[indx]
937 while indx < w:netrw_explore_listlen && curfile == w:netrw_explore_list[indx]
938 let indx= indx + 1
939 endwhile
940 if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
941
942 elseif indx == -2
943 " Pexplore
944 if !exists("w:netrw_explore_list") " sanity check
945 NetrwKeepj call netrw#ErrorMsg(s:WARNING,"using Pexplore or <s-up> improperly; see help for netrw-starstar",41)
946 if has("clipboard") && g:netrw_clipboard
947 if @* != keepregstar | sil! let @* = keepregstar | endif
948 if @+ != keepregplus | sil! let @+ = keepregplus | endif
949 endif
950 sil! let @/ = keepregslash
951 return
952 endif
953 let indx= w:netrw_explore_indx
954 if indx < 0 | let indx= 0 | endif
955 if indx >= w:netrw_explore_listlen | let indx= w:netrw_explore_listlen - 1 | endif
956 let curfile= w:netrw_explore_list[indx]
957 while indx >= 0 && curfile == w:netrw_explore_list[indx]
958 let indx= indx - 1
959 endwhile
960 if indx < 0 | let indx= 0 | endif
961
962 else
963 " Explore -- initialize
964 " build list of files to Explore with Nexplore/Pexplore
965 NetrwKeepj keepalt call s:NetrwClearExplore()
966 let w:netrw_explore_indx= 0
967 if !exists("b:netrw_curdir")
968 let b:netrw_curdir= getcwd()
969 endif
970
971 " switch on starpat to build the w:netrw_explore_list of files
972 if starpat == 1
973 " starpat=1: Explore *//pattern (current directory only search for files containing pattern)
974 try
975 exe "NetrwKeepj noautocmd vimgrep /".pattern."/gj ".fnameescape(b:netrw_curdir)."/*"
976 catch /^Vim\%((\a\+)\)\=:E480/
977 keepalt call netrw#ErrorMsg(s:WARNING,"no match with pattern<".pattern.">",76)
978 return
979 endtry
980 let w:netrw_explore_list = s:NetrwExploreListUniq(map(getqflist(),'bufname(v:val.bufnr)'))
981 if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
982
983 elseif starpat == 2
984 " starpat=2: Explore **//pattern (recursive descent search for files containing pattern)
985 try
986 exe "sil NetrwKeepj noautocmd keepalt vimgrep /".pattern."/gj "."**/*"
987 catch /^Vim\%((\a\+)\)\=:E480/
988 keepalt call netrw#ErrorMsg(s:WARNING,'no files matched pattern<'.pattern.'>',45)
989 if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
990 if has("clipboard") && g:netrw_clipboard
991 if @* != keepregstar | sil! let @* = keepregstar | endif
992 if @+ != keepregplus | sil! let @+ = keepregplus | endif
993 endif
994 sil! let @/ = keepregslash
995 return
996 endtry
997 let s:netrw_curdir = b:netrw_curdir
998 let w:netrw_explore_list = getqflist()
999 let w:netrw_explore_list = s:NetrwExploreListUniq(map(w:netrw_explore_list,'s:netrw_curdir."/".bufname(v:val.bufnr)'))
1000 if &hls | let keepregslash= s:ExplorePatHls(pattern) | endif
1001
1002 elseif starpat == 3
1003 " starpat=3: Explore */filepat (search in current directory for filenames matching filepat)
1004 let filepat= substitute(dirname,'^\*/','','')
1005 let filepat= substitute(filepat,'^[%#<]','\\&','')
1006 let w:netrw_explore_list= s:NetrwExploreListUniq(split(expand(b:netrw_curdir."/".filepat),'\n'))
1007 if &hls | let keepregslash= s:ExplorePatHls(filepat) | endif
1008
1009 elseif starpat == 4
1010 " starpat=4: Explore **/filepat (recursive descent search for filenames matching filepat)
1011 let w:netrw_explore_list= s:NetrwExploreListUniq(split(expand(b:netrw_curdir."/".dirname),'\n'))
1012 if &hls | let keepregslash= s:ExplorePatHls(dirname) | endif
1013 endif " switch on starpat to build w:netrw_explore_list
1014
1015 let w:netrw_explore_listlen = len(w:netrw_explore_list)
1016
1017 if w:netrw_explore_listlen == 0 || (w:netrw_explore_listlen == 1 && w:netrw_explore_list[0] =~ '\*\*\/')
1018 keepalt NetrwKeepj call netrw#ErrorMsg(s:WARNING,"no files matched",42)
1019 if has("clipboard") && g:netrw_clipboard
1020 if @* != keepregstar | sil! let @* = keepregstar | endif
1021 if @+ != keepregplus | sil! let @+ = keepregplus | endif
1022 endif
1023 sil! let @/ = keepregslash
1024 return
1025 endif
1026 endif " if indx ... endif
1027
1028 " NetrwStatusLine support - for exploring support
1029 let w:netrw_explore_indx= indx
1030
1031 " wrap the indx around, but issue a note
1032 if indx >= w:netrw_explore_listlen || indx < 0
1033 let indx = (indx < 0)? ( w:netrw_explore_listlen - 1 ) : 0
1034 let w:netrw_explore_indx= indx
1035 keepalt NetrwKeepj call netrw#ErrorMsg(s:NOTE,"no more files match Explore pattern",43)
Bram Moolenaara6878372014-03-22 21:02:50 +01001036 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01001037
1038 exe "let dirfile= w:netrw_explore_list[".indx."]"
1039 let newdir= substitute(dirfile,'/[^/]*$','','e')
1040
1041 call netrw#LocalBrowseCheck(newdir)
1042 if !exists("w:netrw_liststyle")
1043 let w:netrw_liststyle= g:netrw_liststyle
1044 endif
1045 if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:LONGLIST
1046 keepalt NetrwKeepj call search('^'.substitute(dirfile,"^.*/","","").'\>',"W")
1047 else
1048 keepalt NetrwKeepj call search('\<'.substitute(dirfile,"^.*/","","").'\>',"w")
1049 endif
1050 let w:netrw_explore_mtchcnt = indx + 1
1051 let w:netrw_explore_bufnr = bufnr("%")
1052 let w:netrw_explore_line = line(".")
1053 keepalt NetrwKeepj call s:SetupNetrwStatusLine('%f %h%m%r%=%9*%{NetrwStatusLine()}')
Bram Moolenaarff034192013-04-24 18:51:19 +02001054
1055 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001056 if !exists("g:netrw_quiet")
1057 keepalt NetrwKeepj call netrw#ErrorMsg(s:WARNING,"your vim needs the +path_extra feature for Exploring with **!",44)
1058 endif
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001059 if has("clipboard") && g:netrw_clipboard
Bram Moolenaar0c0734d2019-11-26 21:44:46 +01001060 if @* != keepregstar | sil! let @* = keepregstar | endif
1061 if @+ != keepregplus | sil! let @+ = keepregplus | endif
Bram Moolenaara6878372014-03-22 21:02:50 +01001062 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02001063 sil! let @/ = keepregslash
Bram Moolenaarff034192013-04-24 18:51:19 +02001064 return
Bram Moolenaarff034192013-04-24 18:51:19 +02001065 endif
1066
Bram Moolenaarff034192013-04-24 18:51:19 +02001067 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001068 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && dirname =~ '/'
1069 sil! unlet w:netrw_treedict
1070 sil! unlet w:netrw_treetop
1071 endif
1072 let newdir= dirname
1073 if !exists("b:netrw_curdir")
1074 NetrwKeepj call netrw#LocalBrowseCheck(getcwd())
1075 else
1076 NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,newdir,0))
1077 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02001078 endif
1079
1080 " visual display of **/ **// */ Exploration files
Bram Moolenaarff034192013-04-24 18:51:19 +02001081 if exists("w:netrw_explore_indx") && exists("b:netrw_curdir")
Luca Saccarolac363ca12024-12-19 20:16:18 +01001082 if !exists("s:explore_prvdir") || s:explore_prvdir != b:netrw_curdir
1083 " only update match list when current directory isn't the same as before
1084 let s:explore_prvdir = b:netrw_curdir
1085 let s:explore_match = ""
1086 let dirlen = strlen(b:netrw_curdir)
1087 if b:netrw_curdir !~ '/$'
1088 let dirlen= dirlen + 1
Bram Moolenaarff034192013-04-24 18:51:19 +02001089 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01001090 let prvfname= ""
1091 for fname in w:netrw_explore_list
1092 if fname =~ '^'.b:netrw_curdir
1093 if s:explore_match == ""
1094 let s:explore_match= '\<'.escape(strpart(fname,dirlen),g:netrw_markfileesc).'\>'
1095 else
1096 let s:explore_match= s:explore_match.'\|\<'.escape(strpart(fname,dirlen),g:netrw_markfileesc).'\>'
1097 endif
1098 elseif fname !~ '^/' && fname != prvfname
1099 if s:explore_match == ""
1100 let s:explore_match= '\<'.escape(fname,g:netrw_markfileesc).'\>'
1101 else
1102 let s:explore_match= s:explore_match.'\|\<'.escape(fname,g:netrw_markfileesc).'\>'
1103 endif
1104 endif
1105 let prvfname= fname
1106 endfor
1107 if has("syntax") && exists("g:syntax_on") && g:syntax_on
1108 exe "2match netrwMarkFile /".s:explore_match."/"
Bram Moolenaarff034192013-04-24 18:51:19 +02001109 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02001110 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01001111 echo "<s-up>==Pexplore <s-down>==Nexplore"
Bram Moolenaarff034192013-04-24 18:51:19 +02001112 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001113 2match none
1114 if exists("s:explore_match") | unlet s:explore_match | endif
1115 if exists("s:explore_prvdir") | unlet s:explore_prvdir | endif
Bram Moolenaarff034192013-04-24 18:51:19 +02001116 endif
1117
Bram Moolenaara6878372014-03-22 21:02:50 +01001118 " since Explore may be used to initialize netrw's browser,
1119 " there's no danger of a late FocusGained event on initialization.
1120 " Consequently, set s:netrw_events to 2.
1121 let s:netrw_events= 2
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001122 if has("clipboard") && g:netrw_clipboard
Luca Saccarolac363ca12024-12-19 20:16:18 +01001123 if @* != keepregstar | sil! let @* = keepregstar | endif
1124 if @+ != keepregplus | sil! let @+ = keepregplus | endif
Bram Moolenaara6878372014-03-22 21:02:50 +01001125 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02001126 sil! let @/ = keepregslash
Bram Moolenaarff034192013-04-24 18:51:19 +02001127endfun
1128
1129" ---------------------------------------------------------------------
Bram Moolenaar8d043172014-01-23 14:24:41 +01001130" netrw#Lexplore: toggle Explorer window, keeping it on the left of the current tab {{{2
Bram Moolenaar71badf92023-04-22 22:40:14 +01001131" Uses g:netrw_chgwin : specifies the window where Lexplore files are to be opened
1132" t:netrw_lexposn : winsaveview() output (used on Lexplore window)
1133" t:netrw_lexbufnr: the buffer number of the Lexplore buffer (internal to this function)
1134" s:lexplore_win : window number of Lexplore window (serves to indicate which window is a Lexplore window)
1135" w:lexplore_buf : buffer number of Lexplore window (serves to indicate which window is a Lexplore window)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01001136fun! netrw#Lexplore(count,rightside,...)
Luca Saccarolac363ca12024-12-19 20:16:18 +01001137 " call Dfunc("netrw#Lexplore(count=".a:count." rightside=".a:rightside.",...) a:0=".a:0." ft=".&ft)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01001138 let curwin= winnr()
1139
Bram Moolenaara6878372014-03-22 21:02:50 +01001140 if a:0 > 0 && a:1 != ""
Luca Saccarolac363ca12024-12-19 20:16:18 +01001141 " if a netrw window is already on the left-side of the tab
1142 " and a directory has been specified, explore with that
1143 " directory.
1144 let a1 = expand(a:1)
1145 exe "1wincmd w"
1146 if &ft == "netrw"
1147 exe "Explore ".fnameescape(a1)
1148 exe curwin."wincmd w"
1149 let s:lexplore_win= curwin
1150 let w:lexplore_buf= bufnr("%")
1151 if exists("t:netrw_lexposn")
1152 unlet t:netrw_lexposn
1153 endif
1154 return
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01001155 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01001156 exe curwin."wincmd w"
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01001157 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001158 let a1= ""
Bram Moolenaara6878372014-03-22 21:02:50 +01001159 endif
1160
Bram Moolenaar8d043172014-01-23 14:24:41 +01001161 if exists("t:netrw_lexbufnr")
Luca Saccarolac363ca12024-12-19 20:16:18 +01001162 " check if t:netrw_lexbufnr refers to a netrw window
1163 let lexwinnr = bufwinnr(t:netrw_lexbufnr)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01001164 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001165 let lexwinnr= 0
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01001166 endif
1167
1168 if lexwinnr > 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01001169 " close down netrw explorer window
1170 exe lexwinnr."wincmd w"
1171 let g:netrw_winsize = -winwidth(0)
1172 let t:netrw_lexposn = winsaveview()
1173 close
1174 if lexwinnr < curwin
1175 let curwin= curwin - 1
1176 endif
1177 if lexwinnr != curwin
1178 exe curwin."wincmd w"
1179 endif
1180 unlet t:netrw_lexbufnr
Bram Moolenaar8d043172014-01-23 14:24:41 +01001181
1182 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001183 " open netrw explorer window
1184 exe "1wincmd w"
1185 let keep_altv = g:netrw_altv
1186 let g:netrw_altv = 0
1187 if a:count != 0
1188 let netrw_winsize = g:netrw_winsize
1189 let g:netrw_winsize = a:count
1190 endif
1191 let curfile= expand("%")
1192 exe (a:rightside? "botright" : "topleft")." vertical ".((g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize) . " new"
1193 if a:0 > 0 && a1 != ""
1194 call netrw#Explore(0,0,0,a1)
1195 exe "Explore ".fnameescape(a1)
1196 elseif curfile =~ '^\a\{3,}://'
1197 call netrw#Explore(0,0,0,substitute(curfile,'[^/\\]*$','',''))
1198 else
1199 call netrw#Explore(0,0,0,".")
1200 endif
1201 if a:count != 0
1202 let g:netrw_winsize = netrw_winsize
1203 endif
1204 setlocal winfixwidth
1205 let g:netrw_altv = keep_altv
1206 let t:netrw_lexbufnr = bufnr("%")
1207 " done to prevent build-up of hidden buffers due to quitting and re-invocation of :Lexplore.
1208 " Since the intended use of :Lexplore is to have an always-present explorer window, the extra
1209 " effort to prevent mis-use of :Lex is warranted.
1210 set bh=wipe
1211 if exists("t:netrw_lexposn")
1212 call winrestview(t:netrw_lexposn)
1213 unlet t:netrw_lexposn
1214 endif
Bram Moolenaar8d043172014-01-23 14:24:41 +01001215 endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01001216
1217 " set up default window for editing via <cr>
Bram Moolenaara6878372014-03-22 21:02:50 +01001218 if exists("g:netrw_chgwin") && g:netrw_chgwin == -1
Luca Saccarolac363ca12024-12-19 20:16:18 +01001219 if a:rightside
1220 let g:netrw_chgwin= 1
1221 else
1222 let g:netrw_chgwin= 2
1223 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01001224 endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01001225
Bram Moolenaar8d043172014-01-23 14:24:41 +01001226endfun
1227
1228" ---------------------------------------------------------------------
Bram Moolenaara6878372014-03-22 21:02:50 +01001229" netrw#Clean: remove netrw {{{2
Bram Moolenaar446cb832008-06-24 21:56:24 +00001230" supports :NetrwClean -- remove netrw from first directory on runtimepath
1231" :NetrwClean! -- remove netrw from all directories on runtimepath
Bram Moolenaara6878372014-03-22 21:02:50 +01001232fun! netrw#Clean(sys)
Luca Saccarolac363ca12024-12-19 20:16:18 +01001233 " call Dfunc("netrw#Clean(sys=".a:sys.")")
Bram Moolenaar446cb832008-06-24 21:56:24 +00001234
1235 if a:sys
Luca Saccarolac363ca12024-12-19 20:16:18 +01001236 let choice= confirm("Remove personal and system copies of netrw?","&Yes\n&No")
Bram Moolenaar446cb832008-06-24 21:56:24 +00001237 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001238 let choice= confirm("Remove personal copy of netrw?","&Yes\n&No")
Bram Moolenaar446cb832008-06-24 21:56:24 +00001239 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01001240 " call Decho("choice=".choice,'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00001241 let diddel= 0
1242 let diddir= ""
1243
1244 if choice == 1
Luca Saccarolac363ca12024-12-19 20:16:18 +01001245 for dir in split(&rtp,',')
1246 if filereadable(dir."/plugin/netrwPlugin.vim")
1247 " call Decho("removing netrw-related files from ".dir,'~'.expand("<slnum>"))
1248 if s:NetrwDelete(dir."/plugin/netrwPlugin.vim") |call netrw#ErrorMsg(1,"unable to remove ".dir."/plugin/netrwPlugin.vim",55) |endif
1249 if s:NetrwDelete(dir."/autoload/netrwFileHandlers.vim")|call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrwFileHandlers.vim",55)|endif
1250 if s:NetrwDelete(dir."/autoload/netrwSettings.vim") |call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrwSettings.vim",55) |endif
1251 if s:NetrwDelete(dir."/autoload/netrw.vim") |call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrw.vim",55) |endif
1252 if s:NetrwDelete(dir."/syntax/netrw.vim") |call netrw#ErrorMsg(1,"unable to remove ".dir."/syntax/netrw.vim",55) |endif
1253 if s:NetrwDelete(dir."/syntax/netrwlist.vim") |call netrw#ErrorMsg(1,"unable to remove ".dir."/syntax/netrwlist.vim",55) |endif
1254 let diddir= dir
1255 let diddel= diddel + 1
1256 if !a:sys|break|endif
1257 endif
1258 endfor
Bram Moolenaar446cb832008-06-24 21:56:24 +00001259 endif
1260
Luca Saccarolac363ca12024-12-19 20:16:18 +01001261 echohl WarningMsg
Bram Moolenaar446cb832008-06-24 21:56:24 +00001262 if diddel == 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01001263 echomsg "netrw is either not installed or not removable"
Bram Moolenaar446cb832008-06-24 21:56:24 +00001264 elseif diddel == 1
Luca Saccarolac363ca12024-12-19 20:16:18 +01001265 echomsg "removed one copy of netrw from <".diddir.">"
Bram Moolenaar446cb832008-06-24 21:56:24 +00001266 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001267 echomsg "removed ".diddel." copies of netrw"
Bram Moolenaar446cb832008-06-24 21:56:24 +00001268 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01001269 echohl None
Bram Moolenaar446cb832008-06-24 21:56:24 +00001270
Luca Saccarolac363ca12024-12-19 20:16:18 +01001271 " call Dret("netrw#Clean")
Bram Moolenaar446cb832008-06-24 21:56:24 +00001272endfun
1273
Bram Moolenaar5c736222010-01-06 20:54:52 +01001274" ---------------------------------------------------------------------
Bram Moolenaara6878372014-03-22 21:02:50 +01001275" netrw#MakeTgt: make a target out of the directory name provided {{{2
1276fun! netrw#MakeTgt(dname)
Luca Saccarolac363ca12024-12-19 20:16:18 +01001277 " call Dfunc("netrw#MakeTgt(dname<".a:dname.">)")
1278 " simplify the target (eg. /abc/def/../ghi -> /abc/ghi)
Bram Moolenaare0fa3742016-02-20 15:47:01 +01001279 let svpos = winsaveview()
Luca Saccarolac363ca12024-12-19 20:16:18 +01001280 " call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
Bram Moolenaara0f849e2015-10-30 14:37:44 +01001281 let s:netrwmftgt_islocal= (a:dname !~ '^\a\{3,}://')
Luca Saccarolac363ca12024-12-19 20:16:18 +01001282 " call Decho("s:netrwmftgt_islocal=".s:netrwmftgt_islocal,'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +01001283 if s:netrwmftgt_islocal
Luca Saccarolac363ca12024-12-19 20:16:18 +01001284 let netrwmftgt= simplify(a:dname)
Bram Moolenaara6878372014-03-22 21:02:50 +01001285 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001286 let netrwmftgt= a:dname
Bram Moolenaara6878372014-03-22 21:02:50 +01001287 endif
1288 if exists("s:netrwmftgt") && netrwmftgt == s:netrwmftgt
Luca Saccarolac363ca12024-12-19 20:16:18 +01001289 " re-selected target, so just clear it
1290 unlet s:netrwmftgt s:netrwmftgt_islocal
Bram Moolenaara6878372014-03-22 21:02:50 +01001291 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001292 let s:netrwmftgt= netrwmftgt
Bram Moolenaara6878372014-03-22 21:02:50 +01001293 endif
1294 if g:netrw_fastbrowse <= 1
Luca Saccarolac363ca12024-12-19 20:16:18 +01001295 call s:NetrwRefresh((b:netrw_curdir !~ '\a\{3,}://'),b:netrw_curdir)
Bram Moolenaara6878372014-03-22 21:02:50 +01001296 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01001297 " call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))"
Bram Moolenaare0fa3742016-02-20 15:47:01 +01001298 call winrestview(svpos)
Luca Saccarolac363ca12024-12-19 20:16:18 +01001299 " call Dret("netrw#MakeTgt")
Bram Moolenaar5c736222010-01-06 20:54:52 +01001300endfun
1301
Bram Moolenaara6878372014-03-22 21:02:50 +01001302" ---------------------------------------------------------------------
1303" netrw#Obtain: {{{2
1304" netrw#Obtain(islocal,fname[,tgtdirectory])
Bram Moolenaarff034192013-04-24 18:51:19 +02001305" islocal=0 obtain from remote source
1306" =1 obtain from local source
1307" fname : a filename or a list of filenames
1308" tgtdir : optional place where files are to go (not present, uses getcwd())
Bram Moolenaara6878372014-03-22 21:02:50 +01001309fun! netrw#Obtain(islocal,fname,...)
Luca Saccarolac363ca12024-12-19 20:16:18 +01001310 " 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 +02001311 " NetrwStatusLine support - for obtaining support
1312
1313 if type(a:fname) == 1
Luca Saccarolac363ca12024-12-19 20:16:18 +01001314 let fnamelist= [ a:fname ]
Bram Moolenaarff034192013-04-24 18:51:19 +02001315 elseif type(a:fname) == 3
Luca Saccarolac363ca12024-12-19 20:16:18 +01001316 let fnamelist= a:fname
Bram Moolenaarff034192013-04-24 18:51:19 +02001317 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001318 call netrw#ErrorMsg(s:ERROR,"attempting to use NetrwObtain on something not a filename or a list",62)
1319 " call Dret("netrw#Obtain")
1320 return
Bram Moolenaarff034192013-04-24 18:51:19 +02001321 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01001322 " call Decho("fnamelist<".string(fnamelist).">",'~'.expand("<slnum>"))
Bram Moolenaarff034192013-04-24 18:51:19 +02001323 if a:0 > 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01001324 let tgtdir= a:1
Bram Moolenaarff034192013-04-24 18:51:19 +02001325 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001326 let tgtdir= getcwd()
Bram Moolenaarff034192013-04-24 18:51:19 +02001327 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01001328 " call Decho("tgtdir<".tgtdir.">",'~'.expand("<slnum>"))
Bram Moolenaarff034192013-04-24 18:51:19 +02001329
1330 if exists("b:netrw_islocal") && b:netrw_islocal
Luca Saccarolac363ca12024-12-19 20:16:18 +01001331 " obtain a file from local b:netrw_curdir to (local) tgtdir
1332 " call Decho("obtain a file from local ".b:netrw_curdir." to ".tgtdir,'~'.expand("<slnum>"))
1333 if exists("b:netrw_curdir") && getcwd() != b:netrw_curdir
1334 let topath= s:ComposePath(tgtdir,"")
1335 if has("win32")
1336 " transfer files one at time
1337 " call Decho("transfer files one at a time",'~'.expand("<slnum>"))
1338 for fname in fnamelist
1339 " call Decho("system(".g:netrw_localcopycmd." ".s:ShellEscape(fname)." ".s:ShellEscape(topath).")",'~'.expand("<slnum>"))
1340 call system(g:netrw_localcopycmd.g:netrw_localcopycmdopt." ".s:ShellEscape(fname)." ".s:ShellEscape(topath))
1341 if v:shell_error != 0
1342 call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localcopycmd<".g:netrw_localcopycmd."> to something that works",80)
1343 " call Dret("s:NetrwObtain 0 : failed: ".g:netrw_localcopycmd." ".s:ShellEscape(fname)." ".s:ShellEscape(topath))
1344 return
1345 endif
1346 endfor
1347 else
1348 " transfer files with one command
1349 " call Decho("transfer files with one command",'~'.expand("<slnum>"))
1350 let filelist= join(map(deepcopy(fnamelist),"s:ShellEscape(v:val)"))
1351 " call Decho("system(".g:netrw_localcopycmd." ".filelist." ".s:ShellEscape(topath).")",'~'.expand("<slnum>"))
1352 call system(g:netrw_localcopycmd.g:netrw_localcopycmdopt." ".filelist." ".s:ShellEscape(topath))
1353 if v:shell_error != 0
1354 call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localcopycmd<".g:netrw_localcopycmd."> to something that works",80)
1355 " call Dret("s:NetrwObtain 0 : failed: ".g:netrw_localcopycmd." ".filelist." ".s:ShellEscape(topath))
1356 return
1357 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02001358 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01001359 elseif !exists("b:netrw_curdir")
1360 call netrw#ErrorMsg(s:ERROR,"local browsing directory doesn't exist!",36)
Bram Moolenaarff034192013-04-24 18:51:19 +02001361 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001362 call netrw#ErrorMsg(s:WARNING,"local browsing directory and current directory are identical",37)
Bram Moolenaarff034192013-04-24 18:51:19 +02001363 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02001364
1365 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001366 " obtain files from remote b:netrw_curdir to local tgtdir
1367 " call Decho("obtain a file from remote ".b:netrw_curdir." to ".tgtdir,'~'.expand("<slnum>"))
1368 if type(a:fname) == 1
1369 call s:SetupNetrwStatusLine('%f %h%m%r%=%9*Obtaining '.a:fname)
Bram Moolenaarff034192013-04-24 18:51:19 +02001370 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01001371 call s:NetrwMethod(b:netrw_curdir)
Bram Moolenaarff034192013-04-24 18:51:19 +02001372
Luca Saccarolac363ca12024-12-19 20:16:18 +01001373 if b:netrw_method == 4
1374 " obtain file using scp
1375 " call Decho("obtain via scp (method#4)",'~'.expand("<slnum>"))
1376 if exists("g:netrw_port") && g:netrw_port != ""
1377 let useport= " ".g:netrw_scpport." ".g:netrw_port
1378 else
1379 let useport= ""
Bram Moolenaarff034192013-04-24 18:51:19 +02001380 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01001381 if b:netrw_fname =~ '/'
1382 let path= substitute(b:netrw_fname,'^\(.*/\).\{-}$','\1','')
1383 else
1384 let path= ""
1385 endif
1386 let filelist= join(map(deepcopy(fnamelist),'escape(s:ShellEscape(g:netrw_machine.":".path.v:val,1)," ")'))
1387 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 +02001388
Luca Saccarolac363ca12024-12-19 20:16:18 +01001389 elseif b:netrw_method == 2
1390 " obtain file using ftp + .netrc
1391 " call Decho("obtain via ftp+.netrc (method #2)",'~'.expand("<slnum>"))
1392 call s:SaveBufVars()|sil NetrwKeepj new|call s:RestoreBufVars()
1393 let tmpbufnr= bufnr("%")
1394 setl ff=unix
1395 if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
1396 NetrwKeepj put =g:netrw_ftpmode
1397 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1398 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02001399
Luca Saccarolac363ca12024-12-19 20:16:18 +01001400 if exists("b:netrw_fname") && b:netrw_fname != ""
1401 call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
1402 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1403 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02001404
Luca Saccarolac363ca12024-12-19 20:16:18 +01001405 if exists("g:netrw_ftpextracmd")
1406 NetrwKeepj put =g:netrw_ftpextracmd
1407 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1408 endif
1409 for fname in fnamelist
1410 call setline(line("$")+1,'get "'.fname.'"')
1411 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1412 endfor
1413 if exists("g:netrw_port") && g:netrw_port != ""
1414 call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
1415 else
1416 call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
1417 endif
1418 " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
1419 if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
1420 let debugkeep= &debug
1421 setl debug=msg
1422 call netrw#ErrorMsg(s:ERROR,getline(1),4)
1423 let &debug= debugkeep
1424 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02001425
Luca Saccarolac363ca12024-12-19 20:16:18 +01001426 elseif b:netrw_method == 3
1427 " obtain with ftp + machine, id, passwd, and fname (ie. no .netrc)
1428 " call Decho("obtain via ftp+mipf (method #3)",'~'.expand("<slnum>"))
1429 call s:SaveBufVars()|sil NetrwKeepj new|call s:RestoreBufVars()
1430 let tmpbufnr= bufnr("%")
1431 setl ff=unix
Bram Moolenaarff034192013-04-24 18:51:19 +02001432
Luca Saccarolac363ca12024-12-19 20:16:18 +01001433 if exists("g:netrw_port") && g:netrw_port != ""
1434 NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
shane.xb.qianc673b802024-12-20 19:36:40 +01001435 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
Luca Saccarolac363ca12024-12-19 20:16:18 +01001436 else
1437 NetrwKeepj put ='open '.g:netrw_machine
1438 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1439 endif
Bram Moolenaar13600302014-05-22 18:26:40 +02001440
Luca Saccarolac363ca12024-12-19 20:16:18 +01001441 if exists("g:netrw_uid") && g:netrw_uid != ""
1442 if exists("g:netrw_ftp") && g:netrw_ftp == 1
1443 NetrwKeepj put =g:netrw_uid
1444 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1445 if exists("s:netrw_passwd") && s:netrw_passwd != ""
1446 NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
1447 endif
shane.xb.qianc673b802024-12-20 19:36:40 +01001448 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
Luca Saccarolac363ca12024-12-19 20:16:18 +01001449 elseif exists("s:netrw_passwd")
1450 NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
1451 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1452 endif
1453 endif
1454
1455 if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
1456 NetrwKeepj put =g:netrw_ftpmode
1457 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1458 endif
1459
1460 if exists("b:netrw_fname") && b:netrw_fname != ""
1461 NetrwKeepj call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
1462 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1463 endif
1464
1465 if exists("g:netrw_ftpextracmd")
1466 NetrwKeepj put =g:netrw_ftpextracmd
1467 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1468 endif
1469
1470 if exists("g:netrw_ftpextracmd")
1471 NetrwKeepj put =g:netrw_ftpextracmd
1472 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1473 endif
1474 for fname in fnamelist
1475 NetrwKeepj call setline(line("$")+1,'get "'.fname.'"')
1476 endfor
1477 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
1478
1479 " perform ftp:
1480 " -i : turns off interactive prompting from ftp
1481 " -n unix : DON'T use <.netrc>, even though it exists
1482 " -n win32: quit being obnoxious about password
1483 " Note: using "_dd to delete to the black hole register; avoids messing up @@
1484 NetrwKeepj norm! 1G"_dd
1485 call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
1486 " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
1487 if getline(1) !~ "^$"
1488 " call Decho("error<".getline(1).">",'~'.expand("<slnum>"))
1489 if !exists("g:netrw_quiet")
1490 NetrwKeepj call netrw#ErrorMsg(s:ERROR,getline(1),5)
1491 endif
1492 endif
1493
1494 elseif b:netrw_method == 9
1495 " obtain file using sftp
1496 " call Decho("obtain via sftp (method #9)",'~'.expand("<slnum>"))
1497 if a:fname =~ '/'
1498 let localfile= substitute(a:fname,'^.*/','','')
1499 else
1500 let localfile= a:fname
1501 endif
1502 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))
1503
1504 elseif !exists("b:netrw_method") || b:netrw_method < 0
1505 " probably a badly formed url; protocol not recognized
1506 " call Dret("netrw#Obtain : unsupported method")
1507 return
1508
Bram Moolenaar13600302014-05-22 18:26:40 +02001509 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001510 " protocol recognized but not supported for Obtain (yet?)
1511 if !exists("g:netrw_quiet")
1512 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"current protocol not supported for obtaining file",97)
1513 endif
1514 " call Dret("netrw#Obtain : current protocol not supported for obtaining file")
1515 return
Bram Moolenaar13600302014-05-22 18:26:40 +02001516 endif
Bram Moolenaar13600302014-05-22 18:26:40 +02001517
Luca Saccarolac363ca12024-12-19 20:16:18 +01001518 " restore status line
1519 if type(a:fname) == 1 && exists("s:netrw_users_stl")
1520 NetrwKeepj call s:SetupNetrwStatusLine(s:netrw_users_stl)
Bram Moolenaar13600302014-05-22 18:26:40 +02001521 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02001522
1523 endif
1524
1525 " cleanup
1526 if exists("tmpbufnr")
Luca Saccarolac363ca12024-12-19 20:16:18 +01001527 if bufnr("%") != tmpbufnr
1528 exe tmpbufnr."bw!"
1529 else
1530 q!
1531 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02001532 endif
1533
Luca Saccarolac363ca12024-12-19 20:16:18 +01001534 " call Dret("netrw#Obtain")
Bram Moolenaara6878372014-03-22 21:02:50 +01001535endfun
1536
1537" ---------------------------------------------------------------------
1538" netrw#Nread: save position, call netrw#NetRead(), and restore position {{{2
1539fun! netrw#Nread(mode,fname)
Luca Saccarolac363ca12024-12-19 20:16:18 +01001540 " call Dfunc("netrw#Nread(mode=".a:mode." fname<".a:fname.">)")
Bram Moolenaare0fa3742016-02-20 15:47:01 +01001541 let svpos= winsaveview()
Luca Saccarolac363ca12024-12-19 20:16:18 +01001542 " call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +01001543 call netrw#NetRead(a:mode,a:fname)
Luca Saccarolac363ca12024-12-19 20:16:18 +01001544 " call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
Bram Moolenaare0fa3742016-02-20 15:47:01 +01001545 call winrestview(svpos)
Bram Moolenaara6878372014-03-22 21:02:50 +01001546
1547 if exists("w:netrw_liststyle") && w:netrw_liststyle != s:TREELIST
Luca Saccarolac363ca12024-12-19 20:16:18 +01001548 if exists("w:netrw_bannercnt")
1549 " start with cursor just after the banner
1550 exe w:netrw_bannercnt
1551 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01001552 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01001553 " call Dret("netrw#Nread")
Bram Moolenaara6878372014-03-22 21:02:50 +01001554endfun
1555
1556" ------------------------------------------------------------------------
Bram Moolenaar85850f32019-07-19 22:05:51 +02001557" s:NetrwOptionsSave: save options prior to setting to "netrw-buffer-standard" form {{{2
1558" Options get restored by s:NetrwOptionsRestore()
1559"
1560" Option handling:
1561" * save user's options (s:NetrwOptionsSave)
1562" * set netrw-safe options (s:NetrwOptionsSafe)
1563" - change an option only when user option != safe option (s:netrwSetSafeSetting)
1564" * restore user's options (s:netrwOPtionsRestore)
1565" - restore a user option when != safe option (s:NetrwRestoreSetting)
1566" vt: (variable type) normally its either "w:" or "s:"
1567fun! s:NetrwOptionsSave(vt)
Luca Saccarolac363ca12024-12-19 20:16:18 +01001568 " call Dfunc("s:NetrwOptionsSave(vt<".a:vt.">) win#".winnr()." buf#".bufnr("%")."<".bufname(bufnr("%")).">"." winnr($)=".winnr("$")." mod=".&mod." ma=".&ma)
1569 " call Decho(a:vt."netrw_optionsave".(exists("{a:vt}netrw_optionsave")? ("=".{a:vt}netrw_optionsave) : " doesn't exist"),'~'.expand("<slnum>"))
1570 " 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>"))
1571 " call Decho("(s:NetrwOptionsSave) lines=".&lines)
Bram Moolenaar85850f32019-07-19 22:05:51 +02001572
1573 if !exists("{a:vt}netrw_optionsave")
Luca Saccarolac363ca12024-12-19 20:16:18 +01001574 let {a:vt}netrw_optionsave= 1
Bram Moolenaar85850f32019-07-19 22:05:51 +02001575 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001576 " call Dret("s:NetrwOptionsSave : options already saved")
1577 return
Bram Moolenaar85850f32019-07-19 22:05:51 +02001578 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01001579 " 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 +02001580
1581 " Save current settings and current directory
Luca Saccarolac363ca12024-12-19 20:16:18 +01001582 " call Decho("saving current settings and current directory",'~'.expand("<slnum>"))
Bram Moolenaar85850f32019-07-19 22:05:51 +02001583 let s:yykeep = @@
1584 if exists("&l:acd")|let {a:vt}netrw_acdkeep = &l:acd|endif
1585 let {a:vt}netrw_aikeep = &l:ai
1586 let {a:vt}netrw_awkeep = &l:aw
1587 let {a:vt}netrw_bhkeep = &l:bh
1588 let {a:vt}netrw_blkeep = &l:bl
1589 let {a:vt}netrw_btkeep = &l:bt
1590 let {a:vt}netrw_bombkeep = &l:bomb
1591 let {a:vt}netrw_cedit = &cedit
1592 let {a:vt}netrw_cikeep = &l:ci
1593 let {a:vt}netrw_cinkeep = &l:cin
1594 let {a:vt}netrw_cinokeep = &l:cino
1595 let {a:vt}netrw_comkeep = &l:com
1596 let {a:vt}netrw_cpokeep = &l:cpo
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001597 let {a:vt}netrw_cuckeep = &l:cuc
1598 let {a:vt}netrw_culkeep = &l:cul
Luca Saccarolac363ca12024-12-19 20:16:18 +01001599 " call Decho("(s:NetrwOptionsSave) COMBAK: cuc=".&l:cuc." cul=".&l:cul)
Bram Moolenaar85850f32019-07-19 22:05:51 +02001600 let {a:vt}netrw_diffkeep = &l:diff
1601 let {a:vt}netrw_fenkeep = &l:fen
Bram Moolenaar85850f32019-07-19 22:05:51 +02001602 if !exists("g:netrw_ffkeep") || g:netrw_ffkeep
Luca Saccarolac363ca12024-12-19 20:16:18 +01001603 let {a:vt}netrw_ffkeep = &l:ff
Bram Moolenaar85850f32019-07-19 22:05:51 +02001604 endif
1605 let {a:vt}netrw_fokeep = &l:fo " formatoptions
1606 let {a:vt}netrw_gdkeep = &l:gd " gdefault
Bram Moolenaar71badf92023-04-22 22:40:14 +01001607 let {a:vt}netrw_gokeep = &go " guioptions
Bram Moolenaar85850f32019-07-19 22:05:51 +02001608 let {a:vt}netrw_hidkeep = &l:hidden
1609 let {a:vt}netrw_imkeep = &l:im
1610 let {a:vt}netrw_iskkeep = &l:isk
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001611 let {a:vt}netrw_lines = &lines
Bram Moolenaar85850f32019-07-19 22:05:51 +02001612 let {a:vt}netrw_lskeep = &l:ls
1613 let {a:vt}netrw_makeep = &l:ma
1614 let {a:vt}netrw_magickeep = &l:magic
1615 let {a:vt}netrw_modkeep = &l:mod
1616 let {a:vt}netrw_nukeep = &l:nu
1617 let {a:vt}netrw_rnukeep = &l:rnu
1618 let {a:vt}netrw_repkeep = &l:report
1619 let {a:vt}netrw_rokeep = &l:ro
1620 let {a:vt}netrw_selkeep = &l:sel
1621 let {a:vt}netrw_spellkeep = &l:spell
Bram Moolenaar85850f32019-07-19 22:05:51 +02001622 if !g:netrw_use_noswf
Luca Saccarolac363ca12024-12-19 20:16:18 +01001623 let {a:vt}netrw_swfkeep = &l:swf
Bram Moolenaar85850f32019-07-19 22:05:51 +02001624 endif
1625 let {a:vt}netrw_tskeep = &l:ts
1626 let {a:vt}netrw_twkeep = &l:tw " textwidth
1627 let {a:vt}netrw_wigkeep = &l:wig " wildignore
1628 let {a:vt}netrw_wrapkeep = &l:wrap
1629 let {a:vt}netrw_writekeep = &l:write
1630
1631 " save a few selected netrw-related variables
Luca Saccarolac363ca12024-12-19 20:16:18 +01001632 " call Decho("saving a few selected netrw-related variables",'~'.expand("<slnum>"))
Bram Moolenaar85850f32019-07-19 22:05:51 +02001633 if g:netrw_keepdir
Luca Saccarolac363ca12024-12-19 20:16:18 +01001634 let {a:vt}netrw_dirkeep = getcwd()
1635 " call Decho("saving to ".a:vt."netrw_dirkeep<".{a:vt}netrw_dirkeep.">",'~'.expand("<slnum>"))
Bram Moolenaar85850f32019-07-19 22:05:51 +02001636 endif
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001637 if has("clipboard") && g:netrw_clipboard
Luca Saccarolac363ca12024-12-19 20:16:18 +01001638 sil! let {a:vt}netrw_starkeep = @*
1639 sil! let {a:vt}netrw_pluskeep = @+
Bram Moolenaar85850f32019-07-19 22:05:51 +02001640 endif
1641 sil! let {a:vt}netrw_slashkeep= @/
1642
Luca Saccarolac363ca12024-12-19 20:16:18 +01001643 " call Decho("(s:NetrwOptionsSave) lines=".&lines)
1644 " 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>"))
1645 " call Dret("s:NetrwOptionsSave : tab#".tabpagenr()." win#".winnr())
Bram Moolenaar85850f32019-07-19 22:05:51 +02001646endfun
1647
1648" ---------------------------------------------------------------------
1649" s:NetrwOptionsSafe: sets options to help netrw do its job {{{2
1650" Use s:NetrwSaveOptions() to save user settings
1651" Use s:NetrwOptionsRestore() to restore user settings
1652fun! s:NetrwOptionsSafe(islocal)
Luca Saccarolac363ca12024-12-19 20:16:18 +01001653 " call Dfunc("s:NetrwOptionsSafe(islocal=".a:islocal.") win#".winnr()." buf#".bufnr("%")."<".bufname(bufnr("%"))."> winnr($)=".winnr("$"))
1654 " call Decho("win#".winnr()."'s ft=".&ft,'~'.expand("<slnum>"))
1655 " 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 +02001656 if exists("+acd") | call s:NetrwSetSafeSetting("&l:acd",0)|endif
1657 call s:NetrwSetSafeSetting("&l:ai",0)
1658 call s:NetrwSetSafeSetting("&l:aw",0)
1659 call s:NetrwSetSafeSetting("&l:bl",0)
1660 call s:NetrwSetSafeSetting("&l:bomb",0)
1661 if a:islocal
Luca Saccarolac363ca12024-12-19 20:16:18 +01001662 call s:NetrwSetSafeSetting("&l:bt","nofile")
Bram Moolenaar85850f32019-07-19 22:05:51 +02001663 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001664 call s:NetrwSetSafeSetting("&l:bt","acwrite")
Bram Moolenaar85850f32019-07-19 22:05:51 +02001665 endif
1666 call s:NetrwSetSafeSetting("&l:ci",0)
1667 call s:NetrwSetSafeSetting("&l:cin",0)
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001668 if g:netrw_fastbrowse > a:islocal
Luca Saccarolac363ca12024-12-19 20:16:18 +01001669 call s:NetrwSetSafeSetting("&l:bh","hide")
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001670 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001671 call s:NetrwSetSafeSetting("&l:bh","delete")
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001672 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02001673 call s:NetrwSetSafeSetting("&l:cino","")
1674 call s:NetrwSetSafeSetting("&l:com","")
1675 if &cpo =~ 'a' | call s:NetrwSetSafeSetting("&cpo",substitute(&cpo,'a','','g')) | endif
1676 if &cpo =~ 'A' | call s:NetrwSetSafeSetting("&cpo",substitute(&cpo,'A','','g')) | endif
1677 setl fo=nroql2
Bram Moolenaar71badf92023-04-22 22:40:14 +01001678 if &go =~ 'a' | set go-=a | endif
1679 if &go =~ 'A' | set go-=A | endif
1680 if &go =~ 'P' | set go-=P | endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02001681 call s:NetrwSetSafeSetting("&l:hid",0)
1682 call s:NetrwSetSafeSetting("&l:im",0)
1683 setl isk+=@ isk+=* isk+=/
1684 call s:NetrwSetSafeSetting("&l:magic",1)
1685 if g:netrw_use_noswf
Luca Saccarolac363ca12024-12-19 20:16:18 +01001686 call s:NetrwSetSafeSetting("swf",0)
Bram Moolenaar85850f32019-07-19 22:05:51 +02001687 endif
1688 call s:NetrwSetSafeSetting("&l:report",10000)
1689 call s:NetrwSetSafeSetting("&l:sel","inclusive")
1690 call s:NetrwSetSafeSetting("&l:spell",0)
1691 call s:NetrwSetSafeSetting("&l:tw",0)
1692 call s:NetrwSetSafeSetting("&l:wig","")
1693 setl cedit&
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001694
1695 " set up cuc and cul based on g:netrw_cursor and listing style
1696 " COMBAK -- cuc cul related
1697 call s:NetrwCursor(0)
Bram Moolenaar85850f32019-07-19 22:05:51 +02001698
1699 " allow the user to override safe options
Luca Saccarolac363ca12024-12-19 20:16:18 +01001700 " call Decho("ft<".&ft."> ei=".&ei,'~'.expand("<slnum>"))
Bram Moolenaar85850f32019-07-19 22:05:51 +02001701 if &ft == "netrw"
Luca Saccarolac363ca12024-12-19 20:16:18 +01001702 " call Decho("do any netrw FileType autocmds (doau FileType netrw)",'~'.expand("<slnum>"))
1703 keepalt NetrwKeepj doau FileType netrw
Bram Moolenaar85850f32019-07-19 22:05:51 +02001704 endif
1705
Luca Saccarolac363ca12024-12-19 20:16:18 +01001706 " call Decho("fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist")." bh=".&l:bh." bt<".&bt.">",'~'.expand("<slnum>"))
1707 " 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>"))
1708 " call Dret("s:NetrwOptionsSafe")
Bram Moolenaar85850f32019-07-19 22:05:51 +02001709endfun
1710
1711" ---------------------------------------------------------------------
1712" s:NetrwOptionsRestore: restore options (based on prior s:NetrwOptionsSave) {{{2
1713fun! s:NetrwOptionsRestore(vt)
Bram Moolenaara6878372014-03-22 21:02:50 +01001714 if !exists("{a:vt}netrw_optionsave")
Luca Saccarolac363ca12024-12-19 20:16:18 +01001715 " filereadable() returns zero for remote files (e.g. scp://user@localhost//etc/fstab)
1716 " Note: @ may not be in 'isfname', so '^\w\+://\f\+/' may not match
1717 if filereadable(expand("%")) || expand("%") =~# '^\w\+://\f\+'
1718 filetype detect
1719 else
1720 setl ft=netrw
1721 endif
1722 return
Bram Moolenaara6878372014-03-22 21:02:50 +01001723 endif
1724 unlet {a:vt}netrw_optionsave
1725
1726 if exists("+acd")
Luca Saccarolac363ca12024-12-19 20:16:18 +01001727 if exists("{a:vt}netrw_acdkeep")
1728 let curdir = getcwd()
1729 let &l:acd = {a:vt}netrw_acdkeep
1730 unlet {a:vt}netrw_acdkeep
1731 if &l:acd
1732 call s:NetrwLcd(curdir)
1733 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01001734 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01001735 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02001736 call s:NetrwRestoreSetting(a:vt."netrw_aikeep","&l:ai")
1737 call s:NetrwRestoreSetting(a:vt."netrw_awkeep","&l:aw")
1738 call s:NetrwRestoreSetting(a:vt."netrw_blkeep","&l:bl")
1739 call s:NetrwRestoreSetting(a:vt."netrw_btkeep","&l:bt")
1740 call s:NetrwRestoreSetting(a:vt."netrw_bombkeep","&l:bomb")
1741 call s:NetrwRestoreSetting(a:vt."netrw_cedit","&cedit")
1742 call s:NetrwRestoreSetting(a:vt."netrw_cikeep","&l:ci")
1743 call s:NetrwRestoreSetting(a:vt."netrw_cinkeep","&l:cin")
1744 call s:NetrwRestoreSetting(a:vt."netrw_cinokeep","&l:cino")
1745 call s:NetrwRestoreSetting(a:vt."netrw_comkeep","&l:com")
1746 call s:NetrwRestoreSetting(a:vt."netrw_cpokeep","&l:cpo")
1747 call s:NetrwRestoreSetting(a:vt."netrw_diffkeep","&l:diff")
1748 call s:NetrwRestoreSetting(a:vt."netrw_fenkeep","&l:fen")
1749 if exists("g:netrw_ffkeep") && g:netrw_ffkeep
Luca Saccarolac363ca12024-12-19 20:16:18 +01001750 call s:NetrwRestoreSetting(a:vt."netrw_ffkeep")","&l:ff")
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01001751 endif
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001752 call s:NetrwRestoreSetting(a:vt."netrw_fokeep" ,"&l:fo")
1753 call s:NetrwRestoreSetting(a:vt."netrw_gdkeep" ,"&l:gd")
Bram Moolenaar71badf92023-04-22 22:40:14 +01001754 call s:NetrwRestoreSetting(a:vt."netrw_gokeep" ,"&go")
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001755 call s:NetrwRestoreSetting(a:vt."netrw_hidkeep" ,"&l:hidden")
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001756 call s:NetrwRestoreSetting(a:vt."netrw_imkeep" ,"&l:im")
1757 call s:NetrwRestoreSetting(a:vt."netrw_iskkeep" ,"&l:isk")
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001758 call s:NetrwRestoreSetting(a:vt."netrw_lines" ,"&lines")
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001759 call s:NetrwRestoreSetting(a:vt."netrw_lskeep" ,"&l:ls")
1760 call s:NetrwRestoreSetting(a:vt."netrw_makeep" ,"&l:ma")
Bram Moolenaar85850f32019-07-19 22:05:51 +02001761 call s:NetrwRestoreSetting(a:vt."netrw_magickeep","&l:magic")
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001762 call s:NetrwRestoreSetting(a:vt."netrw_modkeep" ,"&l:mod")
1763 call s:NetrwRestoreSetting(a:vt."netrw_nukeep" ,"&l:nu")
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001764 call s:NetrwRestoreSetting(a:vt."netrw_rnukeep" ,"&l:rnu")
1765 call s:NetrwRestoreSetting(a:vt."netrw_repkeep" ,"&l:report")
1766 call s:NetrwRestoreSetting(a:vt."netrw_rokeep" ,"&l:ro")
1767 call s:NetrwRestoreSetting(a:vt."netrw_selkeep" ,"&l:sel")
Bram Moolenaar85850f32019-07-19 22:05:51 +02001768 call s:NetrwRestoreSetting(a:vt."netrw_spellkeep","&l:spell")
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001769 call s:NetrwRestoreSetting(a:vt."netrw_twkeep" ,"&l:tw")
1770 call s:NetrwRestoreSetting(a:vt."netrw_wigkeep" ,"&l:wig")
1771 call s:NetrwRestoreSetting(a:vt."netrw_wrapkeep" ,"&l:wrap")
Bram Moolenaar85850f32019-07-19 22:05:51 +02001772 call s:NetrwRestoreSetting(a:vt."netrw_writekeep","&l:write")
1773 call s:NetrwRestoreSetting("s:yykeep","@@")
1774 " former problem: start with liststyle=0; press <i> : result, following line resets l:ts.
1775 " Fixed; in s:PerformListing, when w:netrw_liststyle is s:LONGLIST, will use a printf to pad filename with spaces
1776 " rather than by appending a tab which previously was using "&ts" to set the desired spacing. (Sep 28, 2018)
1777 call s:NetrwRestoreSetting(a:vt."netrw_tskeep","&l:ts")
1778
Bram Moolenaara6878372014-03-22 21:02:50 +01001779 if exists("{a:vt}netrw_swfkeep")
Luca Saccarolac363ca12024-12-19 20:16:18 +01001780 if &directory == ""
1781 " user hasn't specified a swapfile directory;
1782 " netrw will temporarily set the swapfile directory
1783 " to the current directory as returned by getcwd().
1784 let &l:directory= getcwd()
1785 sil! let &l:swf = {a:vt}netrw_swfkeep
1786 setl directory=
1787 unlet {a:vt}netrw_swfkeep
1788 elseif &l:swf != {a:vt}netrw_swfkeep
1789 if !g:netrw_use_noswf
1790 " following line causes a Press ENTER in windows -- can't seem to work around it!!!
1791 sil! let &l:swf= {a:vt}netrw_swfkeep
1792 endif
1793 unlet {a:vt}netrw_swfkeep
Bram Moolenaare0fa3742016-02-20 15:47:01 +01001794 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01001795 endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +01001796 if exists("{a:vt}netrw_dirkeep") && isdirectory(s:NetrwFile({a:vt}netrw_dirkeep)) && g:netrw_keepdir
Luca Saccarolac363ca12024-12-19 20:16:18 +01001797 let dirkeep = substitute({a:vt}netrw_dirkeep,'\\','/','g')
1798 if exists("{a:vt}netrw_dirkeep")
1799 call s:NetrwLcd(dirkeep)
1800 unlet {a:vt}netrw_dirkeep
1801 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01001802 endif
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001803 if has("clipboard") && g:netrw_clipboard
Luca Saccarolac363ca12024-12-19 20:16:18 +01001804 call s:NetrwRestoreSetting(a:vt."netrw_starkeep","@*")
1805 call s:NetrwRestoreSetting(a:vt."netrw_pluskeep","@+")
Bram Moolenaara6878372014-03-22 21:02:50 +01001806 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02001807 call s:NetrwRestoreSetting(a:vt."netrw_slashkeep","@/")
Bram Moolenaara6878372014-03-22 21:02:50 +01001808
Bram Moolenaara6878372014-03-22 21:02:50 +01001809 " Moved the filetype detect here from NetrwGetFile() because remote files
1810 " were having their filetype detect-generated settings overwritten by
1811 " NetrwOptionRestore.
1812 if &ft != "netrw"
Luca Saccarolac363ca12024-12-19 20:16:18 +01001813 filetype detect
Bram Moolenaara6878372014-03-22 21:02:50 +01001814 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01001815endfun
1816
1817" ---------------------------------------------------------------------
Bram Moolenaar85850f32019-07-19 22:05:51 +02001818" s:NetrwSetSafeSetting: sets an option to a safe setting {{{2
1819" but only when the options' value and the safe setting differ
1820" Doing this means that netrw will not come up as having changed a
1821" setting last when it really didn't actually change it.
1822"
1823" Called from s:NetrwOptionsSafe
1824" ex. call s:NetrwSetSafeSetting("&l:sel","inclusive")
1825fun! s:NetrwSetSafeSetting(setting,safesetting)
Luca Saccarolac363ca12024-12-19 20:16:18 +01001826 " call Dfunc("s:NetrwSetSafeSetting(setting<".a:setting."> safesetting<".a:safesetting.">)")
Bram Moolenaara6878372014-03-22 21:02:50 +01001827
Bram Moolenaar85850f32019-07-19 22:05:51 +02001828 if a:setting =~ '^&'
Luca Saccarolac363ca12024-12-19 20:16:18 +01001829 " call Decho("fyi: a:setting starts with &")
1830 exe "let settingval= ".a:setting
1831 " call Decho("fyi: settingval<".settingval.">")
Bram Moolenaara6878372014-03-22 21:02:50 +01001832
Luca Saccarolac363ca12024-12-19 20:16:18 +01001833 if settingval != a:safesetting
1834 " call Decho("set setting<".a:setting."> to option value<".a:safesetting.">")
1835 if type(a:safesetting) == 0
1836 exe "let ".a:setting."=".a:safesetting
1837 elseif type(a:safesetting) == 1
1838 exe "let ".a:setting."= '".a:safesetting."'"
1839 else
1840 call netrw#ErrorMsg(s:ERROR,"(s:NetrwRestoreSetting) doesn't know how to restore ".a:setting." with a safesetting of type#".type(a:safesetting),105)
1841 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02001842 endif
Bram Moolenaar13600302014-05-22 18:26:40 +02001843 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01001844
Luca Saccarolac363ca12024-12-19 20:16:18 +01001845 " call Dret("s:NetrwSetSafeSetting")
Bram Moolenaara6878372014-03-22 21:02:50 +01001846endfun
1847
1848" ------------------------------------------------------------------------
Bram Moolenaar85850f32019-07-19 22:05:51 +02001849" s:NetrwRestoreSetting: restores specified setting using associated keepvar, {{{2
1850" but only if the setting value differs from the associated keepvar.
1851" Doing this means that netrw will not come up as having changed a
1852" setting last when it really didn't actually change it.
1853"
Viktor Szépedbf749b2023-10-16 09:53:37 +02001854" Used by s:NetrwOptionsRestore() to restore each netrw-sensitive setting
Bram Moolenaar85850f32019-07-19 22:05:51 +02001855" keepvars are set up by s:NetrwOptionsSave
1856fun! s:NetrwRestoreSetting(keepvar,setting)
Luca Saccarolac363ca12024-12-19 20:16:18 +01001857 """ call Dfunc("s:NetrwRestoreSetting(a:keepvar<".a:keepvar."> a:setting<".a:setting.">)")
Bram Moolenaara6878372014-03-22 21:02:50 +01001858
Bram Moolenaar85850f32019-07-19 22:05:51 +02001859 " typically called from s:NetrwOptionsRestore
1860 " call s:NetrwRestoreSettings(keep-option-variable-name,'associated-option')
1861 " ex. call s:NetrwRestoreSetting(a:vt."netrw_selkeep","&l:sel")
Bram Moolenaar89a9c152021-08-29 21:55:35 +02001862 " Restores option (but only if different) from a:keepvar
Bram Moolenaar85850f32019-07-19 22:05:51 +02001863 if exists(a:keepvar)
Luca Saccarolac363ca12024-12-19 20:16:18 +01001864 exe "let keepvarval= ".a:keepvar
1865 exe "let setting= ".a:setting
Bram Moolenaar85850f32019-07-19 22:05:51 +02001866
Luca Saccarolac363ca12024-12-19 20:16:18 +01001867 "" call Decho("fyi: a:keepvar<".a:keepvar."> exists")
1868 "" call Decho("fyi: keepvarval=".keepvarval)
1869 "" call Decho("fyi: a:setting<".a:setting."> setting<".setting.">")
Bram Moolenaar85850f32019-07-19 22:05:51 +02001870
Luca Saccarolac363ca12024-12-19 20:16:18 +01001871 if setting != keepvarval
1872 "" call Decho("restore setting<".a:setting."> (currently=".setting.") to keepvarval<".keepvarval.">")
1873 if type(a:setting) == 0
1874 exe "let ".a:setting."= ".keepvarval
1875 elseif type(a:setting) == 1
1876 exe "let ".a:setting."= '".substitute(keepvarval,"'","''","g")."'"
1877 else
1878 call netrw#ErrorMsg(s:ERROR,"(s:NetrwRestoreSetting) doesn't know how to restore ".a:keepvar." with a setting of type#".type(a:setting),105)
1879 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02001880 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02001881
Luca Saccarolac363ca12024-12-19 20:16:18 +01001882 exe "unlet ".a:keepvar
Bram Moolenaara6878372014-03-22 21:02:50 +01001883 endif
1884
Luca Saccarolac363ca12024-12-19 20:16:18 +01001885 "" call Dret("s:NetrwRestoreSetting")
Bram Moolenaarff034192013-04-24 18:51:19 +02001886endfun
1887
1888" ---------------------------------------------------------------------
1889" NetrwStatusLine: {{{2
1890fun! NetrwStatusLine()
1891
Luca Saccarolac363ca12024-12-19 20:16:18 +01001892 " vvv NetrwStatusLine() debugging vvv
1893 " let g:stlmsg=""
1894 " if !exists("w:netrw_explore_bufnr")
1895 " let g:stlmsg="!X<explore_bufnr>"
1896 " elseif w:netrw_explore_bufnr != bufnr("%")
1897 " let g:stlmsg="explore_bufnr!=".bufnr("%")
1898 " endif
1899 " if !exists("w:netrw_explore_line")
1900 " let g:stlmsg=" !X<explore_line>"
1901 " elseif w:netrw_explore_line != line(".")
1902 " let g:stlmsg=" explore_line!={line(.)<".line(".").">"
1903 " endif
1904 " if !exists("w:netrw_explore_list")
1905 " let g:stlmsg=" !X<explore_list>"
1906 " endif
1907 " ^^^ NetrwStatusLine() debugging ^^^
Bram Moolenaarff034192013-04-24 18:51:19 +02001908
1909 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 +01001910 " restore user's status line
1911 let &l:stl = s:netrw_users_stl
1912 let &laststatus = s:netrw_users_ls
1913 if exists("w:netrw_explore_bufnr")|unlet w:netrw_explore_bufnr|endif
1914 if exists("w:netrw_explore_line") |unlet w:netrw_explore_line |endif
1915 return ""
Bram Moolenaarff034192013-04-24 18:51:19 +02001916 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001917 return "Match ".w:netrw_explore_mtchcnt." of ".w:netrw_explore_listlen
Bram Moolenaarff034192013-04-24 18:51:19 +02001918 endif
1919endfun
1920
Bram Moolenaar85850f32019-07-19 22:05:51 +02001921" ===============================
Bram Moolenaarafeb4fa2006-02-01 21:51:12 +00001922" Netrw Transfer Functions: {{{1
1923" ===============================
1924
Bram Moolenaar071d4272004-06-13 20:20:40 +00001925" ------------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +00001926" netrw#NetRead: responsible for reading a file over the net {{{2
Bram Moolenaar9964e462007-05-05 17:54:07 +00001927" mode: =0 read remote file and insert before current line
1928" =1 read remote file and insert after current line
1929" =2 replace with remote file
1930" =3 obtain file, but leave in temporary format
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00001931fun! netrw#NetRead(mode,...)
Luca Saccarolac363ca12024-12-19 20:16:18 +01001932 " 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 +00001933
Bram Moolenaar5c736222010-01-06 20:54:52 +01001934 " NetRead: save options {{{3
Bram Moolenaar85850f32019-07-19 22:05:51 +02001935 call s:NetrwOptionsSave("w:")
1936 call s:NetrwOptionsSafe(0)
Bram Moolenaar00a927d2010-05-14 23:24:24 +02001937 call s:RestoreCursorline()
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01001938 " NetrwSafeOptions sets a buffer up for a netrw listing, which includes buflisting off.
1939 " However, this setting is not wanted for a remote editing session. The buffer should be "nofile", still.
1940 setl bl
Luca Saccarolac363ca12024-12-19 20:16:18 +01001941 " call Decho("buf#".bufnr("%")."<".bufname("%")."> bl=".&bl." bt=".&bt." bh=".&bh,'~'.expand("<slnum>"))
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00001942
Bram Moolenaar5c736222010-01-06 20:54:52 +01001943 " NetRead: interpret mode into a readcmd {{{3
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00001944 if a:mode == 0 " read remote file before current line
Luca Saccarolac363ca12024-12-19 20:16:18 +01001945 let readcmd = "0r"
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00001946 elseif a:mode == 1 " read file after current line
Luca Saccarolac363ca12024-12-19 20:16:18 +01001947 let readcmd = "r"
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00001948 elseif a:mode == 2 " replace with remote file
Luca Saccarolac363ca12024-12-19 20:16:18 +01001949 let readcmd = "%r"
Bram Moolenaar9964e462007-05-05 17:54:07 +00001950 elseif a:mode == 3 " skip read of file (leave as temporary)
Luca Saccarolac363ca12024-12-19 20:16:18 +01001951 let readcmd = "t"
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00001952 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01001953 exe a:mode
1954 let readcmd = "r"
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00001955 endif
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00001956 let ichoice = (a:0 == 0)? 0 : 1
Luca Saccarolac363ca12024-12-19 20:16:18 +01001957 " call Decho("readcmd<".readcmd."> ichoice=".ichoice,'~'.expand("<slnum>"))
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00001958
Bram Moolenaar5c736222010-01-06 20:54:52 +01001959 " NetRead: get temporary filename {{{3
Bram Moolenaar9964e462007-05-05 17:54:07 +00001960 let tmpfile= s:GetTempfile("")
1961 if tmpfile == ""
Luca Saccarolac363ca12024-12-19 20:16:18 +01001962 " call Dret("netrw#NetRead : unable to get a tempfile!")
1963 return
Bram Moolenaar5b8d8fd2005-08-16 23:01:50 +00001964 endif
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00001965
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00001966 while ichoice <= a:0
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00001967
Luca Saccarolac363ca12024-12-19 20:16:18 +01001968 " attempt to repeat with previous host-file-etc
1969 if exists("b:netrw_lastfile") && a:0 == 0
1970 " call Decho("using b:netrw_lastfile<" . b:netrw_lastfile . ">",'~'.expand("<slnum>"))
1971 let choice = b:netrw_lastfile
1972 let ichoice= ichoice + 1
1973
1974 else
1975 exe "let choice= a:" . ichoice
1976 " call Decho("no lastfile: choice<" . choice . ">",'~'.expand("<slnum>"))
1977
1978 if match(choice,"?") == 0
1979 " give help
1980 echomsg 'NetRead Usage:'
1981 echomsg ':Nread machine:path uses rcp'
1982 echomsg ':Nread "machine path" uses ftp with <.netrc>'
1983 echomsg ':Nread "machine id password path" uses ftp'
1984 echomsg ':Nread dav://machine[:port]/path uses cadaver'
1985 echomsg ':Nread fetch://machine/path uses fetch'
1986 echomsg ':Nread ftp://[user@]machine[:port]/path uses ftp autodetects <.netrc>'
1987 echomsg ':Nread http://[user@]machine/path uses http wget'
1988 echomsg ':Nread file:///path uses elinks'
1989 echomsg ':Nread https://[user@]machine/path uses http wget'
1990 echomsg ':Nread rcp://[user@]machine/path uses rcp'
1991 echomsg ':Nread rsync://machine[:port]/path uses rsync'
1992 echomsg ':Nread scp://[user@]machine[[:#]port]/path uses scp'
1993 echomsg ':Nread sftp://[user@]machine[[:#]port]/path uses sftp'
1994 sleep 4
1995 break
1996
1997 elseif match(choice,'^"') != -1
1998 " Reconstruct Choice if choice starts with '"'
1999 " call Decho("reconstructing choice",'~'.expand("<slnum>"))
2000 if match(choice,'"$') != -1
2001 " case "..."
2002 let choice= strpart(choice,1,strlen(choice)-2)
2003 else
2004 " case "... ... ..."
2005 let choice = strpart(choice,1,strlen(choice)-1)
2006 let wholechoice = ""
2007
2008 while match(choice,'"$') == -1
2009 let wholechoice = wholechoice . " " . choice
2010 let ichoice = ichoice + 1
2011 if ichoice > a:0
2012 if !exists("g:netrw_quiet")
2013 call netrw#ErrorMsg(s:ERROR,"Unbalanced string in filename '". wholechoice ."'",3)
2014 endif
2015 " call Dret("netrw#NetRead :2 getcwd<".getcwd().">")
2016 return
2017 endif
2018 let choice= a:{ichoice}
2019 endwhile
2020 let choice= strpart(wholechoice,1,strlen(wholechoice)-1) . " " . strpart(choice,0,strlen(choice)-1)
2021 endif
2022 endif
2023 endif
2024
2025 " call Decho("choice<" . choice . ">",'~'.expand("<slnum>"))
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002026 let ichoice= ichoice + 1
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002027
Luca Saccarolac363ca12024-12-19 20:16:18 +01002028 " NetRead: Determine method of read (ftp, rcp, etc) {{{3
2029 call s:NetrwMethod(choice)
2030 if !exists("b:netrw_method") || b:netrw_method < 0
2031 " call Dret("netrw#NetRead : unsupported method")
2032 return
2033 endif
2034 let tmpfile= s:GetTempfile(b:netrw_fname) " apply correct suffix
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002035
Luca Saccarolac363ca12024-12-19 20:16:18 +01002036 " Check whether or not NetrwBrowse() should be handling this request
2037 " call Decho("checking if NetrwBrowse() should handle choice<".choice."> with netrw_list_cmd<".g:netrw_list_cmd.">",'~'.expand("<slnum>"))
2038 if choice =~ "^.*[\/]$" && b:netrw_method != 5 && choice !~ '^https\=://'
2039 " call Decho("yes, choice matches '^.*[\/]$'",'~'.expand("<slnum>"))
2040 NetrwKeepj call s:NetrwBrowse(0,choice)
2041 " call Dret("netrw#NetRead :3 getcwd<".getcwd().">")
2042 return
2043 endif
Bram Moolenaard4755bb2004-09-02 19:12:26 +00002044
Luca Saccarolac363ca12024-12-19 20:16:18 +01002045 " ============
2046 " NetRead: Perform Protocol-Based Read {{{3
2047 " ===========================
2048 if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1
2049 echo "(netrw) Processing your read request..."
2050 endif
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002051
Luca Saccarolac363ca12024-12-19 20:16:18 +01002052 ".........................................
2053 " NetRead: (rcp) NetRead Method #1 {{{3
2054 if b:netrw_method == 1 " read with rcp
2055 " call Decho("read via rcp (method #1)",'~'.expand("<slnum>"))
2056 " ER: nothing done with g:netrw_uid yet?
2057 " ER: on Win2K" rcp machine[.user]:file tmpfile
2058 " ER: when machine contains '.' adding .user is required (use $USERNAME)
2059 " ER: the tmpfile is full path: rcp sees C:\... as host C
2060 if s:netrw_has_nt_rcp == 1
2061 if exists("g:netrw_uid") && ( g:netrw_uid != "" )
2062 let uid_machine = g:netrw_machine .'.'. g:netrw_uid
2063 else
2064 " Any way needed it machine contains a '.'
2065 let uid_machine = g:netrw_machine .'.'. $USERNAME
K.Takata71d0ba02024-01-10 03:21:05 +09002066 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01002067 else
2068 if exists("g:netrw_uid") && ( g:netrw_uid != "" )
2069 let uid_machine = g:netrw_uid .'@'. g:netrw_machine
2070 else
2071 let uid_machine = g:netrw_machine
2072 endif
Bram Moolenaar5b435d62012-04-05 17:33:26 +02002073 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01002074 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))
2075 let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2076 let b:netrw_lastfile = choice
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002077
Luca Saccarolac363ca12024-12-19 20:16:18 +01002078 ".........................................
shane.xb.qianc673b802024-12-20 19:36:40 +01002079 " NetRead: (ftp + <.netrc>) NetRead Method #2 {{{3
Luca Saccarolac363ca12024-12-19 20:16:18 +01002080 elseif b:netrw_method == 2 " read with ftp + <.netrc>
2081 " call Decho("read via ftp+.netrc (method #2)",'~'.expand("<slnum>"))
2082 let netrw_fname= b:netrw_fname
2083 NetrwKeepj call s:SaveBufVars()|new|NetrwKeepj call s:RestoreBufVars()
2084 let filtbuf= bufnr("%")
2085 setl ff=unix
2086 NetrwKeepj put =g:netrw_ftpmode
2087 " call Decho("filter input: ".getline(line("$")),'~'.expand("<slnum>"))
2088 if exists("g:netrw_ftpextracmd")
2089 NetrwKeepj put =g:netrw_ftpextracmd
2090 " call Decho("filter input: ".getline(line("$")),'~'.expand("<slnum>"))
2091 endif
2092 call setline(line("$")+1,'get "'.netrw_fname.'" '.tmpfile)
2093 " call Decho("filter input: ".getline(line("$")),'~'.expand("<slnum>"))
2094 if exists("g:netrw_port") && g:netrw_port != ""
2095 call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
2096 else
2097 call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
2098 endif
2099 " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2100 if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
2101 let debugkeep = &debug
2102 setl debug=msg
2103 NetrwKeepj call netrw#ErrorMsg(s:ERROR,getline(1),4)
2104 let &debug = debugkeep
2105 endif
2106 call s:SaveBufVars()
2107 keepj bd!
2108 if bufname("%") == "" && getline("$") == "" && line('$') == 1
2109 " needed when one sources a file in a nolbl setting window via ftp
2110 q!
2111 endif
2112 call s:RestoreBufVars()
2113 let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2114 let b:netrw_lastfile = choice
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002115
Luca Saccarolac363ca12024-12-19 20:16:18 +01002116 ".........................................
shane.xb.qianc673b802024-12-20 19:36:40 +01002117 " NetRead: (ftp + machine,id,passwd,filename) NetRead Method #3 {{{3
Luca Saccarolac363ca12024-12-19 20:16:18 +01002118 elseif b:netrw_method == 3 " read with ftp + machine, id, passwd, and fname
2119 " Construct execution string (four lines) which will be passed through filter
2120 " call Decho("read via ftp+mipf (method #3)",'~'.expand("<slnum>"))
2121 let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
2122 NetrwKeepj call s:SaveBufVars()|new|NetrwKeepj call s:RestoreBufVars()
2123 let filtbuf= bufnr("%")
2124 setl ff=unix
2125 if exists("g:netrw_port") && g:netrw_port != ""
2126 NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
shane.xb.qianc673b802024-12-20 19:36:40 +01002127 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
Luca Saccarolac363ca12024-12-19 20:16:18 +01002128 else
2129 NetrwKeepj put ='open '.g:netrw_machine
2130 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2131 endif
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002132
Luca Saccarolac363ca12024-12-19 20:16:18 +01002133 if exists("g:netrw_uid") && g:netrw_uid != ""
2134 if exists("g:netrw_ftp") && g:netrw_ftp == 1
2135 NetrwKeepj put =g:netrw_uid
2136 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2137 if exists("s:netrw_passwd")
2138 NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
2139 endif
shane.xb.qianc673b802024-12-20 19:36:40 +01002140 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
Luca Saccarolac363ca12024-12-19 20:16:18 +01002141 elseif exists("s:netrw_passwd")
2142 NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
2143 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2144 endif
2145 endif
2146
2147 if exists("g:netrw_ftpmode") && g:netrw_ftpmode != ""
2148 NetrwKeepj put =g:netrw_ftpmode
2149 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2150 endif
2151 if exists("g:netrw_ftpextracmd")
2152 NetrwKeepj put =g:netrw_ftpextracmd
2153 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2154 endif
2155 NetrwKeepj put ='get \"'.netrw_fname.'\" '.tmpfile
2156 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2157
2158 " perform ftp:
2159 " -i : turns off interactive prompting from ftp
2160 " -n unix : DON'T use <.netrc>, even though it exists
2161 " -n win32: quit being obnoxious about password
2162 NetrwKeepj norm! 1G"_dd
2163 call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
2164 " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2165 if getline(1) !~ "^$"
2166 " call Decho("error<".getline(1).">",'~'.expand("<slnum>"))
2167 if !exists("g:netrw_quiet")
2168 call netrw#ErrorMsg(s:ERROR,getline(1),5)
2169 endif
2170 endif
2171 call s:SaveBufVars()|keepj bd!|call s:RestoreBufVars()
2172 let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2173 let b:netrw_lastfile = choice
2174
2175 ".........................................
shane.xb.qianc673b802024-12-20 19:36:40 +01002176 " NetRead: (scp) NetRead Method #4 {{{3
Luca Saccarolac363ca12024-12-19 20:16:18 +01002177 elseif b:netrw_method == 4 " read with scp
2178 " call Decho("read via scp (method #4)",'~'.expand("<slnum>"))
2179 if exists("g:netrw_port") && g:netrw_port != ""
2180 let useport= " ".g:netrw_scpport." ".g:netrw_port
2181 else
2182 let useport= ""
2183 endif
2184 " 'C' in 'C:\path\to\file' is handled as hostname on windows.
2185 " This is workaround to avoid mis-handle windows local-path:
2186 if g:netrw_scp_cmd =~ '^scp' && has("win32")
2187 let tmpfile_get = substitute(tr(tmpfile, '\', '/'), '^\(\a\):[/\\]\(.*\)$', '/\1/\2', '')
2188 else
2189 let tmpfile_get = tmpfile
2190 endif
2191 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))
2192 let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2193 let b:netrw_lastfile = choice
2194
2195 ".........................................
shane.xb.qianc673b802024-12-20 19:36:40 +01002196 " NetRead: (http) NetRead Method #5 (wget) {{{3
Luca Saccarolac363ca12024-12-19 20:16:18 +01002197 elseif b:netrw_method == 5
2198 " call Decho("read via http (method #5)",'~'.expand("<slnum>"))
2199 if g:netrw_http_cmd == ""
2200 if !exists("g:netrw_quiet")
2201 call netrw#ErrorMsg(s:ERROR,"neither the wget nor the fetch command is available",6)
2202 endif
2203 " call Dret("netrw#NetRead :4 getcwd<".getcwd().">")
2204 return
2205 endif
2206
2207 if match(b:netrw_fname,"#") == -1 || exists("g:netrw_http_xcmd")
2208 " using g:netrw_http_cmd (usually elinks, links, curl, wget, or fetch)
2209 " call Decho('using '.g:netrw_http_cmd.' (# not in b:netrw_fname<'.b:netrw_fname.">)",'~'.expand("<slnum>"))
2210 if exists("g:netrw_http_xcmd")
2211 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))
2212 else
2213 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))
2214 endif
2215 let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2216
2217 else
2218 " wget/curl/fetch plus a jump to an in-page marker (ie. http://abc/def.html#aMarker)
2219 " call Decho("wget/curl plus jump (# in b:netrw_fname<".b:netrw_fname.">)",'~'.expand("<slnum>"))
2220 let netrw_html= substitute(b:netrw_fname,"#.*$","","")
2221 let netrw_tag = substitute(b:netrw_fname,"^.*#","","")
2222 " call Decho("netrw_html<".netrw_html.">",'~'.expand("<slnum>"))
2223 " call Decho("netrw_tag <".netrw_tag.">",'~'.expand("<slnum>"))
2224 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))
2225 let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2226 " call Decho('<\s*a\s*name=\s*"'.netrw_tag.'"/','~'.expand("<slnum>"))
2227 exe 'NetrwKeepj norm! 1G/<\s*a\s*name=\s*"'.netrw_tag.'"/'."\<CR>"
2228 endif
2229 let b:netrw_lastfile = choice
2230 " call Decho("setl ro",'~'.expand("<slnum>"))
2231 setl ro nomod
2232
2233 ".........................................
shane.xb.qianc673b802024-12-20 19:36:40 +01002234 " NetRead: (dav) NetRead Method #6 {{{3
Luca Saccarolac363ca12024-12-19 20:16:18 +01002235 elseif b:netrw_method == 6
2236 " call Decho("read via cadaver (method #6)",'~'.expand("<slnum>"))
2237
2238 if !executable(g:netrw_dav_cmd)
2239 call netrw#ErrorMsg(s:ERROR,g:netrw_dav_cmd." is not executable",73)
2240 " call Dret("netrw#NetRead : ".g:netrw_dav_cmd." not executable")
2241 return
2242 endif
2243 if g:netrw_dav_cmd =~ "curl"
2244 call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_dav_cmd." ".s:ShellEscape("dav://".g:netrw_machine.b:netrw_fname,1)." ".s:ShellEscape(tmpfile,1))
2245 else
2246 " Construct execution string (four lines) which will be passed through filter
2247 let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
2248 new
2249 setl ff=unix
2250 if exists("g:netrw_port") && g:netrw_port != ""
2251 NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2252 else
2253 NetrwKeepj put ='open '.g:netrw_machine
2254 endif
2255 if exists("g:netrw_uid") && exists("s:netrw_passwd") && g:netrw_uid != ""
2256 NetrwKeepj put ='user '.g:netrw_uid.' '.s:netrw_passwd
2257 endif
2258 NetrwKeepj put ='get '.netrw_fname.' '.tmpfile
2259 NetrwKeepj put ='quit'
2260
2261 " perform cadaver operation:
2262 NetrwKeepj norm! 1G"_dd
2263 call s:NetrwExe(s:netrw_silentxfer."%!".g:netrw_dav_cmd)
2264 keepj bd!
2265 endif
2266 let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2267 let b:netrw_lastfile = choice
2268
2269 ".........................................
shane.xb.qianc673b802024-12-20 19:36:40 +01002270 " NetRead: (rsync) NetRead Method #7 {{{3
Luca Saccarolac363ca12024-12-19 20:16:18 +01002271 elseif b:netrw_method == 7
2272 " call Decho("read via rsync (method #7)",'~'.expand("<slnum>"))
2273 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))
2274 let result = s:NetrwGetFile(readcmd,tmpfile, b:netrw_method)
2275 let b:netrw_lastfile = choice
2276
2277 ".........................................
shane.xb.qianc673b802024-12-20 19:36:40 +01002278 " NetRead: (fetch) NetRead Method #8 {{{3
2279 " fetch://[user@]host[:http]/path
Luca Saccarolac363ca12024-12-19 20:16:18 +01002280 elseif b:netrw_method == 8
2281 " call Decho("read via fetch (method #8)",'~'.expand("<slnum>"))
2282 if g:netrw_fetch_cmd == ""
2283 if !exists("g:netrw_quiet")
2284 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"fetch command not available",7)
2285 endif
2286 " call Dret("NetRead")
2287 return
2288 endif
2289 if exists("g:netrw_option") && g:netrw_option =~ ":https\="
2290 let netrw_option= "http"
2291 else
2292 let netrw_option= "ftp"
2293 endif
2294 " call Decho("read via fetch for ".netrw_option,'~'.expand("<slnum>"))
2295
2296 if exists("g:netrw_uid") && g:netrw_uid != "" && exists("s:netrw_passwd") && s:netrw_passwd != ""
2297 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))
2298 else
2299 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))
2300 endif
2301
2302 let result = s:NetrwGetFile(readcmd,tmpfile, b:netrw_method)
2303 let b:netrw_lastfile = choice
2304 " call Decho("setl ro",'~'.expand("<slnum>"))
2305 setl ro nomod
2306
2307 ".........................................
shane.xb.qianc673b802024-12-20 19:36:40 +01002308 " NetRead: (sftp) NetRead Method #9 {{{3
Luca Saccarolac363ca12024-12-19 20:16:18 +01002309 elseif b:netrw_method == 9
2310 " call Decho("read via sftp (method #9)",'~'.expand("<slnum>"))
2311 call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_sftp_cmd." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1)." ".tmpfile)
2312 let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2313 let b:netrw_lastfile = choice
2314
2315 ".........................................
shane.xb.qianc673b802024-12-20 19:36:40 +01002316 " NetRead: (file) NetRead Method #10 {{{3
Luca Saccarolac363ca12024-12-19 20:16:18 +01002317 elseif b:netrw_method == 10 && exists("g:netrw_file_cmd")
2318 " " call Decho("read via ".b:netrw_file_cmd." (method #10)",'~'.expand("<slnum>"))
2319 call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_file_cmd." ".s:ShellEscape(b:netrw_fname,1)." ".tmpfile)
2320 let result = s:NetrwGetFile(readcmd, tmpfile, b:netrw_method)
2321 let b:netrw_lastfile = choice
2322
2323 ".........................................
shane.xb.qianc673b802024-12-20 19:36:40 +01002324 " NetRead: Complain {{{3
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002325 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01002326 call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",8)
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002327 endif
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002328 endwhile
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002329
Bram Moolenaar5c736222010-01-06 20:54:52 +01002330 " NetRead: cleanup {{{3
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002331 if exists("b:netrw_method")
Luca Saccarolac363ca12024-12-19 20:16:18 +01002332 " call Decho("cleanup b:netrw_method and b:netrw_fname",'~'.expand("<slnum>"))
2333 unlet b:netrw_method
2334 unlet b:netrw_fname
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002335 endif
Bram Moolenaar5ac3b1a2010-07-27 22:50:36 +02002336 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 +01002337 " call Decho("cleanup by deleting tmpfile<".tmpfile.">",'~'.expand("<slnum>"))
2338 NetrwKeepj call s:NetrwDelete(tmpfile)
Bram Moolenaar9964e462007-05-05 17:54:07 +00002339 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02002340 NetrwKeepj call s:NetrwOptionsRestore("w:")
Bram Moolenaar8299df92004-07-10 09:47:34 +00002341
Luca Saccarolac363ca12024-12-19 20:16:18 +01002342 " call Dret("netrw#NetRead :5 getcwd<".getcwd().">")
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002343endfun
2344
2345" ------------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +00002346" netrw#NetWrite: responsible for writing a file over the net {{{2
Bram Moolenaar5b8d8fd2005-08-16 23:01:50 +00002347fun! netrw#NetWrite(...) range
Luca Saccarolac363ca12024-12-19 20:16:18 +01002348 " call Dfunc("netrw#NetWrite(a:0=".a:0.") ".g:loaded_netrw)
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002349
Bram Moolenaar5c736222010-01-06 20:54:52 +01002350 " NetWrite: option handling {{{3
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002351 let mod= 0
Bram Moolenaar85850f32019-07-19 22:05:51 +02002352 call s:NetrwOptionsSave("w:")
2353 call s:NetrwOptionsSafe(0)
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002354
Bram Moolenaar5c736222010-01-06 20:54:52 +01002355 " NetWrite: Get Temporary Filename {{{3
Bram Moolenaar9964e462007-05-05 17:54:07 +00002356 let tmpfile= s:GetTempfile("")
2357 if tmpfile == ""
Luca Saccarolac363ca12024-12-19 20:16:18 +01002358 " call Dret("netrw#NetWrite : unable to get a tempfile!")
2359 return
Bram Moolenaar5b8d8fd2005-08-16 23:01:50 +00002360 endif
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002361
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002362 if a:0 == 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01002363 let ichoice = 0
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002364 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01002365 let ichoice = 1
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002366 endif
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002367
Bram Moolenaar9964e462007-05-05 17:54:07 +00002368 let curbufname= expand("%")
Luca Saccarolac363ca12024-12-19 20:16:18 +01002369 " call Decho("curbufname<".curbufname.">",'~'.expand("<slnum>"))
Bram Moolenaar1afcace2005-11-25 19:54:28 +00002370 if &binary
Luca Saccarolac363ca12024-12-19 20:16:18 +01002371 " For binary writes, always write entire file.
2372 " (line numbers don't really make sense for that).
2373 " Also supports the writing of tar and zip files.
2374 " call Decho("(write entire file) sil exe w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile),'~'.expand("<slnum>"))
2375 exe "sil NetrwKeepj w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile)
Bram Moolenaar9964e462007-05-05 17:54:07 +00002376 elseif g:netrw_cygwin
Luca Saccarolac363ca12024-12-19 20:16:18 +01002377 " write (selected portion of) file to temporary
2378 let cygtmpfile= substitute(tmpfile,g:netrw_cygdrive.'/\(.\)','\1:','')
2379 " call Decho("(write selected portion) sil exe ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(cygtmpfile),'~'.expand("<slnum>"))
2380 exe "sil NetrwKeepj ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(cygtmpfile)
Bram Moolenaar1afcace2005-11-25 19:54:28 +00002381 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01002382 " write (selected portion of) file to temporary
2383 " call Decho("(write selected portion) sil exe ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile),'~'.expand("<slnum>"))
2384 exe "sil NetrwKeepj ".a:firstline."," . a:lastline . "w! ".fnameescape(v:cmdarg)." ".fnameescape(tmpfile)
Bram Moolenaar1afcace2005-11-25 19:54:28 +00002385 endif
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002386
Bram Moolenaar9964e462007-05-05 17:54:07 +00002387 if curbufname == ""
Luca Saccarolac363ca12024-12-19 20:16:18 +01002388 " when the file is [No Name], and one attempts to Nwrite it, the buffer takes
2389 " on the temporary file's name. Deletion of the temporary file during
2390 " cleanup then causes an error message.
2391 0file!
Bram Moolenaar9964e462007-05-05 17:54:07 +00002392 endif
2393
Bram Moolenaar5c736222010-01-06 20:54:52 +01002394 " NetWrite: while choice loop: {{{3
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002395 while ichoice <= a:0
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002396
Luca Saccarolac363ca12024-12-19 20:16:18 +01002397 " Process arguments: {{{4
2398 " attempt to repeat with previous host-file-etc
2399 if exists("b:netrw_lastfile") && a:0 == 0
2400 " call Decho("using b:netrw_lastfile<" . b:netrw_lastfile . ">",'~'.expand("<slnum>"))
2401 let choice = b:netrw_lastfile
2402 let ichoice= ichoice + 1
2403 else
2404 exe "let choice= a:" . ichoice
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002405
Luca Saccarolac363ca12024-12-19 20:16:18 +01002406 " Reconstruct Choice when choice starts with '"'
2407 if match(choice,"?") == 0
2408 echomsg 'NetWrite Usage:"'
2409 echomsg ':Nwrite machine:path uses rcp'
2410 echomsg ':Nwrite "machine path" uses ftp with <.netrc>'
2411 echomsg ':Nwrite "machine id password path" uses ftp'
2412 echomsg ':Nwrite dav://[user@]machine/path uses cadaver'
2413 echomsg ':Nwrite fetch://[user@]machine/path uses fetch'
2414 echomsg ':Nwrite ftp://machine[#port]/path uses ftp (autodetects <.netrc>)'
2415 echomsg ':Nwrite rcp://machine/path uses rcp'
2416 echomsg ':Nwrite rsync://[user@]machine/path uses rsync'
2417 echomsg ':Nwrite scp://[user@]machine[[:#]port]/path uses scp'
2418 echomsg ':Nwrite sftp://[user@]machine/path uses sftp'
2419 sleep 4
2420 break
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002421
Luca Saccarolac363ca12024-12-19 20:16:18 +01002422 elseif match(choice,"^\"") != -1
2423 if match(choice,"\"$") != -1
2424 " case "..."
2425 let choice=strpart(choice,1,strlen(choice)-2)
2426 else
2427 " case "... ... ..."
2428 let choice = strpart(choice,1,strlen(choice)-1)
2429 let wholechoice = ""
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002430
Luca Saccarolac363ca12024-12-19 20:16:18 +01002431 while match(choice,"\"$") == -1
2432 let wholechoice= wholechoice . " " . choice
2433 let ichoice = ichoice + 1
2434 if choice > a:0
2435 if !exists("g:netrw_quiet")
2436 call netrw#ErrorMsg(s:ERROR,"Unbalanced string in filename '". wholechoice ."'",13)
2437 endif
2438 " call Dret("netrw#NetWrite")
2439 return
2440 endif
2441 let choice= a:{ichoice}
2442 endwhile
2443 let choice= strpart(wholechoice,1,strlen(wholechoice)-1) . " " . strpart(choice,0,strlen(choice)-1)
K.Takata71d0ba02024-01-10 03:21:05 +09002444 endif
Bram Moolenaar5b435d62012-04-05 17:33:26 +02002445 endif
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002446 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01002447 let ichoice= ichoice + 1
2448 " call Decho("choice<" . choice . "> ichoice=".ichoice,'~'.expand("<slnum>"))
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002449
Luca Saccarolac363ca12024-12-19 20:16:18 +01002450 " Determine method of write (ftp, rcp, etc) {{{4
2451 NetrwKeepj call s:NetrwMethod(choice)
2452 if !exists("b:netrw_method") || b:netrw_method < 0
2453 " call Dfunc("netrw#NetWrite : unsupported method")
2454 return
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002455 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +01002456
Luca Saccarolac363ca12024-12-19 20:16:18 +01002457 " =============
2458 " NetWrite: Perform Protocol-Based Write {{{3
2459 " ============================
2460 if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1
2461 echo "(netrw) Processing your write request..."
2462 " call Decho("Processing your write request...",'~'.expand("<slnum>"))
2463 endif
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002464
Luca Saccarolac363ca12024-12-19 20:16:18 +01002465 ".........................................
2466 " NetWrite: (rcp) NetWrite Method #1 {{{3
2467 if b:netrw_method == 1
2468 " call Decho("write via rcp (method #1)",'~'.expand("<slnum>"))
2469 if s:netrw_has_nt_rcp == 1
2470 if exists("g:netrw_uid") && ( g:netrw_uid != "" )
2471 let uid_machine = g:netrw_machine .'.'. g:netrw_uid
2472 else
2473 let uid_machine = g:netrw_machine .'.'. $USERNAME
2474 endif
2475 else
2476 if exists("g:netrw_uid") && ( g:netrw_uid != "" )
2477 let uid_machine = g:netrw_uid .'@'. g:netrw_machine
2478 else
2479 let uid_machine = g:netrw_machine
2480 endif
2481 endif
2482 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))
2483 let b:netrw_lastfile = choice
2484
2485 ".........................................
shane.xb.qianc673b802024-12-20 19:36:40 +01002486 " NetWrite: (ftp + <.netrc>) NetWrite Method #2 {{{3
Luca Saccarolac363ca12024-12-19 20:16:18 +01002487 elseif b:netrw_method == 2
2488 " call Decho("write via ftp+.netrc (method #2)",'~'.expand("<slnum>"))
2489 let netrw_fname = b:netrw_fname
2490
2491 " formerly just a "new...bd!", that changed the window sizes when equalalways. Using enew workaround instead
2492 let bhkeep = &l:bh
2493 let curbuf = bufnr("%")
2494 setl bh=hide
2495 keepj keepalt enew
2496
2497 " call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
2498 setl ff=unix
2499 NetrwKeepj put =g:netrw_ftpmode
2500 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
2501 if exists("g:netrw_ftpextracmd")
2502 NetrwKeepj put =g:netrw_ftpextracmd
2503 " call Decho("filter input: ".getline("$"),'~'.expand("<slnum>"))
2504 endif
2505 NetrwKeepj call setline(line("$")+1,'put "'.tmpfile.'" "'.netrw_fname.'"')
2506 " call Decho("filter input: ".getline("$"),'~'.expand("<slnum>"))
2507 if exists("g:netrw_port") && g:netrw_port != ""
2508 call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
2509 else
2510 " call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
2511 call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
2512 endif
2513 " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2514 if getline(1) !~ "^$"
2515 if !exists("g:netrw_quiet")
2516 NetrwKeepj call netrw#ErrorMsg(s:ERROR,getline(1),14)
2517 endif
2518 let mod=1
2519 endif
2520
2521 " remove enew buffer (quietly)
2522 let filtbuf= bufnr("%")
2523 exe curbuf."b!"
2524 let &l:bh = bhkeep
2525 exe filtbuf."bw!"
2526
2527 let b:netrw_lastfile = choice
2528
2529 ".........................................
shane.xb.qianc673b802024-12-20 19:36:40 +01002530 " NetWrite: (ftp + machine, id, passwd, filename) NetWrite Method #3 {{{3
Luca Saccarolac363ca12024-12-19 20:16:18 +01002531 elseif b:netrw_method == 3
2532 " Construct execution string (three or more lines) which will be passed through filter
2533 " call Decho("read via ftp+mipf (method #3)",'~'.expand("<slnum>"))
2534 let netrw_fname = b:netrw_fname
2535 let bhkeep = &l:bh
2536
2537 " formerly just a "new...bd!", that changed the window sizes when equalalways. Using enew workaround instead
2538 let curbuf = bufnr("%")
2539 setl bh=hide
2540 keepj keepalt enew
2541 setl ff=unix
2542
2543 if exists("g:netrw_port") && g:netrw_port != ""
2544 NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
shane.xb.qianc673b802024-12-20 19:36:40 +01002545 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
Luca Saccarolac363ca12024-12-19 20:16:18 +01002546 else
2547 NetrwKeepj put ='open '.g:netrw_machine
2548 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2549 endif
2550 if exists("g:netrw_uid") && g:netrw_uid != ""
2551 if exists("g:netrw_ftp") && g:netrw_ftp == 1
2552 NetrwKeepj put =g:netrw_uid
2553 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2554 if exists("s:netrw_passwd") && s:netrw_passwd != ""
2555 NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
2556 endif
shane.xb.qianc673b802024-12-20 19:36:40 +01002557 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
Luca Saccarolac363ca12024-12-19 20:16:18 +01002558 elseif exists("s:netrw_passwd") && s:netrw_passwd != ""
2559 NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
2560 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2561 endif
2562 endif
2563 NetrwKeepj put =g:netrw_ftpmode
2564 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
2565 if exists("g:netrw_ftpextracmd")
2566 NetrwKeepj put =g:netrw_ftpextracmd
2567 " call Decho("filter input: ".getline("$"),'~'.expand("<slnum>"))
2568 endif
2569 NetrwKeepj put ='put \"'.tmpfile.'\" \"'.netrw_fname.'\"'
2570 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2571 " save choice/id/password for future use
2572 let b:netrw_lastfile = choice
2573
2574 " perform ftp:
2575 " -i : turns off interactive prompting from ftp
2576 " -n unix : DON'T use <.netrc>, even though it exists
2577 " -n win32: quit being obnoxious about password
2578 NetrwKeepj norm! 1G"_dd
2579 call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
2580 " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
2581 if getline(1) !~ "^$"
2582 if !exists("g:netrw_quiet")
2583 call netrw#ErrorMsg(s:ERROR,getline(1),15)
2584 endif
2585 let mod=1
2586 endif
2587
2588 " remove enew buffer (quietly)
2589 let filtbuf= bufnr("%")
2590 exe curbuf."b!"
2591 let &l:bh= bhkeep
2592 exe filtbuf."bw!"
2593
2594 ".........................................
shane.xb.qianc673b802024-12-20 19:36:40 +01002595 " NetWrite: (scp) NetWrite Method #4 {{{3
Luca Saccarolac363ca12024-12-19 20:16:18 +01002596 elseif b:netrw_method == 4
2597 " call Decho("write via scp (method #4)",'~'.expand("<slnum>"))
2598 if exists("g:netrw_port") && g:netrw_port != ""
2599 let useport= " ".g:netrw_scpport." ".fnameescape(g:netrw_port)
2600 else
2601 let useport= ""
2602 endif
2603 call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.useport." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(g:netrw_machine.":".b:netrw_fname,1))
2604 let b:netrw_lastfile = choice
2605
2606 ".........................................
shane.xb.qianc673b802024-12-20 19:36:40 +01002607 " NetWrite: (http) NetWrite Method #5 {{{3
Luca Saccarolac363ca12024-12-19 20:16:18 +01002608 elseif b:netrw_method == 5
2609 " call Decho("write via http (method #5)",'~'.expand("<slnum>"))
2610 let curl= substitute(g:netrw_http_put_cmd,'\s\+.*$',"","")
2611 if executable(curl)
2612 let url= g:netrw_choice
2613 call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_http_put_cmd." ".s:ShellEscape(tmpfile,1)." ".s:ShellEscape(url,1) )
2614 elseif !exists("g:netrw_quiet")
2615 call netrw#ErrorMsg(s:ERROR,"can't write to http using <".g:netrw_http_put_cmd.">",16)
2616 endif
2617
2618 ".........................................
shane.xb.qianc673b802024-12-20 19:36:40 +01002619 " NetWrite: (dav) NetWrite Method #6 (cadaver) {{{3
Luca Saccarolac363ca12024-12-19 20:16:18 +01002620 elseif b:netrw_method == 6
2621 " call Decho("write via cadaver (method #6)",'~'.expand("<slnum>"))
2622
2623 " Construct execution string (four lines) which will be passed through filter
2624 let netrw_fname = escape(b:netrw_fname,g:netrw_fname_escape)
2625 let bhkeep = &l:bh
2626
2627 " formerly just a "new...bd!", that changed the window sizes when equalalways. Using enew workaround instead
2628 let curbuf = bufnr("%")
2629 setl bh=hide
2630 keepj keepalt enew
2631
2632 setl ff=unix
2633 if exists("g:netrw_port") && g:netrw_port != ""
2634 NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
2635 else
2636 NetrwKeepj put ='open '.g:netrw_machine
2637 endif
2638 if exists("g:netrw_uid") && exists("s:netrw_passwd") && g:netrw_uid != ""
2639 NetrwKeepj put ='user '.g:netrw_uid.' '.s:netrw_passwd
2640 endif
2641 NetrwKeepj put ='put '.tmpfile.' '.netrw_fname
2642
2643 " perform cadaver operation:
2644 NetrwKeepj norm! 1G"_dd
2645 call s:NetrwExe(s:netrw_silentxfer."%!".g:netrw_dav_cmd)
2646
2647 " remove enew buffer (quietly)
2648 let filtbuf= bufnr("%")
2649 exe curbuf."b!"
2650 let &l:bh = bhkeep
2651 exe filtbuf."bw!"
2652
2653 let b:netrw_lastfile = choice
2654
2655 ".........................................
shane.xb.qianc673b802024-12-20 19:36:40 +01002656 " NetWrite: (rsync) NetWrite Method #7 {{{3
Luca Saccarolac363ca12024-12-19 20:16:18 +01002657 elseif b:netrw_method == 7
2658 " call Decho("write via rsync (method #7)",'~'.expand("<slnum>"))
2659 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))
2660 let b:netrw_lastfile = choice
2661
2662 ".........................................
shane.xb.qianc673b802024-12-20 19:36:40 +01002663 " NetWrite: (sftp) NetWrite Method #9 {{{3
Luca Saccarolac363ca12024-12-19 20:16:18 +01002664 elseif b:netrw_method == 9
2665 " call Decho("write via sftp (method #9)",'~'.expand("<slnum>"))
2666 let netrw_fname= escape(b:netrw_fname,g:netrw_fname_escape)
2667 if exists("g:netrw_uid") && ( g:netrw_uid != "" )
2668 let uid_machine = g:netrw_uid .'@'. g:netrw_machine
2669 else
2670 let uid_machine = g:netrw_machine
2671 endif
2672
2673 " formerly just a "new...bd!", that changed the window sizes when equalalways. Using enew workaround instead
2674 let bhkeep = &l:bh
2675 let curbuf = bufnr("%")
2676 setl bh=hide
2677 keepj keepalt enew
2678
2679 setl ff=unix
2680 call setline(1,'put "'.escape(tmpfile,'\').'" '.netrw_fname)
2681 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
2682 let sftpcmd= substitute(g:netrw_sftp_cmd,"%TEMPFILE%",escape(tmpfile,'\'),"g")
2683 call s:NetrwExe(s:netrw_silentxfer."%!".sftpcmd.' '.s:ShellEscape(uid_machine,1))
2684 let filtbuf= bufnr("%")
2685 exe curbuf."b!"
2686 let &l:bh = bhkeep
2687 exe filtbuf."bw!"
2688 let b:netrw_lastfile = choice
2689
2690 ".........................................
shane.xb.qianc673b802024-12-20 19:36:40 +01002691 " NetWrite: Complain {{{3
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002692 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01002693 call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . choice . ">",17)
2694 let leavemod= 1
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002695 endif
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002696 endwhile
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002697
Bram Moolenaar5c736222010-01-06 20:54:52 +01002698 " NetWrite: Cleanup: {{{3
Luca Saccarolac363ca12024-12-19 20:16:18 +01002699 " call Decho("cleanup",'~'.expand("<slnum>"))
Bram Moolenaar9964e462007-05-05 17:54:07 +00002700 if s:FileReadable(tmpfile)
Luca Saccarolac363ca12024-12-19 20:16:18 +01002701 " call Decho("tmpfile<".tmpfile."> readable, will now delete it",'~'.expand("<slnum>"))
2702 call s:NetrwDelete(tmpfile)
Bram Moolenaar9964e462007-05-05 17:54:07 +00002703 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02002704 call s:NetrwOptionsRestore("w:")
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002705
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002706 if a:firstline == 1 && a:lastline == line("$")
Luca Saccarolac363ca12024-12-19 20:16:18 +01002707 " restore modifiability; usually equivalent to set nomod
2708 let &l:mod= mod
shane.xb.qianc673b802024-12-20 19:36:40 +01002709 " 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 +02002710 elseif !exists("leavemod")
Luca Saccarolac363ca12024-12-19 20:16:18 +01002711 " indicate that the buffer has not been modified since last written
2712 " call Decho("set nomod",'~'.expand("<slnum>"))
2713 setl nomod
2714 " 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 +00002715 endif
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002716
Luca Saccarolac363ca12024-12-19 20:16:18 +01002717 " call Dret("netrw#NetWrite")
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002718endfun
2719
2720" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +00002721" netrw#NetSource: source a remotely hosted vim script {{{2
Bram Moolenaar9964e462007-05-05 17:54:07 +00002722" uses NetRead to get a copy of the file into a temporarily file,
2723" then sources that file,
2724" then removes that file.
2725fun! netrw#NetSource(...)
Luca Saccarolac363ca12024-12-19 20:16:18 +01002726 " call Dfunc("netrw#NetSource() a:0=".a:0)
Bram Moolenaar9964e462007-05-05 17:54:07 +00002727 if a:0 > 0 && a:1 == '?'
Luca Saccarolac363ca12024-12-19 20:16:18 +01002728 " give help
2729 echomsg 'NetSource Usage:'
2730 echomsg ':Nsource dav://machine[:port]/path uses cadaver'
2731 echomsg ':Nsource fetch://machine/path uses fetch'
2732 echomsg ':Nsource ftp://[user@]machine[:port]/path uses ftp autodetects <.netrc>'
2733 echomsg ':Nsource http[s]://[user@]machine/path uses http wget'
2734 echomsg ':Nsource rcp://[user@]machine/path uses rcp'
2735 echomsg ':Nsource rsync://machine[:port]/path uses rsync'
2736 echomsg ':Nsource scp://[user@]machine[[:#]port]/path uses scp'
2737 echomsg ':Nsource sftp://[user@]machine[[:#]port]/path uses sftp'
2738 sleep 4
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002739 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01002740 let i= 1
2741 while i <= a:0
2742 call netrw#NetRead(3,a:{i})
2743 " call Decho("s:netread_tmpfile<".s:netrw_tmpfile.">",'~'.expand("<slnum>"))
2744 if s:FileReadable(s:netrw_tmpfile)
2745 " call Decho("exe so ".fnameescape(s:netrw_tmpfile),'~'.expand("<slnum>"))
2746 exe "so ".fnameescape(s:netrw_tmpfile)
2747 " call Decho("delete(".s:netrw_tmpfile.")",'~'.expand("<slnum>"))
2748 if delete(s:netrw_tmpfile)
2749 call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".s:netrw_tmpfile.">!",103)
2750 endif
2751 unlet s:netrw_tmpfile
2752 else
2753 call netrw#ErrorMsg(s:ERROR,"unable to source <".a:{i}.">!",48)
2754 endif
2755 let i= i + 1
2756 endwhile
Bram Moolenaar9964e462007-05-05 17:54:07 +00002757 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01002758 " call Dret("netrw#NetSource")
Bram Moolenaar9964e462007-05-05 17:54:07 +00002759endfun
2760
Bram Moolenaar8d043172014-01-23 14:24:41 +01002761" ---------------------------------------------------------------------
Bram Moolenaara6878372014-03-22 21:02:50 +01002762" netrw#SetTreetop: resets the tree top to the current directory/specified directory {{{2
2763" (implements the :Ntree command)
Bram Moolenaar85850f32019-07-19 22:05:51 +02002764fun! netrw#SetTreetop(iscmd,...)
Bram Moolenaara6878372014-03-22 21:02:50 +01002765
Bram Moolenaar85850f32019-07-19 22:05:51 +02002766 " iscmd==0: netrw#SetTreetop called using gn mapping
2767 " iscmd==1: netrw#SetTreetop called using :Ntree from the command line
Bram Moolenaar8d043172014-01-23 14:24:41 +01002768 " clear out the current tree
2769 if exists("w:netrw_treetop")
Luca Saccarolac363ca12024-12-19 20:16:18 +01002770 let inittreetop= w:netrw_treetop
2771 unlet w:netrw_treetop
Bram Moolenaar8d043172014-01-23 14:24:41 +01002772 endif
2773 if exists("w:netrw_treedict")
Luca Saccarolac363ca12024-12-19 20:16:18 +01002774 unlet w:netrw_treedict
Bram Moolenaar8d043172014-01-23 14:24:41 +01002775 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01002776
Bram Moolenaar85850f32019-07-19 22:05:51 +02002777 if (a:iscmd == 0 || a:1 == "") && exists("inittreetop")
Luca Saccarolac363ca12024-12-19 20:16:18 +01002778 let treedir = s:NetrwTreePath(inittreetop)
Bram Moolenaar8d043172014-01-23 14:24:41 +01002779 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01002780 if isdirectory(s:NetrwFile(a:1))
2781 let treedir = a:1
2782 let s:netrw_treetop = treedir
2783 elseif exists("b:netrw_curdir") && (isdirectory(s:NetrwFile(b:netrw_curdir."/".a:1)) || a:1 =~ '^\a\{3,}://')
2784 let treedir = b:netrw_curdir."/".a:1
2785 let s:netrw_treetop = treedir
2786 else
2787 " normally the cursor is left in the message window.
2788 " However, here this results in the directory being listed in the message window, which is not wanted.
2789 let netrwbuf= bufnr("%")
2790 call netrw#ErrorMsg(s:ERROR,"sorry, ".a:1." doesn't seem to be a directory!",95)
2791 exe bufwinnr(netrwbuf)."wincmd w"
2792 let treedir = "."
2793 let s:netrw_treetop = getcwd()
2794 endif
Bram Moolenaar8d043172014-01-23 14:24:41 +01002795 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02002796
2797 " determine if treedir is remote or local
Bram Moolenaara0f849e2015-10-30 14:37:44 +01002798 let islocal= expand("%") !~ '^\a\{3,}://'
Bram Moolenaar85850f32019-07-19 22:05:51 +02002799
2800 " browse the resulting directory
Bram Moolenaara6878372014-03-22 21:02:50 +01002801 if islocal
Luca Saccarolac363ca12024-12-19 20:16:18 +01002802 call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(islocal,treedir,0))
Bram Moolenaara6878372014-03-22 21:02:50 +01002803 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01002804 call s:NetrwBrowse(islocal,s:NetrwBrowseChgDir(islocal,treedir,0))
Bram Moolenaara6878372014-03-22 21:02:50 +01002805 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02002806
Bram Moolenaar8d043172014-01-23 14:24:41 +01002807endfun
2808
Bram Moolenaar9964e462007-05-05 17:54:07 +00002809" ===========================================
Bram Moolenaar446cb832008-06-24 21:56:24 +00002810" s:NetrwGetFile: Function to read temporary file "tfile" with command "readcmd". {{{2
Bram Moolenaar9964e462007-05-05 17:54:07 +00002811" readcmd == %r : replace buffer with newly read file
2812" == 0r : read file at top of buffer
2813" == r : read file after current line
2814" == t : leave file in temporary form (ie. don't read into buffer)
Bram Moolenaar446cb832008-06-24 21:56:24 +00002815fun! s:NetrwGetFile(readcmd, tfile, method)
Luca Saccarolac363ca12024-12-19 20:16:18 +01002816 " call Dfunc("NetrwGetFile(readcmd<".a:readcmd.">,tfile<".a:tfile."> method<".a:method.">)")
Bram Moolenaar9964e462007-05-05 17:54:07 +00002817
2818 " readcmd=='t': simply do nothing
2819 if a:readcmd == 't'
Luca Saccarolac363ca12024-12-19 20:16:18 +01002820 " call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2821 " call Dret("NetrwGetFile : skip read of tfile<".a:tfile.">")
2822 return
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002823 endif
Bram Moolenaar1afcace2005-11-25 19:54:28 +00002824
Bram Moolenaar9964e462007-05-05 17:54:07 +00002825 " get name of remote filename (ie. url and all)
2826 let rfile= bufname("%")
Luca Saccarolac363ca12024-12-19 20:16:18 +01002827 " call Decho("rfile<".rfile.">",'~'.expand("<slnum>"))
Bram Moolenaar578b49e2005-09-10 19:22:57 +00002828
Bram Moolenaar9964e462007-05-05 17:54:07 +00002829 if exists("*NetReadFixup")
Luca Saccarolac363ca12024-12-19 20:16:18 +01002830 " for the use of NetReadFixup (not otherwise used internally)
2831 let line2= line("$")
Bram Moolenaar578b49e2005-09-10 19:22:57 +00002832 endif
2833
Bram Moolenaar9964e462007-05-05 17:54:07 +00002834 if a:readcmd[0] == '%'
Luca Saccarolac363ca12024-12-19 20:16:18 +01002835 " get file into buffer
2836 " call Decho("get file into buffer",'~'.expand("<slnum>"))
Bram Moolenaar9964e462007-05-05 17:54:07 +00002837
Luca Saccarolac363ca12024-12-19 20:16:18 +01002838 " rename the current buffer to the temp file (ie. tfile)
2839 if g:netrw_cygwin
2840 let tfile= substitute(a:tfile,g:netrw_cygdrive.'/\(.\)','\1:','')
2841 else
2842 let tfile= a:tfile
2843 endif
2844 call s:NetrwBufRename(tfile)
Bram Moolenaar9964e462007-05-05 17:54:07 +00002845
Luca Saccarolac363ca12024-12-19 20:16:18 +01002846 " edit temporary file (ie. read the temporary file in)
2847 if rfile =~ '\.zip$'
2848 " call Decho("handling remote zip file with zip#Browse(tfile<".tfile.">)",'~'.expand("<slnum>"))
2849 call zip#Browse(tfile)
2850 elseif rfile =~ '\.tar$'
2851 " call Decho("handling remote tar file with tar#Browse(tfile<".tfile.">)",'~'.expand("<slnum>"))
2852 call tar#Browse(tfile)
2853 elseif rfile =~ '\.tar\.gz$'
2854 " call Decho("handling remote gzip-compressed tar file",'~'.expand("<slnum>"))
2855 call tar#Browse(tfile)
2856 elseif rfile =~ '\.tar\.bz2$'
2857 " call Decho("handling remote bz2-compressed tar file",'~'.expand("<slnum>"))
2858 call tar#Browse(tfile)
2859 elseif rfile =~ '\.tar\.xz$'
2860 " call Decho("handling remote xz-compressed tar file",'~'.expand("<slnum>"))
2861 call tar#Browse(tfile)
2862 elseif rfile =~ '\.txz$'
2863 " call Decho("handling remote xz-compressed tar file (.txz)",'~'.expand("<slnum>"))
2864 call tar#Browse(tfile)
2865 else
2866 " call Decho("edit temporary file",'~'.expand("<slnum>"))
2867 NetrwKeepj e!
2868 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +00002869
Luca Saccarolac363ca12024-12-19 20:16:18 +01002870 " rename buffer back to remote filename
2871 call s:NetrwBufRename(rfile)
Bram Moolenaar5b435d62012-04-05 17:33:26 +02002872
Luca Saccarolac363ca12024-12-19 20:16:18 +01002873 " Jan 19, 2022: COMBAK -- bram problem with https://github.com/vim/vim/pull/9554.diff filetype
2874 " Detect filetype of local version of remote file.
2875 " Note that isk must not include a "/" for scripts.vim
2876 " to process this detection correctly.
2877 " call Decho("detect filetype of local version of remote file<".rfile.">",'~'.expand("<slnum>"))
2878 " call Decho("..did_filetype()=".did_filetype())
2879 " setl ft=
2880 " call Decho("..initial filetype<".&ft."> for buf#".bufnr()."<".bufname().">")
2881 let iskkeep= &isk
2882 setl isk-=/
2883 filetype detect
2884 " call Decho("..local filetype<".&ft."> for buf#".bufnr()."<".bufname().">")
2885 let &l:isk= iskkeep
2886 " call Dredir("ls!","NetrwGetFile (renamed buffer back to remote filename<".rfile."> : expand(%)<".expand("%").">)")
2887 let line1 = 1
2888 let line2 = line("$")
Bram Moolenaar9964e462007-05-05 17:54:07 +00002889
Bram Moolenaar8d043172014-01-23 14:24:41 +01002890 elseif !&ma
Luca Saccarolac363ca12024-12-19 20:16:18 +01002891 " attempting to read a file after the current line in the file, but the buffer is not modifiable
2892 NetrwKeepj call netrw#ErrorMsg(s:WARNING,"attempt to read<".a:tfile."> into a non-modifiable buffer!",94)
2893 " call Dret("NetrwGetFile : attempt to read<".a:tfile."> into a non-modifiable buffer!")
2894 return
Bram Moolenaar8d043172014-01-23 14:24:41 +01002895
Bram Moolenaar9964e462007-05-05 17:54:07 +00002896 elseif s:FileReadable(a:tfile)
Luca Saccarolac363ca12024-12-19 20:16:18 +01002897 " read file after current line
2898 " call Decho("read file<".a:tfile."> after current line",'~'.expand("<slnum>"))
2899 let curline = line(".")
2900 let lastline= line("$")
2901 " call Decho("exe<".a:readcmd." ".fnameescape(v:cmdarg)." ".fnameescape(a:tfile)."> line#".curline,'~'.expand("<slnum>"))
2902 exe "NetrwKeepj ".a:readcmd." ".fnameescape(v:cmdarg)." ".fnameescape(a:tfile)
2903 let line1= curline + 1
2904 let line2= line("$") - lastline + 1
Bram Moolenaar9964e462007-05-05 17:54:07 +00002905
2906 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01002907 " not readable
2908 " call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2909 " call Decho("tfile<".a:tfile."> not readable",'~'.expand("<slnum>"))
2910 NetrwKeepj call netrw#ErrorMsg(s:WARNING,"file <".a:tfile."> not readable",9)
2911 " call Dret("NetrwGetFile : tfile<".a:tfile."> not readable")
2912 return
Bram Moolenaar9964e462007-05-05 17:54:07 +00002913 endif
2914
2915 " User-provided (ie. optional) fix-it-up command
2916 if exists("*NetReadFixup")
Luca Saccarolac363ca12024-12-19 20:16:18 +01002917 " call Decho("calling NetReadFixup(method<".a:method."> line1=".line1." line2=".line2.")",'~'.expand("<slnum>"))
2918 NetrwKeepj call NetReadFixup(a:method, line1, line2)
2919 " else " Decho
2920 " call Decho("NetReadFixup() not called, doesn't exist (line1=".line1." line2=".line2.")",'~'.expand("<slnum>"))
Bram Moolenaar9964e462007-05-05 17:54:07 +00002921 endif
2922
Bram Moolenaaradc21822011-04-01 18:03:16 +02002923 if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
Luca Saccarolac363ca12024-12-19 20:16:18 +01002924 " update the Buffers menu
2925 NetrwKeepj call s:UpdateBuffersMenu()
Bram Moolenaar9964e462007-05-05 17:54:07 +00002926 endif
2927
Luca Saccarolac363ca12024-12-19 20:16:18 +01002928 " 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 +00002929
Luca Saccarolac363ca12024-12-19 20:16:18 +01002930 " make sure file is being displayed
2931 " redraw!
Bram Moolenaar446cb832008-06-24 21:56:24 +00002932
Luca Saccarolac363ca12024-12-19 20:16:18 +01002933 " call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
2934 " call Dret("NetrwGetFile")
Bram Moolenaar578b49e2005-09-10 19:22:57 +00002935endfun
2936
Bram Moolenaar9964e462007-05-05 17:54:07 +00002937" ------------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +00002938" s:NetrwMethod: determine method of transfer {{{2
Bram Moolenaar5c736222010-01-06 20:54:52 +01002939" Input:
2940" choice = url [protocol:]//[userid@]hostname[:port]/[path-to-file]
2941" Output:
Bram Moolenaara0f849e2015-10-30 14:37:44 +01002942" b:netrw_method= 1: rcp
2943" 2: ftp + <.netrc>
Luca Saccarolac363ca12024-12-19 20:16:18 +01002944" 3: ftp + machine, id, password, and [path]filename
2945" 4: scp
2946" 5: http[s] (wget)
2947" 6: dav
2948" 7: rsync
2949" 8: fetch
2950" 9: sftp
2951" 10: file
Bram Moolenaar5c736222010-01-06 20:54:52 +01002952" g:netrw_machine= hostname
2953" b:netrw_fname = filename
2954" g:netrw_port = optional port number (for ftp)
2955" g:netrw_choice = copy of input url (choice)
2956fun! s:NetrwMethod(choice)
Luca Saccarolac363ca12024-12-19 20:16:18 +01002957 " call Dfunc("s:NetrwMethod(a:choice<".a:choice.">)")
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002958
Luca Saccarolac363ca12024-12-19 20:16:18 +01002959 " sanity check: choice should have at least three slashes in it
2960 if strlen(substitute(a:choice,'[^/]','','g')) < 3
Bram Moolenaar251e1912011-06-19 05:09:16 +02002961 call netrw#ErrorMsg(s:ERROR,"not a netrw-style url; netrw uses protocol://[user@]hostname[:port]/[path])",78)
2962 let b:netrw_method = -1
Luca Saccarolac363ca12024-12-19 20:16:18 +01002963 " call Dret("s:NetrwMethod : incorrect url format<".a:choice.">")
Bram Moolenaar251e1912011-06-19 05:09:16 +02002964 return
Luca Saccarolac363ca12024-12-19 20:16:18 +01002965 endif
Bram Moolenaar251e1912011-06-19 05:09:16 +02002966
Luca Saccarolac363ca12024-12-19 20:16:18 +01002967 " record current g:netrw_machine, if any
2968 " curmachine used if protocol == ftp and no .netrc
2969 if exists("g:netrw_machine")
Bram Moolenaar5c736222010-01-06 20:54:52 +01002970 let curmachine= g:netrw_machine
shane.xb.qianc673b802024-12-20 19:36:40 +01002971 " call Decho("curmachine<".curmachine.">",'~'.expand("<slnum>"))
Luca Saccarolac363ca12024-12-19 20:16:18 +01002972 else
Bram Moolenaar5c736222010-01-06 20:54:52 +01002973 let curmachine= "N O T A HOST"
Luca Saccarolac363ca12024-12-19 20:16:18 +01002974 endif
2975 if exists("g:netrw_port")
Bram Moolenaaradc21822011-04-01 18:03:16 +02002976 let netrw_port= g:netrw_port
Luca Saccarolac363ca12024-12-19 20:16:18 +01002977 endif
Bram Moolenaaradc21822011-04-01 18:03:16 +02002978
Luca Saccarolac363ca12024-12-19 20:16:18 +01002979 " insure that netrw_ftp_cmd starts off every method determination
2980 " with the current g:netrw_ftp_cmd
2981 let s:netrw_ftp_cmd= g:netrw_ftp_cmd
Bram Moolenaar5c736222010-01-06 20:54:52 +01002982
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002983 " initialization
2984 let b:netrw_method = 0
2985 let g:netrw_machine = ""
2986 let b:netrw_fname = ""
2987 let g:netrw_port = ""
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00002988 let g:netrw_choice = a:choice
2989
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002990 " Patterns:
Luca Saccarolac363ca12024-12-19 20:16:18 +01002991 " mipf : a:machine a:id password filename Use ftp
2992 " mf : a:machine filename Use ftp + <.netrc> or g:netrw_uid s:netrw_passwd
Bram Moolenaar446cb832008-06-24 21:56:24 +00002993 " ftpurm : ftp://[user@]host[[#:]port]/filename Use ftp + <.netrc> or g:netrw_uid s:netrw_passwd
Luca Saccarolac363ca12024-12-19 20:16:18 +01002994 " rcpurm : rcp://[user@]host/filename Use rcp
2995 " rcphf : [user@]host:filename Use rcp
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002996 " scpurm : scp://[user@]host[[#:]port]/filename Use scp
Luca Saccarolac363ca12024-12-19 20:16:18 +01002997 " httpurm : http[s]://[user@]host/filename Use wget
Bram Moolenaar5c736222010-01-06 20:54:52 +01002998 " davurm : dav[s]://host[:port]/path Use cadaver/curl
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002999 " rsyncurm : rsync://host[:port]/path Use rsync
3000 " fetchurm : fetch://[user@]host[:http]/filename Use fetch (defaults to ftp, override for http)
3001 " sftpurm : sftp://[user@]host/filename Use scp
Luca Saccarolac363ca12024-12-19 20:16:18 +01003002 " fileurm : file://[user@]host/filename Use elinks or links
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003003 let mipf = '^\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)\s\+\(\S\+\)$'
3004 let mf = '^\(\S\+\)\s\+\(\S\+\)$'
Bram Moolenaar15146672011-10-20 22:22:38 +02003005 let ftpurm = '^ftp://\(\([^/]*\)@\)\=\([^/#:]\{-}\)\([#:]\d\+\)\=/\(.*\)$'
3006 let rcpurm = '^rcp://\%(\([^/]*\)@\)\=\([^/]\{-}\)/\(.*\)$'
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003007 let rcphf = '^\(\(\h\w*\)@\)\=\(\h\w*\):\([^@]\+\)$'
Bram Moolenaar1afcace2005-11-25 19:54:28 +00003008 let scpurm = '^scp://\([^/#:]\+\)\%([#:]\(\d\+\)\)\=/\(.*\)$'
Bram Moolenaar15146672011-10-20 22:22:38 +02003009 let httpurm = '^https\=://\([^/]\{-}\)\(/.*\)\=$'
Bram Moolenaar446cb832008-06-24 21:56:24 +00003010 let davurm = '^davs\=://\([^/]\+\)/\(.*/\)\([-_.~[:alnum:]]\+\)$'
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003011 let rsyncurm = '^rsync://\([^/]\{-}\)/\(.*\)\=$'
Bram Moolenaar15146672011-10-20 22:22:38 +02003012 let fetchurm = '^fetch://\(\([^/]*\)@\)\=\([^/#:]\{-}\)\(:http\)\=/\(.*\)$'
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003013 let sftpurm = '^sftp://\([^/]\{-}\)/\(.*\)\=$'
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003014 let fileurm = '^file\=://\(.*\)$'
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00003015
Luca Saccarolac363ca12024-12-19 20:16:18 +01003016 " call Decho("determine method:",'~'.expand("<slnum>"))
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003017 " Determine Method
Bram Moolenaaradc21822011-04-01 18:03:16 +02003018 " Method#1: rcp://user@hostname/...path-to-file {{{3
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003019 if match(a:choice,rcpurm) == 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01003020 " call Decho("rcp://...",'~'.expand("<slnum>"))
3021 let b:netrw_method = 1
3022 let userid = substitute(a:choice,rcpurm,'\1',"")
3023 let g:netrw_machine = substitute(a:choice,rcpurm,'\2',"")
3024 let b:netrw_fname = substitute(a:choice,rcpurm,'\3',"")
3025 if userid != ""
3026 let g:netrw_uid= userid
3027 endif
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00003028
shane.xb.qianc673b802024-12-20 19:36:40 +01003029 " Method#4: scp://user@hostname/...path-to-file {{{3
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003030 elseif match(a:choice,scpurm) == 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01003031 " call Decho("scp://...",'~'.expand("<slnum>"))
3032 let b:netrw_method = 4
3033 let g:netrw_machine = substitute(a:choice,scpurm,'\1',"")
3034 let g:netrw_port = substitute(a:choice,scpurm,'\2',"")
3035 let b:netrw_fname = substitute(a:choice,scpurm,'\3',"")
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00003036
shane.xb.qianc673b802024-12-20 19:36:40 +01003037 " Method#5: http[s]://user@hostname/...path-to-file {{{3
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003038 elseif match(a:choice,httpurm) == 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01003039 " call Decho("http[s]://...",'~'.expand("<slnum>"))
3040 let b:netrw_method = 5
3041 let g:netrw_machine= substitute(a:choice,httpurm,'\1',"")
3042 let b:netrw_fname = substitute(a:choice,httpurm,'\2',"")
3043 let b:netrw_http = (a:choice =~ '^https:')? "https" : "http"
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00003044
shane.xb.qianc673b802024-12-20 19:36:40 +01003045 " Method#6: dav://hostname[:port]/..path-to-file.. {{{3
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003046 elseif match(a:choice,davurm) == 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01003047 " call Decho("dav://...",'~'.expand("<slnum>"))
3048 let b:netrw_method= 6
3049 if a:choice =~ 'davs:'
3050 let g:netrw_machine= 'https://'.substitute(a:choice,davurm,'\1/\2',"")
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003051 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01003052 let g:netrw_machine= 'http://'.substitute(a:choice,davurm,'\1/\2',"")
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003053 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01003054 let b:netrw_fname = substitute(a:choice,davurm,'\3',"")
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00003055
shane.xb.qianc673b802024-12-20 19:36:40 +01003056 " Method#7: rsync://user@hostname/...path-to-file {{{3
Luca Saccarolac363ca12024-12-19 20:16:18 +01003057 elseif match(a:choice,rsyncurm) == 0
3058 " call Decho("rsync://...",'~'.expand("<slnum>"))
3059 let b:netrw_method = 7
3060 let g:netrw_machine= substitute(a:choice,rsyncurm,'\1',"")
3061 let b:netrw_fname = substitute(a:choice,rsyncurm,'\2',"")
3062
shane.xb.qianc673b802024-12-20 19:36:40 +01003063 " Methods 2,3: ftp://[user@]hostname[[:#]port]/...path-to-file {{{3
Luca Saccarolac363ca12024-12-19 20:16:18 +01003064 elseif match(a:choice,ftpurm) == 0
3065 " call Decho("ftp://...",'~'.expand("<slnum>"))
3066 let userid = substitute(a:choice,ftpurm,'\2',"")
3067 let g:netrw_machine= substitute(a:choice,ftpurm,'\3',"")
3068 let g:netrw_port = substitute(a:choice,ftpurm,'\4',"")
3069 let b:netrw_fname = substitute(a:choice,ftpurm,'\5',"")
3070 " call Decho("g:netrw_machine<".g:netrw_machine.">",'~'.expand("<slnum>"))
3071 if userid != ""
3072 let g:netrw_uid= userid
3073 endif
3074
3075 if curmachine != g:netrw_machine
3076 if exists("s:netrw_hup[".g:netrw_machine."]")
3077 call NetUserPass("ftp:".g:netrw_machine)
3078 elseif exists("s:netrw_passwd")
3079 " if there's a change in hostname, require password re-entry
3080 unlet s:netrw_passwd
3081 endif
3082 if exists("netrw_port")
3083 unlet netrw_port
3084 endif
3085 endif
3086
3087 if exists("g:netrw_uid") && exists("s:netrw_passwd")
3088 let b:netrw_method = 3
3089 else
3090 let host= substitute(g:netrw_machine,'\..*$','','')
3091 if exists("s:netrw_hup[host]")
3092 call NetUserPass("ftp:".host)
3093
3094 elseif has("win32") && s:netrw_ftp_cmd =~# '-[sS]:'
3095 " call Decho("has -s: : s:netrw_ftp_cmd<".s:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
3096 " call Decho(" g:netrw_ftp_cmd<".g:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
3097 if g:netrw_ftp_cmd =~# '-[sS]:\S*MACHINE\>'
3098 let s:netrw_ftp_cmd= substitute(g:netrw_ftp_cmd,'\<MACHINE\>',g:netrw_machine,'')
3099 " call Decho("s:netrw_ftp_cmd<".s:netrw_ftp_cmd.">",'~'.expand("<slnum>"))
3100 endif
3101 let b:netrw_method= 2
3102 elseif s:FileReadable(expand("$HOME/.netrc")) && !g:netrw_ignorenetrc
3103 " call Decho("using <".expand("$HOME/.netrc")."> (readable)",'~'.expand("<slnum>"))
3104 let b:netrw_method= 2
3105 else
3106 if !exists("g:netrw_uid") || g:netrw_uid == ""
3107 call NetUserPass()
3108 elseif !exists("s:netrw_passwd") || s:netrw_passwd == ""
3109 call NetUserPass(g:netrw_uid)
3110 " else just use current g:netrw_uid and s:netrw_passwd
3111 endif
3112 let b:netrw_method= 3
3113 endif
3114 endif
3115
shane.xb.qianc673b802024-12-20 19:36:40 +01003116 " Method#8: fetch {{{3
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003117 elseif match(a:choice,fetchurm) == 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01003118 " call Decho("fetch://...",'~'.expand("<slnum>"))
3119 let b:netrw_method = 8
3120 let g:netrw_userid = substitute(a:choice,fetchurm,'\2',"")
3121 let g:netrw_machine= substitute(a:choice,fetchurm,'\3',"")
3122 let b:netrw_option = substitute(a:choice,fetchurm,'\4',"")
3123 let b:netrw_fname = substitute(a:choice,fetchurm,'\5',"")
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00003124
shane.xb.qianc673b802024-12-20 19:36:40 +01003125 " Method#3: Issue an ftp : "machine id password [path/]filename" {{{3
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003126 elseif match(a:choice,mipf) == 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01003127 " call Decho("(ftp) host id pass file",'~'.expand("<slnum>"))
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003128 let b:netrw_method = 3
Luca Saccarolac363ca12024-12-19 20:16:18 +01003129 let g:netrw_machine = substitute(a:choice,mipf,'\1',"")
3130 let g:netrw_uid = substitute(a:choice,mipf,'\2',"")
3131 let s:netrw_passwd = substitute(a:choice,mipf,'\3',"")
3132 let b:netrw_fname = substitute(a:choice,mipf,'\4',"")
3133 call NetUserPass(g:netrw_machine,g:netrw_uid,s:netrw_passwd)
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00003134
shane.xb.qianc673b802024-12-20 19:36:40 +01003135 " Method#3: Issue an ftp: "hostname [path/]filename" {{{3
Luca Saccarolac363ca12024-12-19 20:16:18 +01003136 elseif match(a:choice,mf) == 0
3137 " call Decho("(ftp) host file",'~'.expand("<slnum>"))
3138 if exists("g:netrw_uid") && exists("s:netrw_passwd")
3139 let b:netrw_method = 3
3140 let g:netrw_machine = substitute(a:choice,mf,'\1',"")
3141 let b:netrw_fname = substitute(a:choice,mf,'\2',"")
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00003142
Luca Saccarolac363ca12024-12-19 20:16:18 +01003143 elseif s:FileReadable(expand("$HOME/.netrc"))
3144 let b:netrw_method = 2
3145 let g:netrw_machine = substitute(a:choice,mf,'\1',"")
3146 let b:netrw_fname = substitute(a:choice,mf,'\2',"")
3147 endif
3148
shane.xb.qianc673b802024-12-20 19:36:40 +01003149 " Method#9: sftp://user@hostname/...path-to-file {{{3
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003150 elseif match(a:choice,sftpurm) == 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01003151 " call Decho("sftp://...",'~'.expand("<slnum>"))
3152 let b:netrw_method = 9
3153 let g:netrw_machine= substitute(a:choice,sftpurm,'\1',"")
3154 let b:netrw_fname = substitute(a:choice,sftpurm,'\2',"")
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00003155
shane.xb.qianc673b802024-12-20 19:36:40 +01003156 " Method#1: Issue an rcp: hostname:filename" (this one should be last) {{{3
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003157 elseif match(a:choice,rcphf) == 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01003158 " call Decho("(rcp) [user@]host:file) rcphf<".rcphf.">",'~'.expand("<slnum>"))
3159 let b:netrw_method = 1
3160 let userid = substitute(a:choice,rcphf,'\2',"")
3161 let g:netrw_machine = substitute(a:choice,rcphf,'\3',"")
3162 let b:netrw_fname = substitute(a:choice,rcphf,'\4',"")
3163 " call Decho('\1<'.substitute(a:choice,rcphf,'\1',"").">",'~'.expand("<slnum>"))
3164 " call Decho('\2<'.substitute(a:choice,rcphf,'\2',"").">",'~'.expand("<slnum>"))
3165 " call Decho('\3<'.substitute(a:choice,rcphf,'\3',"").">",'~'.expand("<slnum>"))
3166 " call Decho('\4<'.substitute(a:choice,rcphf,'\4',"").">",'~'.expand("<slnum>"))
3167 if userid != ""
3168 let g:netrw_uid= userid
3169 endif
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00003170
shane.xb.qianc673b802024-12-20 19:36:40 +01003171 " Method#10: file://user@hostname/...path-to-file {{{3
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003172 elseif match(a:choice,fileurm) == 0 && exists("g:netrw_file_cmd")
Luca Saccarolac363ca12024-12-19 20:16:18 +01003173 " call Decho("http[s]://...",'~'.expand("<slnum>"))
3174 let b:netrw_method = 10
3175 let b:netrw_fname = substitute(a:choice,fileurm,'\1',"")
shane.xb.qianc673b802024-12-20 19:36:40 +01003176 " call Decho('\1<'.substitute(a:choice,fileurm,'\1',"").">",'~'.expand("<slnum>"))
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003177
shane.xb.qianc673b802024-12-20 19:36:40 +01003178 " Cannot Determine Method {{{3
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00003179 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01003180 if !exists("g:netrw_quiet")
3181 call netrw#ErrorMsg(s:WARNING,"cannot determine method (format: protocol://[user@]hostname[:port]/[path])",45)
3182 endif
3183 let b:netrw_method = -1
Bram Moolenaar071d4272004-06-13 20:20:40 +00003184 endif
Bram Moolenaaradc21822011-04-01 18:03:16 +02003185 "}}}3
Bram Moolenaar81695252004-12-29 20:58:21 +00003186
Bram Moolenaar81695252004-12-29 20:58:21 +00003187 if g:netrw_port != ""
Luca Saccarolac363ca12024-12-19 20:16:18 +01003188 " remove any leading [:#] from port number
3189 let g:netrw_port = substitute(g:netrw_port,'[#:]\+','','')
Bram Moolenaaradc21822011-04-01 18:03:16 +02003190 elseif exists("netrw_port")
Luca Saccarolac363ca12024-12-19 20:16:18 +01003191 " retain port number as implicit for subsequent ftp operations
3192 let g:netrw_port= netrw_port
Bram Moolenaar81695252004-12-29 20:58:21 +00003193 endif
Bram Moolenaar4ea8fe12006-03-09 22:32:39 +00003194
Luca Saccarolac363ca12024-12-19 20:16:18 +01003195 " call Decho("a:choice <".a:choice.">",'~'.expand("<slnum>"))
3196 " call Decho("b:netrw_method <".b:netrw_method.">",'~'.expand("<slnum>"))
3197 " call Decho("g:netrw_machine<".g:netrw_machine.">",'~'.expand("<slnum>"))
3198 " call Decho("g:netrw_port <".g:netrw_port.">",'~'.expand("<slnum>"))
3199 " if exists("g:netrw_uid") "Decho
3200 " call Decho("g:netrw_uid <".g:netrw_uid.">",'~'.expand("<slnum>"))
3201 " endif "Decho
3202 " if exists("s:netrw_passwd") "Decho
3203 " call Decho("s:netrw_passwd <".s:netrw_passwd.">",'~'.expand("<slnum>"))
3204 " endif "Decho
3205 " call Decho("b:netrw_fname <".b:netrw_fname.">",'~'.expand("<slnum>"))
3206 " call Dret("s:NetrwMethod : b:netrw_method=".b:netrw_method." g:netrw_port=".g:netrw_port)
Bram Moolenaar071d4272004-06-13 20:20:40 +00003207endfun
Bram Moolenaar071d4272004-06-13 20:20:40 +00003208
Bram Moolenaar9964e462007-05-05 17:54:07 +00003209" ---------------------------------------------------------------------
Bram Moolenaarafeb4fa2006-02-01 21:51:12 +00003210" NetUserPass: set username and password for subsequent ftp transfer {{{2
Luca Saccarolac363ca12024-12-19 20:16:18 +01003211" Usage: :call NetUserPass() -- will prompt for userid and password
3212" :call NetUserPass("uid") -- will prompt for password
3213" :call NetUserPass("uid","password") -- sets global userid and password
3214" :call NetUserPass("ftp:host") -- looks up userid and password using hup dictionary
3215" :call NetUserPass("host","uid","password") -- sets hup dictionary with host, userid, password
Bram Moolenaar071d4272004-06-13 20:20:40 +00003216fun! NetUserPass(...)
3217
Luca Saccarolac363ca12024-12-19 20:16:18 +01003218 " call Dfunc("NetUserPass() a:0=".a:0)
Bram Moolenaar5b435d62012-04-05 17:33:26 +02003219
Luca Saccarolac363ca12024-12-19 20:16:18 +01003220 if !exists('s:netrw_hup')
3221 let s:netrw_hup= {}
Bram Moolenaar97d62492012-11-15 21:28:22 +01003222 endif
Bram Moolenaar5b435d62012-04-05 17:33:26 +02003223
Luca Saccarolac363ca12024-12-19 20:16:18 +01003224 if a:0 == 0
3225 " case: no input arguments
Bram Moolenaar5b435d62012-04-05 17:33:26 +02003226
Luca Saccarolac363ca12024-12-19 20:16:18 +01003227 " change host and username if not previously entered; get new password
3228 if !exists("g:netrw_machine")
3229 let g:netrw_machine= input('Enter hostname: ')
Bram Moolenaara6878372014-03-22 21:02:50 +01003230 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01003231 if !exists("g:netrw_uid") || g:netrw_uid == ""
3232 " get username (user-id) via prompt
3233 let g:netrw_uid= input('Enter username: ')
3234 endif
3235 " get password via prompting
3236 let s:netrw_passwd= inputsecret("Enter Password: ")
3237
3238 " set up hup database
3239 let host = substitute(g:netrw_machine,'\..*$','','')
3240 if !exists('s:netrw_hup[host]')
3241 let s:netrw_hup[host]= {}
3242 endif
3243 let s:netrw_hup[host].uid = g:netrw_uid
3244 let s:netrw_hup[host].passwd = s:netrw_passwd
3245
3246 elseif a:0 == 1
3247 " case: one input argument
3248
3249 if a:1 =~ '^ftp:'
3250 " get host from ftp:... url
3251 " access userid and password from hup (host-user-passwd) dictionary
3252 " call Decho("case a:0=1: a:1<".a:1."> (get host from ftp:... url)",'~'.expand("<slnum>"))
3253 let host = substitute(a:1,'^ftp:','','')
3254 let host = substitute(host,'\..*','','')
3255 if exists("s:netrw_hup[host]")
3256 let g:netrw_uid = s:netrw_hup[host].uid
3257 let s:netrw_passwd = s:netrw_hup[host].passwd
shane.xb.qianc673b802024-12-20 19:36:40 +01003258 " call Decho("get s:netrw_hup[".host."].uid <".s:netrw_hup[host].uid.">",'~'.expand("<slnum>"))
3259 " call Decho("get s:netrw_hup[".host."].passwd<".s:netrw_hup[host].passwd.">",'~'.expand("<slnum>"))
Luca Saccarolac363ca12024-12-19 20:16:18 +01003260 else
3261 let g:netrw_uid = input("Enter UserId: ")
3262 let s:netrw_passwd = inputsecret("Enter Password: ")
3263 endif
3264
3265 else
3266 " case: one input argument, not an url. Using it as a new user-id.
3267 " call Decho("case a:0=1: a:1<".a:1."> (get host from input argument, not an url)",'~'.expand("<slnum>"))
3268 if exists("g:netrw_machine")
3269 if g:netrw_machine =~ '[0-9.]\+'
3270 let host= g:netrw_machine
3271 else
3272 let host= substitute(g:netrw_machine,'\..*$','','')
3273 endif
3274 else
3275 let g:netrw_machine= input('Enter hostname: ')
3276 endif
3277 let g:netrw_uid = a:1
3278 " call Decho("set g:netrw_uid= <".g:netrw_uid.">",'~'.expand("<slnum>"))
3279 if exists("g:netrw_passwd")
3280 " ask for password if one not previously entered
3281 let s:netrw_passwd= g:netrw_passwd
3282 else
3283 let s:netrw_passwd = inputsecret("Enter Password: ")
3284 endif
3285 endif
3286
3287 " call Decho("host<".host.">",'~'.expand("<slnum>"))
3288 if exists("host")
3289 if !exists('s:netrw_hup[host]')
3290 let s:netrw_hup[host]= {}
3291 endif
3292 let s:netrw_hup[host].uid = g:netrw_uid
3293 let s:netrw_hup[host].passwd = s:netrw_passwd
3294 endif
3295
3296 elseif a:0 == 2
3297 let g:netrw_uid = a:1
3298 let s:netrw_passwd = a:2
3299
3300 elseif a:0 == 3
3301 " enter hostname, user-id, and password into the hup dictionary
3302 let host = substitute(a:1,'^\a\+:','','')
3303 let host = substitute(host,'\..*$','','')
3304 if !exists('s:netrw_hup[host]')
3305 let s:netrw_hup[host]= {}
3306 endif
3307 let s:netrw_hup[host].uid = a:2
3308 let s:netrw_hup[host].passwd = a:3
3309 let g:netrw_uid = s:netrw_hup[host].uid
3310 let s:netrw_passwd = s:netrw_hup[host].passwd
3311 " call Decho("set s:netrw_hup[".host."].uid <".s:netrw_hup[host].uid.">",'~'.expand("<slnum>"))
3312 " call Decho("set s:netrw_hup[".host."].passwd<".s:netrw_hup[host].passwd.">",'~'.expand("<slnum>"))
Bram Moolenaar5b435d62012-04-05 17:33:26 +02003313 endif
3314
Luca Saccarolac363ca12024-12-19 20:16:18 +01003315 " call Dret("NetUserPass : uid<".g:netrw_uid."> passwd<".s:netrw_passwd.">")
Bram Moolenaar071d4272004-06-13 20:20:40 +00003316endfun
Bram Moolenaar071d4272004-06-13 20:20:40 +00003317
Bram Moolenaar85850f32019-07-19 22:05:51 +02003318" =================================
Bram Moolenaar9964e462007-05-05 17:54:07 +00003319" Shared Browsing Support: {{{1
Bram Moolenaar85850f32019-07-19 22:05:51 +02003320" =================================
Bram Moolenaar071d4272004-06-13 20:20:40 +00003321
Bram Moolenaar69a7cb42004-06-20 12:51:53 +00003322" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +00003323" s:ExplorePatHls: converts an Explore pattern into a regular expression search pattern {{{2
3324fun! s:ExplorePatHls(pattern)
Luca Saccarolac363ca12024-12-19 20:16:18 +01003325 " call Dfunc("s:ExplorePatHls(pattern<".a:pattern.">)")
Bram Moolenaar446cb832008-06-24 21:56:24 +00003326 let repat= substitute(a:pattern,'^**/\{1,2}','','')
Luca Saccarolac363ca12024-12-19 20:16:18 +01003327 " call Decho("repat<".repat.">",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00003328 let repat= escape(repat,'][.\')
Luca Saccarolac363ca12024-12-19 20:16:18 +01003329 " call Decho("repat<".repat.">",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00003330 let repat= '\<'.substitute(repat,'\*','\\(\\S\\+ \\)*\\S\\+','g').'\>'
Luca Saccarolac363ca12024-12-19 20:16:18 +01003331 " call Dret("s:ExplorePatHls repat<".repat.">")
Bram Moolenaar446cb832008-06-24 21:56:24 +00003332 return repat
Bram Moolenaar9964e462007-05-05 17:54:07 +00003333endfun
3334
3335" ---------------------------------------------------------------------
Bram Moolenaar5c736222010-01-06 20:54:52 +01003336" s:NetrwBookHistHandler: {{{2
Bram Moolenaar446cb832008-06-24 21:56:24 +00003337" 0: (user: <mb>) bookmark current directory
3338" 1: (user: <gb>) change to the bookmarked directory
3339" 2: (user: <qb>) list bookmarks
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003340" 3: (browsing) records current directory history
3341" 4: (user: <u>) go up (previous) directory, using history
3342" 5: (user: <U>) go down (next) directory, using history
Bram Moolenaar446cb832008-06-24 21:56:24 +00003343" 6: (user: <mB>) delete bookmark
Bram Moolenaar5c736222010-01-06 20:54:52 +01003344fun! s:NetrwBookHistHandler(chg,curdir)
Luca Saccarolac363ca12024-12-19 20:16:18 +01003345 " 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 +02003346 if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01003347 " " call Dret("s:NetrwBookHistHandler - suppressed due to g:netrw_dirhistmax")
3348 return
Bram Moolenaarff034192013-04-24 18:51:19 +02003349 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +00003350
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003351 let ykeep = @@
3352 let curbufnr = bufnr("%")
3353
Bram Moolenaar9964e462007-05-05 17:54:07 +00003354 if a:chg == 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01003355 " bookmark the current directory
3356 " call Decho("(user: <b>) bookmark the current directory",'~'.expand("<slnum>"))
3357 if exists("s:netrwmarkfilelist_{curbufnr}")
3358 call s:NetrwBookmark(0)
3359 echo "bookmarked marked files"
3360 else
3361 call s:MakeBookmark(a:curdir)
3362 echo "bookmarked the current directory"
3363 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +00003364
Luca Saccarolac363ca12024-12-19 20:16:18 +01003365 try
3366 call s:NetrwBookHistSave()
3367 catch
3368 endtry
KSR-Yasudaf4498252023-10-06 03:34:17 +09003369
Bram Moolenaar9964e462007-05-05 17:54:07 +00003370 elseif a:chg == 1
Luca Saccarolac363ca12024-12-19 20:16:18 +01003371 " change to the bookmarked directory
3372 " call Decho("(user: <".v:count."gb>) change to the bookmarked directory",'~'.expand("<slnum>"))
3373 if exists("g:netrw_bookmarklist[v:count-1]")
3374 " call Decho("(user: <".v:count."gb>) bookmarklist=".string(g:netrw_bookmarklist),'~'.expand("<slnum>"))
3375 exe "NetrwKeepj e ".fnameescape(g:netrw_bookmarklist[v:count-1])
3376 else
3377 echomsg "Sorry, bookmark#".v:count." doesn't exist!"
3378 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +00003379
3380 elseif a:chg == 2
Luca Saccarolac363ca12024-12-19 20:16:18 +01003381 " redraw!
3382 let didwork= 0
3383 " list user's bookmarks
3384 " call Decho("(user: <q>) list user's bookmarks",'~'.expand("<slnum>"))
3385 if exists("g:netrw_bookmarklist")
3386 " call Decho('list '.len(g:netrw_bookmarklist).' bookmarks','~'.expand("<slnum>"))
3387 let cnt= 1
3388 for bmd in g:netrw_bookmarklist
3389 " call Decho("Netrw Bookmark#".cnt.": ".g:netrw_bookmarklist[cnt-1],'~'.expand("<slnum>"))
3390 echo printf("Netrw Bookmark#%-2d: %s",cnt,g:netrw_bookmarklist[cnt-1])
3391 let didwork = 1
3392 let cnt = cnt + 1
3393 endfor
3394 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +00003395
Luca Saccarolac363ca12024-12-19 20:16:18 +01003396 " list directory history
3397 " Note: history is saved only when PerformListing is done;
3398 " ie. when netrw can re-use a netrw buffer, the current directory is not saved in the history.
3399 let cnt = g:netrw_dirhistcnt
3400 let first = 1
3401 let histcnt = 0
3402 if g:netrw_dirhistmax > 0
3403 while ( first || cnt != g:netrw_dirhistcnt )
3404 " call Decho("first=".first." cnt=".cnt." dirhistcnt=".g:netrw_dirhistcnt,'~'.expand("<slnum>"))
3405 if exists("g:netrw_dirhist_{cnt}")
3406 " call Decho("Netrw History#".histcnt.": ".g:netrw_dirhist_{cnt},'~'.expand("<slnum>"))
3407 echo printf("Netrw History#%-2d: %s",histcnt,g:netrw_dirhist_{cnt})
3408 let didwork= 1
3409 endif
3410 let histcnt = histcnt + 1
3411 let first = 0
3412 let cnt = ( cnt - 1 ) % g:netrw_dirhistmax
3413 if cnt < 0
3414 let cnt= cnt + g:netrw_dirhistmax
3415 endif
3416 endwhile
3417 else
3418 let g:netrw_dirhistcnt= 0
3419 endif
3420 if didwork
3421 call inputsave()|call input("Press <cr> to continue")|call inputrestore()
3422 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +00003423
3424 elseif a:chg == 3
Luca Saccarolac363ca12024-12-19 20:16:18 +01003425 " saves most recently visited directories (when they differ)
3426 " call Decho("(browsing) record curdir history",'~'.expand("<slnum>"))
3427 if !exists("g:netrw_dirhistcnt") || !exists("g:netrw_dirhist_{g:netrw_dirhistcnt}") || g:netrw_dirhist_{g:netrw_dirhistcnt} != a:curdir
3428 if g:netrw_dirhistmax > 0
3429 let g:netrw_dirhistcnt = ( g:netrw_dirhistcnt + 1 ) % g:netrw_dirhistmax
3430 let g:netrw_dirhist_{g:netrw_dirhistcnt} = a:curdir
3431 endif
3432 " call Decho("save dirhist#".g:netrw_dirhistcnt."<".g:netrw_dirhist_{g:netrw_dirhistcnt}.">",'~'.expand("<slnum>"))
Bram Moolenaaradc21822011-04-01 18:03:16 +02003433 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +00003434
3435 elseif a:chg == 4
Luca Saccarolac363ca12024-12-19 20:16:18 +01003436 " u: change to the previous directory stored on the history list
3437 " call Decho("(user: <u>) chg to prev dir from history",'~'.expand("<slnum>"))
Bram Moolenaaradc21822011-04-01 18:03:16 +02003438 if g:netrw_dirhistmax > 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01003439 let g:netrw_dirhistcnt= ( g:netrw_dirhistcnt - v:count1 ) % g:netrw_dirhistmax
3440 if g:netrw_dirhistcnt < 0
3441 let g:netrw_dirhistcnt= g:netrw_dirhistcnt + g:netrw_dirhistmax
3442 endif
Bram Moolenaaradc21822011-04-01 18:03:16 +02003443 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01003444 let g:netrw_dirhistcnt= 0
Bram Moolenaaradc21822011-04-01 18:03:16 +02003445 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01003446 if exists("g:netrw_dirhist_{g:netrw_dirhistcnt}")
3447 " call Decho("changedir u#".g:netrw_dirhistcnt."<".g:netrw_dirhist_{g:netrw_dirhistcnt}.">",'~'.expand("<slnum>"))
3448 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
3449 setl ma noro
3450 " call Decho("setl ma noro",'~'.expand("<slnum>"))
3451 sil! NetrwKeepj %d _
3452 setl nomod
3453 " call Decho("setl nomod",'~'.expand("<slnum>"))
3454 " call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3455 endif
3456 " call Decho("exe e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhistcnt}),'~'.expand("<slnum>"))
3457 exe "NetrwKeepj e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhistcnt})
3458 else
3459 if g:netrw_dirhistmax > 0
3460 let g:netrw_dirhistcnt= ( g:netrw_dirhistcnt + v:count1 ) % g:netrw_dirhistmax
3461 else
3462 let g:netrw_dirhistcnt= 0
3463 endif
3464 echo "Sorry, no predecessor directory exists yet"
3465 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +00003466
3467 elseif a:chg == 5
Luca Saccarolac363ca12024-12-19 20:16:18 +01003468 " U: change to the subsequent directory stored on the history list
3469 " call Decho("(user: <U>) chg to next dir from history",'~'.expand("<slnum>"))
3470 if g:netrw_dirhistmax > 0
3471 let g:netrw_dirhistcnt= ( g:netrw_dirhistcnt + 1 ) % g:netrw_dirhistmax
3472 if exists("g:netrw_dirhist_{g:netrw_dirhistcnt}")
3473 " call Decho("changedir U#".g:netrw_dirhistcnt."<".g:netrw_dirhist_{g:netrw_dirhistcnt}.">",'~'.expand("<slnum>"))
3474 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
3475 " call Decho("setl ma noro",'~'.expand("<slnum>"))
3476 setl ma noro
3477 sil! NetrwKeepj %d _
3478 " call Decho("removed all lines from buffer (%d)",'~'.expand("<slnum>"))
3479 " call Decho("setl nomod",'~'.expand("<slnum>"))
3480 setl nomod
3481 " call Decho("(set nomod) ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
3482 endif
3483 " call Decho("exe e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhistcnt}),'~'.expand("<slnum>"))
3484 exe "NetrwKeepj e! ".fnameescape(g:netrw_dirhist_{g:netrw_dirhistcnt})
3485 else
3486 let g:netrw_dirhistcnt= ( g:netrw_dirhistcnt - 1 ) % g:netrw_dirhistmax
3487 if g:netrw_dirhistcnt < 0
3488 let g:netrw_dirhistcnt= g:netrw_dirhistcnt + g:netrw_dirhistmax
3489 endif
3490 echo "Sorry, no successor directory exists yet"
3491 endif
Bram Moolenaaradc21822011-04-01 18:03:16 +02003492 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01003493 let g:netrw_dirhistcnt= 0
3494 echo "Sorry, no successor directory exists yet (g:netrw_dirhistmax is ".g:netrw_dirhistmax.")"
Bram Moolenaar9964e462007-05-05 17:54:07 +00003495 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00003496
3497 elseif a:chg == 6
Luca Saccarolac363ca12024-12-19 20:16:18 +01003498 " call Decho("(user: <mB>) delete bookmark'd directory",'~'.expand("<slnum>"))
3499 if exists("s:netrwmarkfilelist_{curbufnr}")
3500 call s:NetrwBookmark(1)
3501 echo "removed marked files from bookmarks"
3502 else
3503 " delete the v:count'th bookmark
3504 let iremove = v:count
3505 let dremove = g:netrw_bookmarklist[iremove - 1]
3506 " call Decho("delete bookmark#".iremove."<".g:netrw_bookmarklist[iremove - 1].">",'~'.expand("<slnum>"))
3507 call s:MergeBookmarks()
3508 " call Decho("remove g:netrw_bookmarklist[".(iremove-1)."]<".g:netrw_bookmarklist[(iremove-1)].">",'~'.expand("<slnum>"))
3509 NetrwKeepj call remove(g:netrw_bookmarklist,iremove-1)
3510 echo "removed ".dremove." from g:netrw_bookmarklist"
3511 " call Decho("g:netrw_bookmarklist=".string(g:netrw_bookmarklist),'~'.expand("<slnum>"))
3512 endif
3513 " call Decho("resulting g:netrw_bookmarklist=".string(g:netrw_bookmarklist),'~'.expand("<slnum>"))
KSR-Yasudaf4498252023-10-06 03:34:17 +09003514
Luca Saccarolac363ca12024-12-19 20:16:18 +01003515 try
3516 call s:NetrwBookHistSave()
3517 catch
3518 endtry
Bram Moolenaar9964e462007-05-05 17:54:07 +00003519 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00003520 call s:NetrwBookmarkMenu()
Bram Moolenaarff034192013-04-24 18:51:19 +02003521 call s:NetrwTgtMenu()
Bram Moolenaar97d62492012-11-15 21:28:22 +01003522 let @@= ykeep
Luca Saccarolac363ca12024-12-19 20:16:18 +01003523 " call Dret("s:NetrwBookHistHandler")
Bram Moolenaar5c736222010-01-06 20:54:52 +01003524endfun
3525
3526" ---------------------------------------------------------------------
3527" s:NetrwBookHistRead: this function reads bookmarks and history {{{2
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003528" Will source the history file (.netrwhist) only if the g:netrw_disthistmax is > 0.
Bram Moolenaar5c736222010-01-06 20:54:52 +01003529" Sister function: s:NetrwBookHistSave()
3530fun! s:NetrwBookHistRead()
Luca Saccarolac363ca12024-12-19 20:16:18 +01003531 " call Dfunc("s:NetrwBookHistRead()")
Bram Moolenaarff034192013-04-24 18:51:19 +02003532 if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01003533 " call Dret("s:NetrwBookHistRead - nothing read (suppressed due to dirhistmax=".(exists("g:netrw_dirhistmax")? g:netrw_dirhistmax : "n/a").")")
3534 return
Bram Moolenaarff034192013-04-24 18:51:19 +02003535 endif
Bram Moolenaar97d62492012-11-15 21:28:22 +01003536 let ykeep= @@
Bram Moolenaar85850f32019-07-19 22:05:51 +02003537
3538 " read bookmarks
Bram Moolenaar5c736222010-01-06 20:54:52 +01003539 if !exists("s:netrw_initbookhist")
Luca Saccarolac363ca12024-12-19 20:16:18 +01003540 let home = s:NetrwHome()
3541 let savefile= home."/.netrwbook"
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003542 if filereadable(s:NetrwFile(savefile))
Luca Saccarolac363ca12024-12-19 20:16:18 +01003543 " call Decho("sourcing .netrwbook",'~'.expand("<slnum>"))
3544 exe "keepalt NetrwKeepj so ".savefile
Bram Moolenaaradc21822011-04-01 18:03:16 +02003545 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01003546
3547 " read history
3548 if g:netrw_dirhistmax > 0
3549 let savefile= home."/.netrwhist"
3550 if filereadable(s:NetrwFile(savefile))
3551 " call Decho("sourcing .netrwhist",'~'.expand("<slnum>"))
3552 exe "keepalt NetrwKeepj so ".savefile
3553 endif
3554 let s:netrw_initbookhist= 1
3555 au VimLeave * call s:NetrwBookHistSave()
3556 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +01003557 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02003558
Bram Moolenaar97d62492012-11-15 21:28:22 +01003559 let @@= ykeep
Luca Saccarolac363ca12024-12-19 20:16:18 +01003560 " call Decho("dirhistmax=".(exists("g:netrw_dirhistmax")? g:netrw_dirhistmax : "n/a"),'~'.expand("<slnum>"))
3561 " call Decho("dirhistcnt=".(exists("g:netrw_dirhistcnt")? g:netrw_dirhistcnt : "n/a"),'~'.expand("<slnum>"))
3562 " call Dret("s:NetrwBookHistRead")
Bram Moolenaar5c736222010-01-06 20:54:52 +01003563endfun
3564
3565" ---------------------------------------------------------------------
Bram Moolenaar85850f32019-07-19 22:05:51 +02003566" s:NetrwBookHistSave: this function saves bookmarks and history to files {{{2
Bram Moolenaar5c736222010-01-06 20:54:52 +01003567" Sister function: s:NetrwBookHistRead()
3568" I used to do this via viminfo but that appears to
3569" be unreliable for long-term storage
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003570" If g:netrw_dirhistmax is <= 0, no history or bookmarks
3571" will be saved.
Bram Moolenaar85850f32019-07-19 22:05:51 +02003572" (s:NetrwBookHistHandler(3,...) used to record history)
Bram Moolenaar5c736222010-01-06 20:54:52 +01003573fun! s:NetrwBookHistSave()
Luca Saccarolac363ca12024-12-19 20:16:18 +01003574 " call Dfunc("s:NetrwBookHistSave() dirhistmax=".g:netrw_dirhistmax." dirhistcnt=".g:netrw_dirhistcnt)
Bram Moolenaarff034192013-04-24 18:51:19 +02003575 if !exists("g:netrw_dirhistmax") || g:netrw_dirhistmax <= 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01003576 " call Dret("s:NetrwBookHistSave : nothing saved (dirhistmax=".g:netrw_dirhistmax.")")
3577 return
Bram Moolenaaradc21822011-04-01 18:03:16 +02003578 endif
3579
Bram Moolenaar5c736222010-01-06 20:54:52 +01003580 let savefile= s:NetrwHome()."/.netrwhist"
Luca Saccarolac363ca12024-12-19 20:16:18 +01003581 " call Decho("savefile<".savefile.">",'~'.expand("<slnum>"))
Bram Moolenaar5c736222010-01-06 20:54:52 +01003582 1split
Bram Moolenaar1d59aa12020-09-19 18:50:13 +02003583
3584 " setting up a new buffer which will become .netrwhist
Bram Moolenaar5c736222010-01-06 20:54:52 +01003585 call s:NetrwEnew()
Luca Saccarolac363ca12024-12-19 20:16:18 +01003586 " call Decho("case g:netrw_use_noswf=".g:netrw_use_noswf.(exists("+acd")? " +acd" : " -acd"),'~'.expand("<slnum>"))
Bram Moolenaare0fa3742016-02-20 15:47:01 +01003587 if g:netrw_use_noswf
Luca Saccarolac363ca12024-12-19 20:16:18 +01003588 setl cino= com= cpo-=a cpo-=A fo=nroql2 tw=0 report=10000 noswf
Bram Moolenaare0fa3742016-02-20 15:47:01 +01003589 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01003590 setl cino= com= cpo-=a cpo-=A fo=nroql2 tw=0 report=10000
Bram Moolenaare0fa3742016-02-20 15:47:01 +01003591 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02003592 setl nocin noai noci magic nospell nohid wig= noaw
3593 setl ma noro write
3594 if exists("+acd") | setl noacd | endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003595 sil! NetrwKeepj keepalt %d _
Bram Moolenaar5c736222010-01-06 20:54:52 +01003596
Bram Moolenaar85850f32019-07-19 22:05:51 +02003597 " rename enew'd file: .netrwhist -- no attempt to merge
3598 " record dirhistmax and current dirhistcnt
3599 " save history
Luca Saccarolac363ca12024-12-19 20:16:18 +01003600 " call Decho("saving history: dirhistmax=".g:netrw_dirhistmax." dirhistcnt=".g:netrw_dirhistcnt." lastline=".line("$"),'~'.expand("<slnum>"))
Bram Moolenaarff034192013-04-24 18:51:19 +02003601 sil! keepalt file .netrwhist
Bram Moolenaar5c736222010-01-06 20:54:52 +01003602 call setline(1,"let g:netrw_dirhistmax =".g:netrw_dirhistmax)
Bram Moolenaar85850f32019-07-19 22:05:51 +02003603 call setline(2,"let g:netrw_dirhistcnt =".g:netrw_dirhistcnt)
3604 if g:netrw_dirhistmax > 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01003605 let lastline = line("$")
3606 let cnt = g:netrw_dirhistcnt
3607 let first = 1
3608 while ( first || cnt != g:netrw_dirhistcnt )
3609 let lastline= lastline + 1
3610 if exists("g:netrw_dirhist_{cnt}")
3611 call setline(lastline,'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'")
3612 " call Decho("..".lastline.'let g:netrw_dirhist_'.cnt."='".g:netrw_dirhist_{cnt}."'",'~'.expand("<slnum>"))
3613 endif
3614 let first = 0
3615 let cnt = ( cnt - 1 ) % g:netrw_dirhistmax
3616 if cnt < 0
3617 let cnt= cnt + g:netrw_dirhistmax
3618 endif
3619 endwhile
3620 exe "sil! w! ".savefile
3621 " call Decho("exe sil! w! ".savefile,'~'.expand("<slnum>"))
Bram Moolenaar85850f32019-07-19 22:05:51 +02003622 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +01003623
Bram Moolenaar85850f32019-07-19 22:05:51 +02003624 " save bookmarks
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003625 sil NetrwKeepj %d _
Bram Moolenaar5c736222010-01-06 20:54:52 +01003626 if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != []
Luca Saccarolac363ca12024-12-19 20:16:18 +01003627 " call Decho("saving bookmarks",'~'.expand("<slnum>"))
3628 " merge and write .netrwbook
3629 let savefile= s:NetrwHome()."/.netrwbook"
Bram Moolenaar5c736222010-01-06 20:54:52 +01003630
Luca Saccarolac363ca12024-12-19 20:16:18 +01003631 if filereadable(s:NetrwFile(savefile))
3632 let booklist= deepcopy(g:netrw_bookmarklist)
3633 exe "sil NetrwKeepj keepalt so ".savefile
3634 for bdm in booklist
3635 if index(g:netrw_bookmarklist,bdm) == -1
3636 call add(g:netrw_bookmarklist,bdm)
3637 endif
3638 endfor
3639 call sort(g:netrw_bookmarklist)
3640 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +01003641
Luca Saccarolac363ca12024-12-19 20:16:18 +01003642 " construct and save .netrwbook
3643 call setline(1,"let g:netrw_bookmarklist= ".string(g:netrw_bookmarklist))
3644 exe "sil! w! ".savefile
3645 " call Decho("exe sil! w! ".savefile,'~'.expand("<slnum>"))
Bram Moolenaar5c736222010-01-06 20:54:52 +01003646 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02003647
3648 " cleanup -- remove buffer used to construct history
Bram Moolenaar5c736222010-01-06 20:54:52 +01003649 let bgone= bufnr("%")
3650 q!
Bram Moolenaarff034192013-04-24 18:51:19 +02003651 exe "keepalt ".bgone."bwipe!"
Bram Moolenaar5c736222010-01-06 20:54:52 +01003652
Luca Saccarolac363ca12024-12-19 20:16:18 +01003653 " call Dret("s:NetrwBookHistSave")
Bram Moolenaar9964e462007-05-05 17:54:07 +00003654endfun
3655
3656" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +00003657" s:NetrwBrowse: This function uses the command in g:netrw_list_cmd to provide a {{{2
3658" list of the contents of a local or remote directory. It is assumed that the
3659" g:netrw_list_cmd has a string, USEPORT HOSTNAME, that needs to be substituted
3660" with the requested remote hostname first.
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003661" Often called via: Explore/e dirname/etc -> netrw#LocalBrowseCheck() -> s:NetrwBrowse()
Bram Moolenaar446cb832008-06-24 21:56:24 +00003662fun! s:NetrwBrowse(islocal,dirname)
3663 if !exists("w:netrw_liststyle")|let w:netrw_liststyle= g:netrw_liststyle|endif
Bram Moolenaara6878372014-03-22 21:02:50 +01003664
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003665 " save alternate-file's filename if w:netrw_rexlocal doesn't exist
3666 " This is useful when one edits a local file, then :e ., then :Rex
3667 if a:islocal && !exists("w:netrw_rexfile") && bufname("#") != ""
Luca Saccarolac363ca12024-12-19 20:16:18 +01003668 let w:netrw_rexfile= bufname("#")
Bram Moolenaar5c736222010-01-06 20:54:52 +01003669 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +01003670
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003671 " s:NetrwBrowse : initialize history {{{3
3672 if !exists("s:netrw_initbookhist")
Luca Saccarolac363ca12024-12-19 20:16:18 +01003673 NetrwKeepj call s:NetrwBookHistRead()
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003674 endif
3675
3676 " s:NetrwBrowse : simplify the dirname (especially for ".."s in dirnames) {{{3
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003677 if a:dirname !~ '^\a\{3,}://'
Luca Saccarolac363ca12024-12-19 20:16:18 +01003678 let dirname= simplify(a:dirname)
Bram Moolenaar5c736222010-01-06 20:54:52 +01003679 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01003680 let dirname= a:dirname
Bram Moolenaar5c736222010-01-06 20:54:52 +01003681 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00003682
Bram Moolenaar85850f32019-07-19 22:05:51 +02003683 " repoint t:netrw_lexbufnr if appropriate
3684 if exists("t:netrw_lexbufnr") && bufnr("%") == t:netrw_lexbufnr
Luca Saccarolac363ca12024-12-19 20:16:18 +01003685 let repointlexbufnr= 1
Bram Moolenaar85850f32019-07-19 22:05:51 +02003686 endif
3687
3688 " s:NetrwBrowse : sanity checks: {{{3
Bram Moolenaar446cb832008-06-24 21:56:24 +00003689 if exists("s:netrw_skipbrowse")
Luca Saccarolac363ca12024-12-19 20:16:18 +01003690 unlet s:netrw_skipbrowse
3691 return
Bram Moolenaar446cb832008-06-24 21:56:24 +00003692 endif
3693 if !exists("*shellescape")
Luca Saccarolac363ca12024-12-19 20:16:18 +01003694 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw can't run -- your vim is missing shellescape()",69)
3695 return
Bram Moolenaar446cb832008-06-24 21:56:24 +00003696 endif
3697 if !exists("*fnameescape")
Luca Saccarolac363ca12024-12-19 20:16:18 +01003698 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw can't run -- your vim is missing fnameescape()",70)
3699 return
Bram Moolenaar446cb832008-06-24 21:56:24 +00003700 endif
3701
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003702 " s:NetrwBrowse : save options: {{{3
Bram Moolenaar85850f32019-07-19 22:05:51 +02003703 call s:NetrwOptionsSave("w:")
Bram Moolenaar446cb832008-06-24 21:56:24 +00003704
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003705 " s:NetrwBrowse : re-instate any marked files {{{3
Bram Moolenaar85850f32019-07-19 22:05:51 +02003706 if has("syntax") && exists("g:syntax_on") && g:syntax_on
Luca Saccarolac363ca12024-12-19 20:16:18 +01003707 if exists("s:netrwmarkfilelist_{bufnr('%')}")
3708 exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
3709 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00003710 endif
3711
3712 if a:islocal && exists("w:netrw_acdkeep") && w:netrw_acdkeep
Luca Saccarolac363ca12024-12-19 20:16:18 +01003713 " s:NetrwBrowse : set up "safe" options for local directory/file {{{3
3714 if s:NetrwLcd(dirname)
3715 return
3716 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00003717
Bram Moolenaar5c736222010-01-06 20:54:52 +01003718 elseif !a:islocal && dirname !~ '[\/]$' && dirname !~ '^"'
Luca Saccarolac363ca12024-12-19 20:16:18 +01003719 " s:NetrwBrowse : remote regular file handler {{{3
3720 if bufname(dirname) != ""
3721 exe "NetrwKeepj b ".bufname(dirname)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003722 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01003723 " attempt transfer of remote regular file
Bram Moolenaar446cb832008-06-24 21:56:24 +00003724
Luca Saccarolac363ca12024-12-19 20:16:18 +01003725 " remove any filetype indicator from end of dirname, except for the
3726 " "this is a directory" indicator (/).
3727 " There shouldn't be one of those here, anyway.
3728 let path= substitute(dirname,'[*=@|]\r\=$','','e')
3729 call s:RemotePathAnalysis(dirname)
3730
3731 " s:NetrwBrowse : remote-read the requested file into current buffer {{{3
3732 call s:NetrwEnew(dirname)
3733 call s:NetrwOptionsSafe(a:islocal)
3734 setl ma noro
3735 let b:netrw_curdir = dirname
3736 let url = s:method."://".((s:user == "")? "" : s:user."@").s:machine.(s:port ? ":".s:port : "")."/".s:path
3737 call s:NetrwBufRename(url)
3738 exe "sil! NetrwKeepj keepalt doau BufReadPre ".fnameescape(s:fname)
3739 sil call netrw#NetRead(2,url)
3740 " netrw.vim and tar.vim have already handled decompression of the tarball; avoiding gzip.vim error
3741 if s:path =~ '.bz2'
3742 exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(substitute(s:fname,'\.bz2$','',''))
3743 elseif s:path =~ '.gz'
3744 exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(substitute(s:fname,'\.gz$','',''))
3745 elseif s:path =~ '.gz'
3746 exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(substitute(s:fname,'\.txz$','',''))
3747 else
3748 exe "sil NetrwKeepj keepalt doau BufReadPost ".fnameescape(s:fname)
3749 endif
3750 endif
3751
3752 " s:NetrwBrowse : save certain window-oriented variables into buffer-oriented variables {{{3
3753 call s:SetBufWinVars()
3754 call s:NetrwOptionsRestore("w:")
3755 setl ma nomod noro
3756 return
Bram Moolenaar446cb832008-06-24 21:56:24 +00003757 endif
3758
Bram Moolenaaradc21822011-04-01 18:03:16 +02003759 " use buffer-oriented WinVars if buffer variables exist but associated window variables don't {{{3
Bram Moolenaar446cb832008-06-24 21:56:24 +00003760 call s:UseBufWinVars()
3761
3762 " set up some variables {{{3
3763 let b:netrw_browser_active = 1
Bram Moolenaar5c736222010-01-06 20:54:52 +01003764 let dirname = dirname
Bram Moolenaar446cb832008-06-24 21:56:24 +00003765 let s:last_sort_by = g:netrw_sort_by
3766
3767 " set up menu {{{3
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003768 NetrwKeepj call s:NetrwMenu(1)
Bram Moolenaar446cb832008-06-24 21:56:24 +00003769
Bram Moolenaar97d62492012-11-15 21:28:22 +01003770 " get/set-up buffer {{{3
Bram Moolenaare0fa3742016-02-20 15:47:01 +01003771 let svpos = winsaveview()
Tom Benham64a536d2024-11-07 21:15:03 +01003772
3773 " NetrwGetBuffer might change buffers but s:rexposn_X was set for the
3774 " previous buffer
3775 let prevbufnr = bufnr('%')
Bram Moolenaar446cb832008-06-24 21:56:24 +00003776 let reusing= s:NetrwGetBuffer(a:islocal,dirname)
Tom Benham64a536d2024-11-07 21:15:03 +01003777 if exists("s:rexposn_".prevbufnr)
Luca Saccarolac363ca12024-12-19 20:16:18 +01003778 let s:rexposn_{bufnr('%')} = s:rexposn_{prevbufnr}
Tom Benham64a536d2024-11-07 21:15:03 +01003779 endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003780
Bram Moolenaar446cb832008-06-24 21:56:24 +00003781 " maintain markfile highlighting
Bram Moolenaar85850f32019-07-19 22:05:51 +02003782 if has("syntax") && exists("g:syntax_on") && g:syntax_on
Luca Saccarolac363ca12024-12-19 20:16:18 +01003783 if exists("s:netrwmarkfilemtch_{bufnr('%')}") && s:netrwmarkfilemtch_{bufnr("%")} != ""
3784 exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
3785 else
3786 2match none
3787 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00003788 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02003789 if reusing && line("$") > 1
Luca Saccarolac363ca12024-12-19 20:16:18 +01003790 call s:NetrwOptionsRestore("w:")
3791 setl noma nomod nowrap
3792 return
Bram Moolenaar446cb832008-06-24 21:56:24 +00003793 endif
3794
3795 " set b:netrw_curdir to the new directory name {{{3
Bram Moolenaar5ac3b1a2010-07-27 22:50:36 +02003796 let b:netrw_curdir= dirname
Bram Moolenaar446cb832008-06-24 21:56:24 +00003797 if b:netrw_curdir =~ '[/\\]$'
Luca Saccarolac363ca12024-12-19 20:16:18 +01003798 let b:netrw_curdir= substitute(b:netrw_curdir,'[/\\]$','','e')
Bram Moolenaar446cb832008-06-24 21:56:24 +00003799 endif
Nir Lichtman1e34b952024-05-08 19:19:34 +02003800 if b:netrw_curdir =~ '\a:$' && has("win32")
Luca Saccarolac363ca12024-12-19 20:16:18 +01003801 let b:netrw_curdir= b:netrw_curdir."/"
Bram Moolenaar8d043172014-01-23 14:24:41 +01003802 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00003803 if b:netrw_curdir == ''
Luca Saccarolac363ca12024-12-19 20:16:18 +01003804 if has("amiga")
3805 " On the Amiga, the empty string connotes the current directory
3806 let b:netrw_curdir= getcwd()
3807 else
3808 " under unix, when the root directory is encountered, the result
3809 " from the preceding substitute is an empty string.
3810 let b:netrw_curdir= '/'
3811 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00003812 endif
3813 if !a:islocal && b:netrw_curdir !~ '/$'
Luca Saccarolac363ca12024-12-19 20:16:18 +01003814 let b:netrw_curdir= b:netrw_curdir.'/'
Bram Moolenaar446cb832008-06-24 21:56:24 +00003815 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00003816
3817 " ------------
3818 " (local only) {{{3
3819 " ------------
3820 if a:islocal
Luca Saccarolac363ca12024-12-19 20:16:18 +01003821 " Set up ShellCmdPost handling. Append current buffer to browselist
3822 call s:LocalFastBrowser()
Bram Moolenaar446cb832008-06-24 21:56:24 +00003823
Luca Saccarolac363ca12024-12-19 20:16:18 +01003824 " handle g:netrw_keepdir: set vim's current directory to netrw's notion of the current directory {{{3
3825 if !g:netrw_keepdir
3826 if !exists("&l:acd") || !&l:acd
3827 if s:NetrwLcd(b:netrw_curdir)
3828 return
3829 endif
3830 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00003831 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00003832
shane.xb.qianc673b802024-12-20 19:36:40 +01003833 " --------------------------------
3834 " remote handling: {{{3
3835 " --------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +00003836 else
Bram Moolenaar446cb832008-06-24 21:56:24 +00003837
Luca Saccarolac363ca12024-12-19 20:16:18 +01003838 " analyze dirname and g:netrw_list_cmd {{{3
3839 if dirname =~# "^NetrwTreeListing\>"
3840 let dirname= b:netrw_curdir
3841 elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir")
3842 let dirname= substitute(b:netrw_curdir,'\\','/','g')
3843 if dirname !~ '/$'
3844 let dirname= dirname.'/'
3845 endif
3846 let b:netrw_curdir = dirname
3847 else
3848 let dirname = substitute(dirname,'\\','/','g')
Bram Moolenaar446cb832008-06-24 21:56:24 +00003849 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00003850
Luca Saccarolac363ca12024-12-19 20:16:18 +01003851 let dirpat = '^\(\w\{-}\)://\(\w\+@\)\=\([^/]\+\)/\(.*\)$'
3852 if dirname !~ dirpat
3853 if !exists("g:netrw_quiet")
3854 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"netrw doesn't understand your dirname<".dirname.">",20)
3855 endif
3856 NetrwKeepj call s:NetrwOptionsRestore("w:")
3857 setl noma nomod nowrap
3858 return
Bram Moolenaar446cb832008-06-24 21:56:24 +00003859 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01003860 let b:netrw_curdir= dirname
Bram Moolenaar446cb832008-06-24 21:56:24 +00003861 endif " (additional remote handling)
3862
Bram Moolenaar85850f32019-07-19 22:05:51 +02003863 " -------------------------------
3864 " Perform Directory Listing: {{{3
3865 " -------------------------------
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003866 NetrwKeepj call s:NetrwMaps(a:islocal)
3867 NetrwKeepj call s:NetrwCommands(a:islocal)
3868 NetrwKeepj call s:PerformListing(a:islocal)
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003869
Bram Moolenaare0fa3742016-02-20 15:47:01 +01003870 " restore option(s)
Bram Moolenaar85850f32019-07-19 22:05:51 +02003871 call s:NetrwOptionsRestore("w:")
Bram Moolenaare0fa3742016-02-20 15:47:01 +01003872
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003873 " If there is a rexposn: restore position with rexposn
3874 " Otherwise : set rexposn
3875 if exists("s:rexposn_".bufnr("%"))
Luca Saccarolac363ca12024-12-19 20:16:18 +01003876 NetrwKeepj call winrestview(s:rexposn_{bufnr('%')})
3877 if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt
3878 NetrwKeepj exe w:netrw_bannercnt
3879 endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003880 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01003881 NetrwKeepj call s:SetRexDir(a:islocal,b:netrw_curdir)
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003882 endif
Bram Moolenaar15146672011-10-20 22:22:38 +02003883 if v:version >= 700 && has("balloon_eval") && &beval == 0 && &l:bexpr == "" && !exists("g:netrw_nobeval")
Luca Saccarolac363ca12024-12-19 20:16:18 +01003884 let &l:bexpr= "netrw#BalloonHelp()"
3885 setl beval
Bram Moolenaaradc21822011-04-01 18:03:16 +02003886 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +01003887
Bram Moolenaar85850f32019-07-19 22:05:51 +02003888 " repoint t:netrw_lexbufnr if appropriate
3889 if exists("repointlexbufnr")
Luca Saccarolac363ca12024-12-19 20:16:18 +01003890 let t:netrw_lexbufnr= bufnr("%")
Bram Moolenaar85850f32019-07-19 22:05:51 +02003891 endif
3892
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003893 " restore position
3894 if reusing
Luca Saccarolac363ca12024-12-19 20:16:18 +01003895 call winrestview(svpos)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01003896 endif
3897
Bram Moolenaara6878372014-03-22 21:02:50 +01003898 " The s:LocalBrowseRefresh() function is called by an autocmd
Bram Moolenaar85850f32019-07-19 22:05:51 +02003899 " installed by s:LocalFastBrowser() when g:netrw_fastbrowse <= 1 (ie. slow or medium speed).
3900 " However, s:NetrwBrowse() causes the FocusGained event to fire the first time.
Bram Moolenaar446cb832008-06-24 21:56:24 +00003901 return
3902endfun
3903
3904" ---------------------------------------------------------------------
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003905" s:NetrwFile: because of g:netrw_keepdir, isdirectory(), type(), etc may or {{{2
3906" may not apply correctly; ie. netrw's idea of the current directory may
3907" differ from vim's. This function insures that netrw's idea of the current
3908" directory is used.
Bram Moolenaar85850f32019-07-19 22:05:51 +02003909" Returns a path to the file specified by a:fname
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003910fun! s:NetrwFile(fname)
Luca Saccarolac363ca12024-12-19 20:16:18 +01003911 " "" call Dfunc("s:NetrwFile(fname<".a:fname.">) win#".winnr())
3912 " "" call Decho("g:netrw_keepdir =".(exists("g:netrw_keepdir")? g:netrw_keepdir : 'n/a'),'~'.expand("<slnum>"))
3913 " "" call Decho("g:netrw_cygwin =".(exists("g:netrw_cygwin")? g:netrw_cygwin : 'n/a'),'~'.expand("<slnum>"))
3914 " "" call Decho("g:netrw_liststyle=".(exists("g:netrw_liststyle")? g:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
3915 " "" call Decho("w:netrw_liststyle=".(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
Bram Moolenaare0fa3742016-02-20 15:47:01 +01003916
3917 " clean up any leading treedepthstring
3918 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
Luca Saccarolac363ca12024-12-19 20:16:18 +01003919 let fname= substitute(a:fname,'^'.s:treedepthstring.'\+','','')
shane.xb.qianc673b802024-12-20 19:36:40 +01003920 " "" call Decho("clean up any leading treedepthstring: fname<".fname.">",'~'.expand("<slnum>"))
Bram Moolenaare0fa3742016-02-20 15:47:01 +01003921 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01003922 let fname= a:fname
Bram Moolenaare0fa3742016-02-20 15:47:01 +01003923 endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003924
3925 if g:netrw_keepdir
Luca Saccarolac363ca12024-12-19 20:16:18 +01003926 " vim's idea of the current directory possibly may differ from netrw's
3927 if !exists("b:netrw_curdir")
3928 let b:netrw_curdir= getcwd()
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003929 endif
3930
Luca Saccarolac363ca12024-12-19 20:16:18 +01003931 if !exists("g:netrw_cygwin") && has("win32")
3932 if fname =~ '^\' || fname =~ '^\a:\'
3933 " windows, but full path given
3934 let ret= fname
shane.xb.qianc673b802024-12-20 19:36:40 +01003935 " "" call Decho("windows+full path: isdirectory(".fname.")",'~'.expand("<slnum>"))
Luca Saccarolac363ca12024-12-19 20:16:18 +01003936 else
3937 " windows, relative path given
3938 let ret= s:ComposePath(b:netrw_curdir,fname)
3939 " "" call Decho("windows+rltv path: isdirectory(".fname.")",'~'.expand("<slnum>"))
3940 endif
3941
3942 elseif fname =~ '^/'
3943 " not windows, full path given
3944 let ret= fname
shane.xb.qianc673b802024-12-20 19:36:40 +01003945 " "" call Decho("unix+full path: isdirectory(".fname.")",'~'.expand("<slnum>"))
Luca Saccarolac363ca12024-12-19 20:16:18 +01003946 else
3947 " not windows, relative path given
3948 let ret= s:ComposePath(b:netrw_curdir,fname)
3949 " "" call Decho("unix+rltv path: isdirectory(".fname.")",'~'.expand("<slnum>"))
3950 endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003951 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01003952 " vim and netrw agree on the current directory
3953 let ret= fname
3954 " "" call Decho("vim and netrw agree on current directory (g:netrw_keepdir=".g:netrw_keepdir.")",'~'.expand("<slnum>"))
3955 " "" call Decho("vim directory: ".getcwd(),'~'.expand("<slnum>"))
3956 " "" call Decho("netrw directory: ".(exists("b:netrw_curdir")? b:netrw_curdir : 'n/a'),'~'.expand("<slnum>"))
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003957 endif
3958
Luca Saccarolac363ca12024-12-19 20:16:18 +01003959 " "" call Dret("s:NetrwFile ".ret)
Bram Moolenaara0f849e2015-10-30 14:37:44 +01003960 return ret
3961endfun
3962
3963" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +00003964" s:NetrwFileInfo: supports qf (query for file information) {{{2
3965fun! s:NetrwFileInfo(islocal,fname)
Luca Saccarolac363ca12024-12-19 20:16:18 +01003966 " call Dfunc("s:NetrwFileInfo(islocal=".a:islocal." fname<".a:fname.">) b:netrw_curdir<".b:netrw_curdir.">")
Bram Moolenaar97d62492012-11-15 21:28:22 +01003967 let ykeep= @@
Bram Moolenaar446cb832008-06-24 21:56:24 +00003968 if a:islocal
Luca Saccarolac363ca12024-12-19 20:16:18 +01003969 let lsopt= "-lsad"
3970 if g:netrw_sizestyle =~# 'H'
3971 let lsopt= "-lsadh"
3972 elseif g:netrw_sizestyle =~# 'h'
3973 let lsopt= "-lsadh --si"
3974 endif
3975 " call Decho("(s:NetrwFileInfo) lsopt<".lsopt.">")
3976 if (has("unix") || has("macunix")) && executable("/bin/ls")
Bram Moolenaar8d043172014-01-23 14:24:41 +01003977
Luca Saccarolac363ca12024-12-19 20:16:18 +01003978 if getline(".") == "../"
3979 echo system("/bin/ls ".lsopt." ".s:ShellEscape(".."))
shane.xb.qianc673b802024-12-20 19:36:40 +01003980 " call Decho("#1: echo system(/bin/ls -lsad ".s:ShellEscape(..).")",'~'.expand("<slnum>"))
Bram Moolenaar8d043172014-01-23 14:24:41 +01003981
Luca Saccarolac363ca12024-12-19 20:16:18 +01003982 elseif w:netrw_liststyle == s:TREELIST && getline(".") !~ '^'.s:treedepthstring
3983 echo system("/bin/ls ".lsopt." ".s:ShellEscape(b:netrw_curdir))
shane.xb.qianc673b802024-12-20 19:36:40 +01003984 " call Decho("#2: echo system(/bin/ls -lsad ".s:ShellEscape(b:netrw_curdir).")",'~'.expand("<slnum>"))
Bram Moolenaar8d043172014-01-23 14:24:41 +01003985
Luca Saccarolac363ca12024-12-19 20:16:18 +01003986 elseif exists("b:netrw_curdir")
3987 echo system("/bin/ls ".lsopt." ".s:ShellEscape(s:ComposePath(b:netrw_curdir,a:fname)))
shane.xb.qianc673b802024-12-20 19:36:40 +01003988 " call Decho("#3: echo system(/bin/ls -lsad ".s:ShellEscape(b:netrw_curdir.a:fname).")",'~'.expand("<slnum>"))
Bram Moolenaar8d043172014-01-23 14:24:41 +01003989
Luca Saccarolac363ca12024-12-19 20:16:18 +01003990 else
3991 " call Decho('using ls '.a:fname." using cwd<".getcwd().">",'~'.expand("<slnum>"))
3992 echo system("/bin/ls ".lsopt." ".s:ShellEscape(s:NetrwFile(a:fname)))
3993 " call Decho("#5: echo system(/bin/ls -lsad ".s:ShellEscape(a:fname).")",'~'.expand("<slnum>"))
3994 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00003995 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01003996 " use vim functions to return information about file below cursor
3997 " call Decho("using vim functions to query for file info",'~'.expand("<slnum>"))
3998 if !isdirectory(s:NetrwFile(a:fname)) && !filereadable(s:NetrwFile(a:fname)) && a:fname =~ '[*@/]'
3999 let fname= substitute(a:fname,".$","","")
4000 else
4001 let fname= a:fname
4002 endif
4003 let t = getftime(s:NetrwFile(fname))
4004 let sz = getfsize(s:NetrwFile(fname))
4005 if g:netrw_sizestyle =~# "[hH]"
4006 let sz= s:NetrwHumanReadable(sz)
4007 endif
4008 echo a:fname.": ".sz." ".strftime(g:netrw_timefmt,getftime(s:NetrwFile(fname)))
4009 " call Decho("fname.": ".sz." ".strftime(g:netrw_timefmt,getftime(fname)),'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00004010 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00004011 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01004012 echo "sorry, \"qf\" not supported yet for remote files"
Bram Moolenaar446cb832008-06-24 21:56:24 +00004013 endif
Bram Moolenaar97d62492012-11-15 21:28:22 +01004014 let @@= ykeep
Luca Saccarolac363ca12024-12-19 20:16:18 +01004015 " call Dret("s:NetrwFileInfo")
Bram Moolenaar446cb832008-06-24 21:56:24 +00004016endfun
4017
4018" ---------------------------------------------------------------------
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +02004019" s:NetrwFullPath: returns the full path to a directory and/or file {{{2
4020fun! s:NetrwFullPath(filename)
Luca Saccarolac363ca12024-12-19 20:16:18 +01004021 " " call Dfunc("s:NetrwFullPath(filename<".a:filename.">)")
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +02004022 let filename= a:filename
4023 if filename !~ '^/'
Luca Saccarolac363ca12024-12-19 20:16:18 +01004024 let filename= resolve(getcwd().'/'.filename)
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +02004025 endif
4026 if filename != "/" && filename =~ '/$'
Luca Saccarolac363ca12024-12-19 20:16:18 +01004027 let filename= substitute(filename,'/$','','')
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +02004028 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01004029 " " call Dret("s:NetrwFullPath <".filename.">")
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +02004030 return filename
4031endfun
4032
4033" ---------------------------------------------------------------------
Bram Moolenaar85850f32019-07-19 22:05:51 +02004034" s:NetrwGetBuffer: [get a new|find an old netrw] buffer for a netrw listing {{{2
Bram Moolenaar446cb832008-06-24 21:56:24 +00004035" returns 0=cleared buffer
Bram Moolenaara0f849e2015-10-30 14:37:44 +01004036" 1=re-used buffer (buffer not cleared)
Bram Moolenaar89a9c152021-08-29 21:55:35 +02004037" 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 +00004038fun! s:NetrwGetBuffer(islocal,dirname)
Luca Saccarolac363ca12024-12-19 20:16:18 +01004039 " call Dfunc("s:NetrwGetBuffer(islocal=".a:islocal." dirname<".a:dirname.">) liststyle=".g:netrw_liststyle)
4040 " 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>"))
4041 " call Decho("netrwbuf dictionary=".(exists("s:netrwbuf")? string(s:netrwbuf) : 'n/a'),'~'.expand("<slnum>"))
4042 " call Dredir("ls!","s:NetrwGetBuffer")
Bram Moolenaar446cb832008-06-24 21:56:24 +00004043 let dirname= a:dirname
4044
4045 " re-use buffer if possible {{{3
Luca Saccarolac363ca12024-12-19 20:16:18 +01004046 " call Decho("--re-use a buffer if possible--",'~'.expand("<slnum>"))
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +02004047 if !exists("s:netrwbuf")
Luca Saccarolac363ca12024-12-19 20:16:18 +01004048 " call Decho(" s:netrwbuf initialized to {}",'~'.expand("<slnum>"))
4049 let s:netrwbuf= {}
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +02004050 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01004051 " call Decho(" s:netrwbuf =".string(s:netrwbuf),'~'.expand("<slnum>"))
4052 " call Decho(" w:netrw_liststyle =".(exists("w:netrw_liststyle")? w:netrw_liststyle : "n/a"),'~'.expand("<slnum>"))
Bram Moolenaar85850f32019-07-19 22:05:51 +02004053
4054 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
Luca Saccarolac363ca12024-12-19 20:16:18 +01004055 let bufnum = -1
Bram Moolenaar85850f32019-07-19 22:05:51 +02004056
Luca Saccarolac363ca12024-12-19 20:16:18 +01004057 if !empty(s:netrwbuf) && has_key(s:netrwbuf,s:NetrwFullPath(dirname))
4058 if has_key(s:netrwbuf,"NetrwTreeListing")
4059 let bufnum= s:netrwbuf["NetrwTreeListing"]
4060 else
4061 let bufnum= s:netrwbuf[s:NetrwFullPath(dirname)]
4062 endif
4063 " call Decho(" NetrwTreeListing: bufnum#".bufnum,'~'.expand("<slnum>"))
4064 if !bufexists(bufnum)
4065 call remove(s:netrwbuf,"NetrwTreeListing")
4066 let bufnum= -1
4067 endif
4068 elseif bufnr("NetrwTreeListing") != -1
4069 let bufnum= bufnr("NetrwTreeListing")
shane.xb.qianc673b802024-12-20 19:36:40 +01004070 " call Decho(" NetrwTreeListing".": bufnum#".bufnum,'~'.expand("<slnum>"))
Bram Moolenaar85850f32019-07-19 22:05:51 +02004071 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01004072 " call Decho(" did not find a NetrwTreeListing buffer",'~'.expand("<slnum>"))
4073 let bufnum= -1
Bram Moolenaar85850f32019-07-19 22:05:51 +02004074 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02004075
4076 elseif has_key(s:netrwbuf,s:NetrwFullPath(dirname))
Luca Saccarolac363ca12024-12-19 20:16:18 +01004077 let bufnum= s:netrwbuf[s:NetrwFullPath(dirname)]
4078 " call Decho(" lookup netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."]=".bufnum,'~'.expand("<slnum>"))
4079 if !bufexists(bufnum)
4080 call remove(s:netrwbuf,s:NetrwFullPath(dirname))
4081 let bufnum= -1
4082 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02004083
Bram Moolenaar446cb832008-06-24 21:56:24 +00004084 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01004085 " call Decho(" lookup netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."] not a key",'~'.expand("<slnum>"))
4086 let bufnum= -1
Bram Moolenaar446cb832008-06-24 21:56:24 +00004087 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01004088 " call Decho(" bufnum#".bufnum,'~'.expand("<slnum>"))
Bram Moolenaar85850f32019-07-19 22:05:51 +02004089
Bram Moolenaar71badf92023-04-22 22:40:14 +01004090 " highjack the current buffer
Bram Moolenaar89a9c152021-08-29 21:55:35 +02004091 " IF the buffer already has the desired name
4092 " AND it is empty
4093 let curbuf = bufname("%")
4094 if curbuf == '.'
Luca Saccarolac363ca12024-12-19 20:16:18 +01004095 let curbuf = getcwd()
Bram Moolenaar89a9c152021-08-29 21:55:35 +02004096 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01004097 " call Dredir("ls!","NetrwGetFile (renamed buffer back to remote filename<".rfile."> : expand(%)<".expand("%").">)")
4098 " call Decho("deciding if netrw may highjack the current buffer#".bufnr("%")."<".curbuf.">",'~'.expand("<slnum>"))
4099 " call Decho("..dirname<".dirname."> IF dirname == bufname",'~'.expand("<slnum>"))
4100 " call Decho("..curbuf<".curbuf.">",'~'.expand("<slnum>"))
4101 " call Decho("..line($)=".line("$")." AND this is 1",'~'.expand("<slnum>"))
4102 " call Decho("..getline(%)<".getline("%")."> AND this line is empty",'~'.expand("<slnum>"))
Bram Moolenaar89a9c152021-08-29 21:55:35 +02004103 if dirname == curbuf && line("$") == 1 && getline("%") == ""
Luca Saccarolac363ca12024-12-19 20:16:18 +01004104 " call Dret("s:NetrwGetBuffer 0<cleared buffer> : highjacking buffer#".bufnr("%"))
4105 return 0
Bram Moolenaar89a9c152021-08-29 21:55:35 +02004106 else " DEBUG
Luca Saccarolac363ca12024-12-19 20:16:18 +01004107 " call Decho("..did NOT highjack buffer",'~'.expand("<slnum>"))
Bram Moolenaar85850f32019-07-19 22:05:51 +02004108 endif
Bram Moolenaar89a9c152021-08-29 21:55:35 +02004109 " 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 +00004110
4111 " get enew buffer and name it -or- re-use buffer {{{3
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +02004112 if bufnum < 0 " get enew buffer and name it
Luca Saccarolac363ca12024-12-19 20:16:18 +01004113 " call Decho("--get enew buffer and name it (bufnum#".bufnum."<0 OR bufexists(".bufnum.")=".bufexists(bufnum)."==0)",'~'.expand("<slnum>"))
4114 call s:NetrwEnew(dirname)
4115 " call Decho(" got enew buffer#".bufnr("%")." (altbuf<".expand("#").">)",'~'.expand("<slnum>"))
4116 " name the buffer
4117 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4118 " Got enew buffer; transform into a NetrwTreeListing
4119 " call Decho("--transform enew buffer#".bufnr("%")." into a NetrwTreeListing --",'~'.expand("<slnum>"))
4120 let w:netrw_treebufnr = bufnr("%")
4121 call s:NetrwBufRename("NetrwTreeListing")
4122 if g:netrw_use_noswf
4123 setl nobl bt=nofile noswf
4124 else
4125 setl nobl bt=nofile
4126 endif
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 nnoremap <silent> <buffer> ][ :sil call <SID>TreeListMove('][')<cr>
shane.xb.qianc673b802024-12-20 19:36:40 +01004131 " call Decho(" tree listing bufnr=".w:netrw_treebufnr,'~'.expand("<slnum>"))
Bram Moolenaare0fa3742016-02-20 15:47:01 +01004132 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01004133 call s:NetrwBufRename(dirname)
4134 " enter the new buffer into the s:netrwbuf dictionary
4135 let s:netrwbuf[s:NetrwFullPath(dirname)]= bufnr("%")
4136 " call Decho("update netrwbuf dictionary: s:netrwbuf[".s:NetrwFullPath(dirname)."]=".bufnr("%"),'~'.expand("<slnum>"))
4137 " call Decho("netrwbuf dictionary=".string(s:netrwbuf),'~'.expand("<slnum>"))
Bram Moolenaare0fa3742016-02-20 15:47:01 +01004138 endif
shane.xb.qianc673b802024-12-20 19:36:40 +01004139 " call Decho(" named enew buffer#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00004140
4141 else " Re-use the buffer
Luca Saccarolac363ca12024-12-19 20:16:18 +01004142 " call Decho("--re-use buffer#".bufnum." (bufnum#".bufnum.">=0 AND bufexists(".bufnum.")=".bufexists(bufnum)."!=0)",'~'.expand("<slnum>"))
4143 " ignore all events
4144 let eikeep= &ei
4145 setl ei=all
Bram Moolenaar71badf92023-04-22 22:40:14 +01004146
Luca Saccarolac363ca12024-12-19 20:16:18 +01004147 if &ft == "netrw"
4148 " call Decho("buffer type is netrw; not using keepalt with b ".bufnum)
4149 exe "sil! NetrwKeepj noswapfile b ".bufnum
shane.xb.qianc673b802024-12-20 19:36:40 +01004150 " call Dredir("ls!","one")
Luca Saccarolac363ca12024-12-19 20:16:18 +01004151 else
4152 " call Decho("buffer type is not netrw; using keepalt with b ".bufnum)
4153 call s:NetrwEditBuf(bufnum)
4154 " call Dredir("ls!","two")
4155 endif
4156 " call Decho(" line($)=".line("$"),'~'.expand("<slnum>"))
4157 if bufname("%") == '.'
4158 call s:NetrwBufRename(getcwd())
4159 endif
Bram Moolenaar71badf92023-04-22 22:40:14 +01004160
Luca Saccarolac363ca12024-12-19 20:16:18 +01004161 " restore ei
4162 let &ei= eikeep
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01004163
Luca Saccarolac363ca12024-12-19 20:16:18 +01004164 if line("$") <= 1 && getline(1) == ""
4165 " empty buffer
4166 NetrwKeepj call s:NetrwListSettings(a:islocal)
4167 " 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>"))
4168 " call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4169 " call Dret("s:NetrwGetBuffer 0<buffer empty> : re-using buffer#".bufnr("%").", but its empty, so refresh it")
4170 return 0
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01004171
Luca Saccarolac363ca12024-12-19 20:16:18 +01004172 elseif g:netrw_fastbrowse == 0 || (a:islocal && g:netrw_fastbrowse == 1)
4173 " call Decho("g:netrw_fastbrowse=".g:netrw_fastbrowse." a:islocal=".a:islocal.": clear buffer",'~'.expand("<slnum>"))
4174 NetrwKeepj call s:NetrwListSettings(a:islocal)
4175 sil NetrwKeepj %d _
4176 " 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>"))
4177 " call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4178 " call Dret("s:NetrwGetBuffer 0<cleared buffer> : re-using buffer#".bufnr("%").", but refreshing due to g:netrw_fastbrowse=".g:netrw_fastbrowse)
4179 return 0
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01004180
Luca Saccarolac363ca12024-12-19 20:16:18 +01004181 elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
4182 " call Decho("--re-use tree listing--",'~'.expand("<slnum>"))
4183 " call Decho(" clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
4184 setl ma
4185 sil NetrwKeepj %d _
4186 NetrwKeepj call s:NetrwListSettings(a:islocal)
4187 " 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>"))
4188 " call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4189 " call Dret("s:NetrwGetBuffer 0<cleared buffer> : re-using buffer#".bufnr("%").", but treelist mode always needs a refresh")
4190 return 0
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01004191
Luca Saccarolac363ca12024-12-19 20:16:18 +01004192 else
4193 " call Decho("settings buf#".bufnr("%")."<".bufname("%").">: ".((&l:ma == 0)? "no" : "")."ma ".((&l:mod == 0)? "no" : "")."mod ".((&l:bl == 0)? "no" : "")."bl ".((&l:ro == 0)? "no" : "")."ro fo=".&l:fo,'~'.expand("<slnum>"))
4194 " call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4195 " call Dret("s:NetrwGetBuffer 1<buffer not cleared>")
4196 return 1
4197 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00004198 endif
4199
4200 " do netrw settings: make this buffer not-a-file, modifiable, not line-numbered, etc {{{3
4201 " fastbrowse Local Remote Hiding a buffer implies it may be re-used (fast)
4202 " slow 0 D D Deleting a buffer implies it will not be re-used (slow)
4203 " med 1 D H
4204 " fast 2 H H
Luca Saccarolac363ca12024-12-19 20:16:18 +01004205 " 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 +00004206 let fname= expand("%")
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01004207 NetrwKeepj call s:NetrwListSettings(a:islocal)
Bram Moolenaar85850f32019-07-19 22:05:51 +02004208 call s:NetrwBufRename(fname)
Bram Moolenaar446cb832008-06-24 21:56:24 +00004209
4210 " delete all lines from buffer {{{3
Luca Saccarolac363ca12024-12-19 20:16:18 +01004211 " call Decho("--delete all lines from buffer--",'~'.expand("<slnum>"))
4212 " call Decho(" clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
Bram Moolenaara0f849e2015-10-30 14:37:44 +01004213 sil! keepalt NetrwKeepj %d _
Bram Moolenaar446cb832008-06-24 21:56:24 +00004214
Luca Saccarolac363ca12024-12-19 20:16:18 +01004215 " 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>"))
4216 " call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
4217 " call Dret("s:NetrwGetBuffer 0<cleared buffer>")
Bram Moolenaar446cb832008-06-24 21:56:24 +00004218 return 0
4219endfun
4220
4221" ---------------------------------------------------------------------
4222" s:NetrwGetcwd: get the current directory. {{{2
4223" Change backslashes to forward slashes, if any.
4224" If doesc is true, escape certain troublesome characters
4225fun! s:NetrwGetcwd(doesc)
Luca Saccarolac363ca12024-12-19 20:16:18 +01004226 " call Dfunc("NetrwGetcwd(doesc=".a:doesc.")")
Bram Moolenaar446cb832008-06-24 21:56:24 +00004227 let curdir= substitute(getcwd(),'\\','/','ge')
4228 if curdir !~ '[\/]$'
Luca Saccarolac363ca12024-12-19 20:16:18 +01004229 let curdir= curdir.'/'
Bram Moolenaar446cb832008-06-24 21:56:24 +00004230 endif
4231 if a:doesc
Luca Saccarolac363ca12024-12-19 20:16:18 +01004232 let curdir= fnameescape(curdir)
Bram Moolenaar446cb832008-06-24 21:56:24 +00004233 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01004234 " call Dret("NetrwGetcwd <".curdir.">")
Bram Moolenaar446cb832008-06-24 21:56:24 +00004235 return curdir
4236endfun
4237
4238" ---------------------------------------------------------------------
4239" s:NetrwGetWord: it gets the directory/file named under the cursor {{{2
4240fun! s:NetrwGetWord()
Luca Saccarolac363ca12024-12-19 20:16:18 +01004241 " call Dfunc("s:NetrwGetWord() liststyle=".s:ShowStyle()." virtcol=".virtcol("."))
4242 " 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 +01004243 let keepsol= &l:sol
4244 setl nosol
4245
Bram Moolenaar446cb832008-06-24 21:56:24 +00004246 call s:UseBufWinVars()
4247
4248 " insure that w:netrw_liststyle is set up
4249 if !exists("w:netrw_liststyle")
Luca Saccarolac363ca12024-12-19 20:16:18 +01004250 if exists("g:netrw_liststyle")
4251 let w:netrw_liststyle= g:netrw_liststyle
4252 else
4253 let w:netrw_liststyle= s:THINLIST
4254 endif
4255 " call Decho("w:netrw_liststyle=".w:netrw_liststyle,'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00004256 endif
4257
4258 if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt
Luca Saccarolac363ca12024-12-19 20:16:18 +01004259 " Active Banner support
4260 " call Decho("active banner handling",'~'.expand("<slnum>"))
4261 NetrwKeepj norm! 0
4262 let dirname= "./"
4263 let curline= getline('.')
Bram Moolenaar446cb832008-06-24 21:56:24 +00004264
Luca Saccarolac363ca12024-12-19 20:16:18 +01004265 if curline =~# '"\s*Sorted by\s'
4266 NetrwKeepj norm! "_s
4267 let s:netrw_skipbrowse= 1
4268 echo 'Pressing "s" also works'
Bram Moolenaar446cb832008-06-24 21:56:24 +00004269
Luca Saccarolac363ca12024-12-19 20:16:18 +01004270 elseif curline =~# '"\s*Sort sequence:'
4271 let s:netrw_skipbrowse= 1
4272 echo 'Press "S" to edit sorting sequence'
Bram Moolenaar446cb832008-06-24 21:56:24 +00004273
Luca Saccarolac363ca12024-12-19 20:16:18 +01004274 elseif curline =~# '"\s*Quick Help:'
4275 NetrwKeepj norm! ?
4276 let s:netrw_skipbrowse= 1
Bram Moolenaar446cb832008-06-24 21:56:24 +00004277
Luca Saccarolac363ca12024-12-19 20:16:18 +01004278 elseif curline =~# '"\s*\%(Hiding\|Showing\):'
4279 NetrwKeepj norm! a
4280 let s:netrw_skipbrowse= 1
4281 echo 'Pressing "a" also works'
Bram Moolenaar446cb832008-06-24 21:56:24 +00004282
Luca Saccarolac363ca12024-12-19 20:16:18 +01004283 elseif line("$") > w:netrw_bannercnt
4284 exe 'sil NetrwKeepj '.w:netrw_bannercnt
4285 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00004286
4287 elseif w:netrw_liststyle == s:THINLIST
Luca Saccarolac363ca12024-12-19 20:16:18 +01004288 " call Decho("thin column handling",'~'.expand("<slnum>"))
4289 NetrwKeepj norm! 0
4290 let dirname= substitute(getline('.'),'\t -->.*$','','')
Bram Moolenaar446cb832008-06-24 21:56:24 +00004291
4292 elseif w:netrw_liststyle == s:LONGLIST
Luca Saccarolac363ca12024-12-19 20:16:18 +01004293 " call Decho("long column handling",'~'.expand("<slnum>"))
4294 NetrwKeepj norm! 0
4295 let dirname= substitute(getline('.'),'^\(\%(\S\+ \)*\S\+\).\{-}$','\1','e')
Bram Moolenaar446cb832008-06-24 21:56:24 +00004296
Bram Moolenaare0fa3742016-02-20 15:47:01 +01004297 elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
Luca Saccarolac363ca12024-12-19 20:16:18 +01004298 " call Decho("treelist handling",'~'.expand("<slnum>"))
4299 let dirname= substitute(getline('.'),'^\('.s:treedepthstring.'\)*','','e')
4300 let dirname= substitute(dirname,'\t -->.*$','','')
Bram Moolenaar446cb832008-06-24 21:56:24 +00004301
4302 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01004303 " call Decho("obtain word from wide listing",'~'.expand("<slnum>"))
4304 let dirname= getline('.')
Bram Moolenaar446cb832008-06-24 21:56:24 +00004305
Luca Saccarolac363ca12024-12-19 20:16:18 +01004306 if !exists("b:netrw_cpf")
4307 let b:netrw_cpf= 0
4308 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/^./if virtcol("$") > b:netrw_cpf|let b:netrw_cpf= virtcol("$")|endif'
shane.xb.qianc673b802024-12-20 19:36:40 +01004309 call histdel("/",-1)
4310 " "call Decho("computed cpf=".b:netrw_cpf,'~'.expand("<slnum>"))
4311 endif
4312
4313 " call Decho("buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
4314 let filestart = (virtcol(".")/b:netrw_cpf)*b:netrw_cpf
4315 " call Decho("filestart= ([virtcol=".virtcol(".")."]/[b:netrw_cpf=".b:netrw_cpf."])*b:netrw_cpf=".filestart." bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
4316 " call Decho("1: dirname<".dirname.">",'~'.expand("<slnum>"))
4317 if filestart == 0
4318 NetrwKeepj norm! 0ma
4319 else
4320 call cursor(line("."),filestart+1)
4321 NetrwKeepj norm! ma
4322 endif
4323
4324 let dict={}
4325 " save the unnamed register and register 0-9 and a
4326 let dict.a=[getreg('a'), getregtype('a')]
4327 for i in range(0, 9)
4328 let dict[i] = [getreg(i), getregtype(i)]
4329 endfor
4330 let dict.unnamed = [getreg(''), getregtype('')]
4331
4332 let eofname= filestart + b:netrw_cpf + 1
4333 if eofname <= col("$")
4334 call cursor(line("."),filestart+b:netrw_cpf+1)
4335 NetrwKeepj norm! "ay`a
4336 else
4337 NetrwKeepj norm! "ay$
4338 endif
4339
4340 let dirname = @a
4341 call s:RestoreRegister(dict)
4342
4343 " call Decho("2: dirname<".dirname.">",'~'.expand("<slnum>"))
4344 let dirname= substitute(dirname,'\s\+$','','e')
4345 " call Decho("3: dirname<".dirname.">",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00004346 endif
4347
shane.xb.qianc673b802024-12-20 19:36:40 +01004348 " symlinks are indicated by a trailing "@". Remove it before further processing.
4349 let dirname= substitute(dirname,"@$","","")
Bram Moolenaar446cb832008-06-24 21:56:24 +00004350
shane.xb.qianc673b802024-12-20 19:36:40 +01004351 " executables are indicated by a trailing "*". Remove it before further processing.
4352 let dirname= substitute(dirname,"\*$","","")
Bram Moolenaar446cb832008-06-24 21:56:24 +00004353
shane.xb.qianc673b802024-12-20 19:36:40 +01004354 let &l:sol= keepsol
Luca Saccarolac363ca12024-12-19 20:16:18 +01004355
shane.xb.qianc673b802024-12-20 19:36:40 +01004356 " call Dret("s:NetrwGetWord <".dirname.">")
4357 return dirname
Bram Moolenaar446cb832008-06-24 21:56:24 +00004358endfun
4359
4360" ---------------------------------------------------------------------
Bram Moolenaar85850f32019-07-19 22:05:51 +02004361" s:NetrwListSettings: make standard settings for making a netrw listing {{{2
4362" g:netrw_bufsettings will be used after the listing is produced.
4363" Called by s:NetrwGetBuffer()
Bram Moolenaar446cb832008-06-24 21:56:24 +00004364fun! s:NetrwListSettings(islocal)
Luca Saccarolac363ca12024-12-19 20:16:18 +01004365 " call Dfunc("s:NetrwListSettings(islocal=".a:islocal.")")
4366 " 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 +00004367 let fname= bufname("%")
Luca Saccarolac363ca12024-12-19 20:16:18 +01004368 " " call Decho("setl bt=nofile nobl ma nonu nowrap noro nornu",'~'.expand("<slnum>"))
Bram Moolenaar85850f32019-07-19 22:05:51 +02004369 " nobl noma nomod nonu noma nowrap ro nornu (std g:netrw_bufsettings)
4370 setl bt=nofile nobl ma nonu nowrap noro nornu
4371 call s:NetrwBufRename(fname)
Bram Moolenaar446cb832008-06-24 21:56:24 +00004372 if g:netrw_use_noswf
Luca Saccarolac363ca12024-12-19 20:16:18 +01004373 setl noswf
Bram Moolenaar446cb832008-06-24 21:56:24 +00004374 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01004375 " call Dredir("ls!","s:NetrwListSettings")
4376 " call Decho("exe setl ts=".(g:netrw_maxfilenamelen+1),'~'.expand("<slnum>"))
Bram Moolenaar97d62492012-11-15 21:28:22 +01004377 exe "setl ts=".(g:netrw_maxfilenamelen+1)
Bram Moolenaarff034192013-04-24 18:51:19 +02004378 setl isk+=.,~,-
Bram Moolenaar446cb832008-06-24 21:56:24 +00004379 if g:netrw_fastbrowse > a:islocal
Luca Saccarolac363ca12024-12-19 20:16:18 +01004380 setl bh=hide
Bram Moolenaar446cb832008-06-24 21:56:24 +00004381 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01004382 setl bh=delete
Bram Moolenaar446cb832008-06-24 21:56:24 +00004383 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01004384 " 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>"))
4385 " call Dret("s:NetrwListSettings")
Bram Moolenaar446cb832008-06-24 21:56:24 +00004386endfun
4387
4388" ---------------------------------------------------------------------
Bram Moolenaar85850f32019-07-19 22:05:51 +02004389" s:NetrwListStyle: change list style (thin - long - wide - tree) {{{2
Bram Moolenaar446cb832008-06-24 21:56:24 +00004390" islocal=0: remote browsing
4391" =1: local browsing
4392fun! s:NetrwListStyle(islocal)
Bram Moolenaar97d62492012-11-15 21:28:22 +01004393 let ykeep = @@
Bram Moolenaar446cb832008-06-24 21:56:24 +00004394 let fname = s:NetrwGetWord()
4395 if !exists("w:netrw_liststyle")|let w:netrw_liststyle= g:netrw_liststyle|endif
Bram Moolenaare0fa3742016-02-20 15:47:01 +01004396 let svpos = winsaveview()
Bram Moolenaar446cb832008-06-24 21:56:24 +00004397 let w:netrw_liststyle = (w:netrw_liststyle + 1) % s:MAXLIST
Bram Moolenaar446cb832008-06-24 21:56:24 +00004398
Bram Moolenaar85850f32019-07-19 22:05:51 +02004399 " repoint t:netrw_lexbufnr if appropriate
4400 if exists("t:netrw_lexbufnr") && bufnr("%") == t:netrw_lexbufnr
Luca Saccarolac363ca12024-12-19 20:16:18 +01004401 let repointlexbufnr= 1
Bram Moolenaar85850f32019-07-19 22:05:51 +02004402 endif
4403
Bram Moolenaar446cb832008-06-24 21:56:24 +00004404 if w:netrw_liststyle == s:THINLIST
Luca Saccarolac363ca12024-12-19 20:16:18 +01004405 " use one column listing
4406 let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
Bram Moolenaar446cb832008-06-24 21:56:24 +00004407
4408 elseif w:netrw_liststyle == s:LONGLIST
Luca Saccarolac363ca12024-12-19 20:16:18 +01004409 " use long list
4410 let g:netrw_list_cmd = g:netrw_list_cmd." -l"
Bram Moolenaar446cb832008-06-24 21:56:24 +00004411
4412 elseif w:netrw_liststyle == s:WIDELIST
Luca Saccarolac363ca12024-12-19 20:16:18 +01004413 " give wide list
4414 let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
Bram Moolenaar446cb832008-06-24 21:56:24 +00004415
Bram Moolenaare0fa3742016-02-20 15:47:01 +01004416 elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
Luca Saccarolac363ca12024-12-19 20:16:18 +01004417 let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
Bram Moolenaar446cb832008-06-24 21:56:24 +00004418
4419 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01004420 NetrwKeepj call netrw#ErrorMsg(s:WARNING,"bad value for g:netrw_liststyle (=".w:netrw_liststyle.")",46)
4421 let g:netrw_liststyle = s:THINLIST
4422 let w:netrw_liststyle = g:netrw_liststyle
4423 let g:netrw_list_cmd = substitute(g:netrw_list_cmd,' -l','','ge')
Bram Moolenaar446cb832008-06-24 21:56:24 +00004424 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02004425 setl ma noro
Bram Moolenaar446cb832008-06-24 21:56:24 +00004426
4427 " clear buffer - this will cause NetrwBrowse/LocalBrowseCheck to do a refresh
Bram Moolenaara0f849e2015-10-30 14:37:44 +01004428 sil! NetrwKeepj %d _
Bram Moolenaar00a927d2010-05-14 23:24:24 +02004429 " following prevents tree listing buffer from being marked "modified"
Bram Moolenaar5b435d62012-04-05 17:33:26 +02004430 setl nomod
Bram Moolenaar446cb832008-06-24 21:56:24 +00004431
4432 " refresh the listing
Tom Benham64a536d2024-11-07 21:15:03 +01004433 NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
Bram Moolenaar89a9c152021-08-29 21:55:35 +02004434 NetrwKeepj call s:NetrwCursor(0)
Bram Moolenaar446cb832008-06-24 21:56:24 +00004435
Bram Moolenaar85850f32019-07-19 22:05:51 +02004436 " repoint t:netrw_lexbufnr if appropriate
4437 if exists("repointlexbufnr")
Luca Saccarolac363ca12024-12-19 20:16:18 +01004438 let t:netrw_lexbufnr= bufnr("%")
Bram Moolenaar85850f32019-07-19 22:05:51 +02004439 endif
4440
Bram Moolenaar13600302014-05-22 18:26:40 +02004441 " restore position; keep cursor on the filename
Luca Saccarolac363ca12024-12-19 20:16:18 +01004442 " call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
Bram Moolenaare0fa3742016-02-20 15:47:01 +01004443 NetrwKeepj call winrestview(svpos)
Bram Moolenaar97d62492012-11-15 21:28:22 +01004444 let @@= ykeep
Bram Moolenaar446cb832008-06-24 21:56:24 +00004445
Bram Moolenaar446cb832008-06-24 21:56:24 +00004446endfun
4447
4448" ---------------------------------------------------------------------
Bram Moolenaar5c736222010-01-06 20:54:52 +01004449" s:NetrwBannerCtrl: toggles the display of the banner {{{2
4450fun! s:NetrwBannerCtrl(islocal)
Bram Moolenaar97d62492012-11-15 21:28:22 +01004451 let ykeep= @@
Bram Moolenaar5c736222010-01-06 20:54:52 +01004452 " toggle the banner (enable/suppress)
4453 let g:netrw_banner= !g:netrw_banner
4454
4455 " refresh the listing
Bram Moolenaare0fa3742016-02-20 15:47:01 +01004456 let svpos= winsaveview()
Tom Benham64a536d2024-11-07 21:15:03 +01004457 call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
Bram Moolenaar5c736222010-01-06 20:54:52 +01004458
4459 " keep cursor on the filename
Bram Moolenaar85850f32019-07-19 22:05:51 +02004460 if g:netrw_banner && exists("w:netrw_bannercnt") && line(".") >= w:netrw_bannercnt
Luca Saccarolac363ca12024-12-19 20:16:18 +01004461 let fname= s:NetrwGetWord()
4462 sil NetrwKeepj $
4463 let result= search('\%(^\%(|\+\s\)\=\|\s\{2,}\)\zs'.escape(fname,'.\[]*$^').'\%(\s\{2,}\|$\)','bc')
4464 " " call Decho("search result=".result." w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'N/A'),'~'.expand("<slnum>"))
4465 if result <= 0 && exists("w:netrw_bannercnt")
4466 exe "NetrwKeepj ".w:netrw_bannercnt
4467 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +01004468 endif
Bram Moolenaar97d62492012-11-15 21:28:22 +01004469 let @@= ykeep
Luca Saccarolac363ca12024-12-19 20:16:18 +01004470 " call Dret("s:NetrwBannerCtrl : g:netrw_banner=".g:netrw_banner)
Bram Moolenaar5c736222010-01-06 20:54:52 +01004471endfun
4472
4473" ---------------------------------------------------------------------
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01004474" s:NetrwBookmark: supports :NetrwMB[!] [file]s {{{2
4475"
4476" No bang: enters files/directories into Netrw's bookmark system
4477" No argument and in netrw buffer:
4478" if there are marked files: bookmark marked files
4479" otherwise : bookmark file/directory under cursor
4480" No argument and not in netrw buffer: bookmarks current open file
4481" Has arguments: globs them individually and bookmarks them
4482"
4483" With bang: deletes files/directories from Netrw's bookmark system
4484fun! s:NetrwBookmark(del,...)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01004485 if a:0 == 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01004486 if &ft == "netrw"
4487 let curbufnr = bufnr("%")
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01004488
Luca Saccarolac363ca12024-12-19 20:16:18 +01004489 if exists("s:netrwmarkfilelist_{curbufnr}")
4490 " for every filename in the marked list
4491 let svpos = winsaveview()
4492 let islocal= expand("%") !~ '^\a\{3,}://'
4493 for fname in s:netrwmarkfilelist_{curbufnr}
4494 if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif
4495 endfor
4496 let curdir = exists("b:netrw_curdir")? b:netrw_curdir : getcwd()
4497 call s:NetrwUnmarkList(curbufnr,curdir)
4498 NetrwKeepj call s:NetrwRefresh(islocal,s:NetrwBrowseChgDir(islocal,'./',0))
4499 NetrwKeepj call winrestview(svpos)
4500 else
4501 let fname= s:NetrwGetWord()
4502 if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif
4503 endif
4504
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01004505 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01004506 " bookmark currently open file
4507 let fname= expand("%")
4508 if a:del|call s:DeleteBookmark(fname)|else|call s:MakeBookmark(fname)|endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01004509 endif
4510
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01004511 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01004512 " bookmark specified files
4513 " attempts to infer if working remote or local
4514 " by deciding if the current file begins with an url
4515 " Globbing cannot be done remotely.
4516 let islocal= expand("%") !~ '^\a\{3,}://'
4517 let i = 1
4518 while i <= a:0
4519 if islocal
4520 if v:version > 704 || (v:version == 704 && has("patch656"))
4521 let mbfiles= glob(fnameescape(a:{i}),0,1,1)
4522 else
4523 let mbfiles= glob(fnameescape(a:{i}),0,1)
4524 endif
4525 else
4526 let mbfiles= [a:{i}]
4527 endif
4528 for mbfile in mbfiles
4529 if a:del|call s:DeleteBookmark(mbfile)|else|call s:MakeBookmark(mbfile)|endif
4530 endfor
4531 let i= i + 1
4532 endwhile
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01004533 endif
4534
4535 " update the menu
4536 call s:NetrwBookmarkMenu()
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01004537endfun
4538
4539" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +00004540" s:NetrwBookmarkMenu: Uses menu priorities {{{2
4541" .2.[cnt] for bookmarks, and
4542" .3.[cnt] for history
4543" (see s:NetrwMenu())
4544fun! s:NetrwBookmarkMenu()
Bram Moolenaar9964e462007-05-05 17:54:07 +00004545 if !exists("s:netrw_menucnt")
Luca Saccarolac363ca12024-12-19 20:16:18 +01004546 return
Bram Moolenaar9964e462007-05-05 17:54:07 +00004547 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01004548 " call Dfunc("NetrwBookmarkMenu() histcnt=".g:netrw_dirhistcnt." menucnt=".s:netrw_menucnt)
Bram Moolenaar446cb832008-06-24 21:56:24 +00004549
4550 " the following test assures that gvim is running, has menus available, and has menus enabled.
Bram Moolenaaradc21822011-04-01 18:03:16 +02004551 if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
Luca Saccarolac363ca12024-12-19 20:16:18 +01004552 if exists("g:NetrwTopLvlMenu")
4553 " call Decho("removing ".g:NetrwTopLvlMenu."Bookmarks menu item(s)",'~'.expand("<slnum>"))
4554 exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Bookmarks'
4555 exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Delete'
4556 endif
4557 if !exists("s:netrw_initbookhist")
4558 call s:NetrwBookHistRead()
4559 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +00004560
Luca Saccarolac363ca12024-12-19 20:16:18 +01004561 " show bookmarked places
4562 if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != [] && g:netrw_dirhistmax > 0
4563 let cnt= 1
4564 for bmd in g:netrw_bookmarklist
4565 " call Decho('sil! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmark.'.bmd.' :e '.bmd,'~'.expand("<slnum>"))
4566 let bmd= escape(bmd,g:netrw_menu_escape)
Bram Moolenaar5c736222010-01-06 20:54:52 +01004567
Luca Saccarolac363ca12024-12-19 20:16:18 +01004568 " show bookmarks for goto menu
4569 exe 'sil! menu '.g:NetrwMenuPriority.".2.".cnt." ".g:NetrwTopLvlMenu.'Bookmarks.'.bmd.' :e '.bmd."\<cr>"
Bram Moolenaar5c736222010-01-06 20:54:52 +01004570
Luca Saccarolac363ca12024-12-19 20:16:18 +01004571 " show bookmarks for deletion menu
4572 exe 'sil! menu '.g:NetrwMenuPriority.".8.2.".cnt." ".g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Delete.'.bmd.' '.cnt."mB"
4573 let cnt= cnt + 1
4574 endfor
Bram Moolenaar5c736222010-01-06 20:54:52 +01004575
Luca Saccarolac363ca12024-12-19 20:16:18 +01004576 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +00004577
Luca Saccarolac363ca12024-12-19 20:16:18 +01004578 " show directory browsing history
4579 if g:netrw_dirhistmax > 0
4580 let cnt = g:netrw_dirhistcnt
4581 let first = 1
4582 let histcnt = 0
4583 while ( first || cnt != g:netrw_dirhistcnt )
4584 let histcnt = histcnt + 1
4585 let priority = g:netrw_dirhistcnt + histcnt
4586 if exists("g:netrw_dirhist_{cnt}")
4587 let histdir= escape(g:netrw_dirhist_{cnt},g:netrw_menu_escape)
4588 " call Decho('sil! menu '.g:NetrwMenuPriority.".3.".priority." ".g:NetrwTopLvlMenu.'History.'.histdir.' :e '.histdir,'~'.expand("<slnum>"))
4589 exe 'sil! menu '.g:NetrwMenuPriority.".3.".priority." ".g:NetrwTopLvlMenu.'History.'.histdir.' :e '.histdir."\<cr>"
4590 endif
4591 let first = 0
4592 let cnt = ( cnt - 1 ) % g:netrw_dirhistmax
4593 if cnt < 0
4594 let cnt= cnt + g:netrw_dirhistmax
4595 endif
4596 endwhile
4597 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +01004598
Bram Moolenaar9964e462007-05-05 17:54:07 +00004599 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01004600 " call Dret("NetrwBookmarkMenu")
Bram Moolenaar9964e462007-05-05 17:54:07 +00004601endfun
4602
4603" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +00004604" s:NetrwBrowseChgDir: constructs a new directory based on the current {{{2
4605" directory and a new directory name. Also, if the
4606" "new directory name" is actually a file,
4607" NetrwBrowseChgDir() edits the file.
Tom Benham64a536d2024-11-07 21:15:03 +01004608" cursor=0: newdir is relative to b:netrw_curdir
4609" =1: newdir is relative to the path to the word under the cursor in
4610" tree view
4611fun! s:NetrwBrowseChgDir(islocal,newdir,cursor,...)
Bram Moolenaar97d62492012-11-15 21:28:22 +01004612 let ykeep= @@
Bram Moolenaar446cb832008-06-24 21:56:24 +00004613 if !exists("b:netrw_curdir")
Luca Saccarolac363ca12024-12-19 20:16:18 +01004614 " Don't try to change-directory: this can happen, for example, when netrw#ErrorMsg has been called
4615 " and the current window is the NetrwMessage window.
4616 let @@= ykeep
4617 return
Bram Moolenaar9964e462007-05-05 17:54:07 +00004618 endif
4619
Bram Moolenaar89a9c152021-08-29 21:55:35 +02004620 " NetrwBrowseChgDir; save options and initialize {{{3
Bram Moolenaar85850f32019-07-19 22:05:51 +02004621 call s:SavePosn(s:netrw_posn)
4622 NetrwKeepj call s:NetrwOptionsSave("s:")
4623 NetrwKeepj call s:NetrwOptionsSafe(a:islocal)
Tom Benham64a536d2024-11-07 21:15:03 +01004624
4625 let newdir = a:newdir
4626 if a:cursor && exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treetop")
Luca Saccarolac363ca12024-12-19 20:16:18 +01004627 " dirname is the path to the word under the cursor
4628 let dirname = s:NetrwTreePath(w:netrw_treetop)
4629 " newdir resolves to a directory and points to a directory in dirname
4630 " /tmp/test/folder_symlink/ -> /tmp/test/original_folder/
4631 if a:islocal && fnamemodify(dirname, ':t') == newdir && isdirectory(resolve(dirname)) && resolve(dirname) == resolve(newdir)
4632 let dirname = fnamemodify(resolve(dirname), ':p:h:h')
4633 let newdir = fnamemodify(resolve(newdir), ':t')
4634 endif
4635 " Remove trailing "/"
4636 let dirname = substitute(dirname, "/$", "", "")
Tom Benham64a536d2024-11-07 21:15:03 +01004637
Luca Saccarolac363ca12024-12-19 20:16:18 +01004638 " If the word under the cursor is a directory (except for ../), NetrwTreePath
4639 " returns the full path, including the word under the cursor, remove it
4640 if newdir =~ "/$" && newdir != "../"
4641 let dirname = fnamemodify(dirname, ":h")
4642 endif
Bram Moolenaar00a927d2010-05-14 23:24:24 +02004643 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01004644 let dirname = b:netrw_curdir
Bram Moolenaar00a927d2010-05-14 23:24:24 +02004645 endif
Tom Benham64a536d2024-11-07 21:15:03 +01004646 if has("win32")
Luca Saccarolac363ca12024-12-19 20:16:18 +01004647 let dirname = substitute(dirname,'\\','/','ge')
Tom Benham64a536d2024-11-07 21:15:03 +01004648 endif
Bram Moolenaar00a927d2010-05-14 23:24:24 +02004649 let dolockout = 0
Bram Moolenaar13600302014-05-22 18:26:40 +02004650 let dorestore = 1
Bram Moolenaara6878372014-03-22 21:02:50 +01004651
4652 " ignore <cr>s when done in the banner
4653 if g:netrw_banner
Luca Saccarolac363ca12024-12-19 20:16:18 +01004654 if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt && line("$") >= w:netrw_bannercnt
4655 if getline(".") =~# 'Quick Help'
4656 let g:netrw_quickhelp= (g:netrw_quickhelp + 1)%len(s:QuickHelp)
4657 setl ma noro nowrap
4658 NetrwKeepj call setline(line('.'),'" Quick Help: <F1>:help '.s:QuickHelp[g:netrw_quickhelp])
4659 setl noma nomod nowrap
4660 NetrwKeepj call s:NetrwOptionsRestore("s:")
4661 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01004662 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01004663 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +00004664
Bram Moolenaar446cb832008-06-24 21:56:24 +00004665 " set up o/s-dependent directory recognition pattern
4666 if has("amiga")
Luca Saccarolac363ca12024-12-19 20:16:18 +01004667 let dirpat= '[\/:]$'
Bram Moolenaar9964e462007-05-05 17:54:07 +00004668 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01004669 let dirpat= '[\/]$'
Bram Moolenaar446cb832008-06-24 21:56:24 +00004670 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00004671
4672 if dirname !~ dirpat
Luca Saccarolac363ca12024-12-19 20:16:18 +01004673 " apparently vim is "recognizing" that it is in a directory and
4674 " is removing the trailing "/". Bad idea, so let's put it back.
4675 let dirname= dirname.'/'
Bram Moolenaar446cb832008-06-24 21:56:24 +00004676 endif
4677
Bram Moolenaara0f849e2015-10-30 14:37:44 +01004678 if newdir !~ dirpat && !(a:islocal && isdirectory(s:NetrwFile(s:ComposePath(dirname,newdir))))
Luca Saccarolac363ca12024-12-19 20:16:18 +01004679 " ------------------------------
4680 " NetrwBrowseChgDir: edit a file {{{3
4681 " ------------------------------
Bram Moolenaar5b435d62012-04-05 17:33:26 +02004682
Luca Saccarolac363ca12024-12-19 20:16:18 +01004683 " save position for benefit of Rexplore
4684 let s:rexposn_{bufnr("%")}= winsaveview()
Bram Moolenaara6878372014-03-22 21:02:50 +01004685
Luca Saccarolac363ca12024-12-19 20:16:18 +01004686 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict") && newdir !~ '^\(/\|\a:\)'
4687 if dirname =~ '/$'
4688 let dirname= dirname.newdir
4689 else
4690 let dirname= dirname."/".newdir
4691 endif
4692 elseif newdir =~ '^\(/\|\a:\)'
4693 let dirname= newdir
Bram Moolenaar446cb832008-06-24 21:56:24 +00004694 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01004695 let dirname= s:ComposePath(dirname,newdir)
Bram Moolenaar446cb832008-06-24 21:56:24 +00004696 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01004697 " this lets netrw#BrowseX avoid the edit
4698 if a:0 < 1
4699 NetrwKeepj call s:NetrwOptionsRestore("s:")
4700 let curdir= b:netrw_curdir
4701 if !exists("s:didsplit")
4702 if type(g:netrw_browse_split) == 3
4703 " open file in server
4704 " Note that g:netrw_browse_split is a List: [servername,tabnr,winnr]
4705 call s:NetrwServerEdit(a:islocal,dirname)
4706 return
Bram Moolenaar1d59aa12020-09-19 18:50:13 +02004707
Luca Saccarolac363ca12024-12-19 20:16:18 +01004708 elseif g:netrw_browse_split == 1
4709 " horizontally splitting the window first
4710 let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
4711 exe "keepalt ".(g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
4712 if !&ea
4713 keepalt wincmd _
4714 endif
4715 call s:SetRexDir(a:islocal,curdir)
4716
4717 elseif g:netrw_browse_split == 2
4718 " vertically splitting the window first
4719 let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
4720 exe "keepalt ".(g:netrw_alto? "top " : "bot ")."vert ".winsz."wincmd s"
4721 if !&ea
4722 keepalt wincmd |
4723 endif
4724 call s:SetRexDir(a:islocal,curdir)
4725
4726 elseif g:netrw_browse_split == 3
4727 " open file in new tab
4728 keepalt tabnew
4729 if !exists("b:netrw_curdir")
4730 let b:netrw_curdir= getcwd()
4731 endif
4732 call s:SetRexDir(a:islocal,curdir)
4733
4734 elseif g:netrw_browse_split == 4
4735 " act like "P" (ie. open previous window)
4736 if s:NetrwPrevWinOpen(2) == 3
4737 let @@= ykeep
4738 return
4739 endif
4740 call s:SetRexDir(a:islocal,curdir)
4741
4742 else
4743 " handling a file, didn't split, so remove menu
4744 call s:NetrwMenu(0)
4745 " optional change to window
4746 if g:netrw_chgwin >= 1
4747 if winnr("$")+1 == g:netrw_chgwin
4748 " if g:netrw_chgwin is set to one more than the last window, then
4749 " vertically split the last window to make that window available.
4750 let curwin= winnr()
4751 exe "NetrwKeepj keepalt ".winnr("$")."wincmd w"
4752 vs
4753 exe "NetrwKeepj keepalt ".g:netrw_chgwin."wincmd ".curwin
4754 endif
4755 exe "NetrwKeepj keepalt ".g:netrw_chgwin."wincmd w"
4756 endif
4757 call s:SetRexDir(a:islocal,curdir)
4758 endif
4759
Bram Moolenaar5c736222010-01-06 20:54:52 +01004760 endif
Bram Moolenaar1d59aa12020-09-19 18:50:13 +02004761
Luca Saccarolac363ca12024-12-19 20:16:18 +01004762 " the point where netrw actually edits the (local) file
4763 " if its local only: LocalBrowseCheck() doesn't edit a file, but NetrwBrowse() will
4764 " use keepalt to support :e # to return to a directory listing
4765 if !&mod
4766 " if e the new file would fail due to &mod, then don't change any of the flags
4767 let dolockout= 1
Bram Moolenaar5c736222010-01-06 20:54:52 +01004768 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01004769 if a:islocal
4770 " some like c-^ to return to the last edited file
4771 " others like c-^ to return to the netrw buffer
4772 " Apr 30, 2020: used to have e! here. That can cause loss of a modified file,
4773 " so emit error E37 instead.
4774 call s:NetrwEditFile("e","",dirname)
4775 call s:NetrwCursor(1)
4776 if &hidden || &bufhidden == "hide"
4777 " file came from vim's hidden storage. Don't "restore" options with it.
4778 let dorestore= 0
4779 endif
4780 else
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +02004781 endif
Bram Moolenaar1d59aa12020-09-19 18:50:13 +02004782
Luca Saccarolac363ca12024-12-19 20:16:18 +01004783 " handle g:Netrw_funcref -- call external-to-netrw functions
4784 " This code will handle g:Netrw_funcref as an individual function reference
4785 " or as a list of function references. It will ignore anything that's not
4786 " a function reference. See :help Funcref for information about function references.
4787 if exists("g:Netrw_funcref")
4788 if type(g:Netrw_funcref) == 2
4789 NetrwKeepj call g:Netrw_funcref()
4790 elseif type(g:Netrw_funcref) == 3
4791 for Fncref in g:Netrw_funcref
4792 if type(Fncref) == 2
4793 NetrwKeepj call Fncref()
4794 endif
4795 endfor
4796 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +00004797 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +00004798 endif
Bram Moolenaar5ac3b1a2010-07-27 22:50:36 +02004799
Bram Moolenaar446cb832008-06-24 21:56:24 +00004800 elseif newdir =~ '^/'
Luca Saccarolac363ca12024-12-19 20:16:18 +01004801 " ----------------------------------------------------
4802 " NetrwBrowseChgDir: just go to the new directory spec {{{3
4803 " ----------------------------------------------------
4804 let dirname = newdir
4805 NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4806 NetrwKeepj call s:NetrwOptionsRestore("s:")
4807 norm! m`
Bram Moolenaar446cb832008-06-24 21:56:24 +00004808
4809 elseif newdir == './'
Luca Saccarolac363ca12024-12-19 20:16:18 +01004810 " ---------------------------------------------
4811 " NetrwBrowseChgDir: refresh the directory list {{{3
4812 " ---------------------------------------------
4813 NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4814 norm! m`
Bram Moolenaar446cb832008-06-24 21:56:24 +00004815
4816 elseif newdir == '../'
Luca Saccarolac363ca12024-12-19 20:16:18 +01004817 " --------------------------------------
4818 " NetrwBrowseChgDir: go up one directory {{{3
4819 " --------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +00004820
Luca Saccarolac363ca12024-12-19 20:16:18 +01004821 if w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
4822 " force a refresh
4823 setl noro ma
4824 NetrwKeepj %d _
4825 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00004826
Luca Saccarolac363ca12024-12-19 20:16:18 +01004827 if has("amiga")
4828 " amiga
4829 if a:islocal
4830 let dirname= substitute(dirname,'^\(.*[/:]\)\([^/]\+$\)','\1','')
4831 let dirname= substitute(dirname,'/$','','')
4832 else
4833 let dirname= substitute(dirname,'^\(.*[/:]\)\([^/]\+/$\)','\1','')
4834 endif
4835
4836 elseif !g:netrw_cygwin && has("win32")
4837 " windows
4838 if a:islocal
4839 let dirname= substitute(dirname,'^\(.*\)/\([^/]\+\)/$','\1','')
4840 if dirname == ""
4841 let dirname= '/'
4842 endif
4843 else
4844 let dirname= substitute(dirname,'^\(\a\{3,}://.\{-}/\{1,2}\)\(.\{-}\)\([^/]\+\)/$','\1\2','')
4845 endif
4846 if dirname =~ '^\a:$'
4847 let dirname= dirname.'/'
4848 endif
4849
Bram Moolenaar446cb832008-06-24 21:56:24 +00004850 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01004851 " unix or cygwin
4852 if a:islocal
4853 let dirname= substitute(dirname,'^\(.*\)/\([^/]\+\)/$','\1','')
4854 if dirname == ""
4855 let dirname= '/'
4856 endif
4857 else
4858 let dirname= substitute(dirname,'^\(\a\{3,}://.\{-}/\{1,2}\)\(.\{-}\)\([^/]\+\)/$','\1\2','')
4859 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00004860 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01004861 NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4862 norm! m`
Bram Moolenaar446cb832008-06-24 21:56:24 +00004863
4864 elseif exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
Luca Saccarolac363ca12024-12-19 20:16:18 +01004865 " --------------------------------------
4866 " NetrwBrowseChgDir: Handle Tree Listing {{{3
4867 " --------------------------------------
4868 " force a refresh (for TREELIST, NetrwTreeDir() will force the refresh)
4869 setl noro ma
4870 if !(exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("b:netrw_curdir"))
4871 NetrwKeepj %d _
Bram Moolenaar446cb832008-06-24 21:56:24 +00004872 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01004873 let treedir = s:NetrwTreeDir(a:islocal)
4874 let s:treecurpos = winsaveview()
4875 let haskey = 0
Bram Moolenaar446cb832008-06-24 21:56:24 +00004876
Luca Saccarolac363ca12024-12-19 20:16:18 +01004877 " search treedict for tree dir as-is
Bram Moolenaar446cb832008-06-24 21:56:24 +00004878 if has_key(w:netrw_treedict,treedir)
Luca Saccarolac363ca12024-12-19 20:16:18 +01004879 let haskey= 1
Bram Moolenaar446cb832008-06-24 21:56:24 +00004880 else
Bram Moolenaar446cb832008-06-24 21:56:24 +00004881 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00004882
Luca Saccarolac363ca12024-12-19 20:16:18 +01004883 " search treedict for treedir with a [/@] appended
4884 if !haskey && treedir !~ '[/@]$'
4885 if has_key(w:netrw_treedict,treedir."/")
4886 let treedir= treedir."/"
4887 let haskey = 1
4888 else
4889 endif
4890 endif
4891
4892 " search treedict for treedir with any trailing / elided
4893 if !haskey && treedir =~ '/$'
4894 let treedir= substitute(treedir,'/$','','')
4895 if has_key(w:netrw_treedict,treedir)
4896 let haskey = 1
4897 else
4898 endif
4899 endif
4900
4901 if haskey
4902 " close tree listing for selected subdirectory
4903 call remove(w:netrw_treedict,treedir)
4904 let dirname= w:netrw_treetop
4905 else
4906 " go down one directory
4907 let dirname= substitute(treedir,'/*$','/','')
4908 endif
4909 NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4910 let s:treeforceredraw = 1
Bram Moolenaar446cb832008-06-24 21:56:24 +00004911
4912 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01004913 " ----------------------------------------
4914 " NetrwBrowseChgDir: Go down one directory {{{3
4915 " ----------------------------------------
4916 let dirname = s:ComposePath(dirname,newdir)
4917 NetrwKeepj call s:SetRexDir(a:islocal,dirname)
4918 norm! m`
Bram Moolenaar9964e462007-05-05 17:54:07 +00004919 endif
4920
Luca Saccarolac363ca12024-12-19 20:16:18 +01004921 " --------------------------------------
4922 " NetrwBrowseChgDir: Restore and Cleanup {{{3
4923 " --------------------------------------
Bram Moolenaar13600302014-05-22 18:26:40 +02004924 if dorestore
Luca Saccarolac363ca12024-12-19 20:16:18 +01004925 " dorestore is zero'd when a local file was hidden or bufhidden;
4926 " in such a case, we want to keep whatever settings it may have.
4927 NetrwKeepj call s:NetrwOptionsRestore("s:")
Bram Moolenaar13600302014-05-22 18:26:40 +02004928 endif
Bram Moolenaar13600302014-05-22 18:26:40 +02004929 if dolockout && dorestore
Luca Saccarolac363ca12024-12-19 20:16:18 +01004930 if filewritable(dirname)
4931 setl ma noro nomod
4932 else
4933 setl ma ro nomod
4934 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +00004935 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02004936 call s:RestorePosn(s:netrw_posn)
Bram Moolenaar97d62492012-11-15 21:28:22 +01004937 let @@= ykeep
Bram Moolenaar9964e462007-05-05 17:54:07 +00004938
Bram Moolenaar446cb832008-06-24 21:56:24 +00004939 return dirname
Bram Moolenaar9964e462007-05-05 17:54:07 +00004940endfun
4941
4942" ---------------------------------------------------------------------
Bram Moolenaara6878372014-03-22 21:02:50 +01004943" s:NetrwBrowseUpDir: implements the "-" mappings {{{2
4944" for thin, long, and wide: cursor placed just after banner
4945" for tree, keeps cursor on current filename
4946fun! s:NetrwBrowseUpDir(islocal)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01004947 if exists("w:netrw_bannercnt") && line(".") < w:netrw_bannercnt-1
Luca Saccarolac363ca12024-12-19 20:16:18 +01004948 " this test needed because occasionally this function seems to be incorrectly called
4949 " when multiple leftmouse clicks are taken when atop the one line help in the banner.
4950 " I'm allowing the very bottom line to permit a "-" exit so that one may escape empty
4951 " directories.
4952 return
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01004953 endif
4954
Bram Moolenaara6878372014-03-22 21:02:50 +01004955 norm! 0
4956 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
Luca Saccarolac363ca12024-12-19 20:16:18 +01004957 let curline= getline(".")
4958 let swwline= winline() - 1
4959 if exists("w:netrw_treetop")
4960 let b:netrw_curdir= w:netrw_treetop
4961 elseif exists("b:netrw_curdir")
4962 let w:netrw_treetop= b:netrw_curdir
4963 else
4964 let w:netrw_treetop= getcwd()
4965 let b:netrw_curdir = w:netrw_treetop
4966 endif
4967 let curfile = getline(".")
4968 let curpath = s:NetrwTreePath(w:netrw_treetop)
4969 if a:islocal
4970 call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,'../',0))
4971 else
4972 call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,'../',0))
4973 endif
4974 if w:netrw_treetop == '/'
4975 keepj call search('^\M'.curfile,"w")
4976 elseif curfile == '../'
4977 keepj call search('^\M'.curfile,"wb")
4978 else
4979 while 1
4980 keepj call search('^\M'.s:treedepthstring.curfile,"wb")
4981 let treepath= s:NetrwTreePath(w:netrw_treetop)
4982 if treepath == curpath
4983 break
4984 endif
4985 endwhile
4986 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02004987
Bram Moolenaara6878372014-03-22 21:02:50 +01004988 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01004989 call s:SavePosn(s:netrw_posn)
4990 if exists("b:netrw_curdir")
4991 let curdir= b:netrw_curdir
4992 else
4993 let curdir= expand(getcwd())
4994 endif
4995 if a:islocal
4996 call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,'../',0))
4997 else
4998 call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,'../',0))
4999 endif
5000 call s:RestorePosn(s:netrw_posn)
5001 let curdir= substitute(curdir,'^.*[\/]','','')
5002 let curdir= '\<'. escape(curdir, '~'). '/'
5003 call search(curdir,'wc')
Bram Moolenaara6878372014-03-22 21:02:50 +01005004 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01005005endfun
5006
Christian Brabandt8b0fa7a2024-10-31 09:21:23 +01005007func s:redir()
5008 " set up redirection (avoids browser messages)
5009 " by default if not set, g:netrw_suppress_gx_mesg is true
5010 if get(g:, 'netrw_suppress_gx_mesg', 1)
5011 if &srr =~# "%s"
5012 return printf(&srr, has("win32") ? "nul" : "/dev/null")
5013 else
5014 return &srr .. (has("win32") ? "nul" : "/dev/null")
5015 endif
5016 endif
5017 return ''
5018endfunc
5019
5020if has('unix')
Luca Saccarolac363ca12024-12-19 20:16:18 +01005021 if has('win32unix')
5022 " Cygwin provides cygstart
5023 if executable('cygstart')
5024 fun! netrw#Launch(args)
5025 exe 'silent ! cygstart --hide' a:args s:redir() | redraw!
5026 endfun
5027 elseif !empty($MSYSTEM) && executable('start')
5028 " MSYS2/Git Bash comes by default without cygstart; see
5029 " https://www.msys2.org/wiki/How-does-MSYS2-differ-from-Cygwin
5030 " Instead it provides /usr/bin/start script running `cmd.exe //c start`
5031 " Adding "" //b` sets void title, hides cmd window and blocks path conversion
5032 " of /b to \b\ " by MSYS2; see https://www.msys2.org/docs/filesystem-paths/
5033 fun! netrw#Launch(args)
5034 exe 'silent !start "" //b' a:args s:redir() | redraw!
5035 endfun
5036 else
5037 " imitate /usr/bin/start script for other environments and hope for the best
5038 fun! netrw#Launch(args)
5039 exe 'silent !cmd //c start "" //b' a:args s:redir() | redraw!
5040 endfun
5041 endif
5042 elseif exists('$WSL_DISTRO_NAME') " use cmd.exe to start GUI apps in WSL
5043 fun! netrw#Launch(args)
5044 let args = a:args
5045 exe 'silent !' ..
5046 \ ((args =~? '\v<\f+\.(exe|com|bat|cmd)>') ?
5047 \ 'cmd.exe /c start /b ' .. args :
5048 \ 'nohup ' .. args .. ' ' .. s:redir() .. ' &')
5049 \ | redraw!
5050 endfun
Christian Brabandt8b0fa7a2024-10-31 09:21:23 +01005051 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01005052 fun! netrw#Launch(args)
5053 exe ':silent ! nohup' a:args s:redir() (has('gui_running') ? '' : '&') | redraw!
5054 endfun
Christian Brabandt8b0fa7a2024-10-31 09:21:23 +01005055 endif
Christian Brabandt8b0fa7a2024-10-31 09:21:23 +01005056elseif has('win32')
Luca Saccarolac363ca12024-12-19 20:16:18 +01005057 fun! netrw#Launch(args)
5058 exe 'silent !' .. (&shell =~? '\<cmd\.exe\>' ? '' : 'cmd.exe /c')
5059 \ 'start "" /b' a:args s:redir() | redraw!
5060 endfun
Christian Brabandt8b0fa7a2024-10-31 09:21:23 +01005061else
Luca Saccarolac363ca12024-12-19 20:16:18 +01005062 fun! netrw#Launch(dummy)
5063 echom 'No common launcher found'
5064 endfun
Christian Brabandt8b0fa7a2024-10-31 09:21:23 +01005065endif
5066
5067" Git Bash
5068if has('win32unix')
Luca Saccarolac363ca12024-12-19 20:16:18 +01005069 " (cyg)start suffices
5070 let s:os_viewer = ''
shane.xb.qianc673b802024-12-20 19:36:40 +01005071" Windows / WSL
Christian Brabandt8b0fa7a2024-10-31 09:21:23 +01005072elseif executable('explorer.exe')
Luca Saccarolac363ca12024-12-19 20:16:18 +01005073 let s:os_viewer = 'explorer.exe'
shane.xb.qianc673b802024-12-20 19:36:40 +01005074" Linux / BSD
Christian Brabandt8b0fa7a2024-10-31 09:21:23 +01005075elseif executable('xdg-open')
Luca Saccarolac363ca12024-12-19 20:16:18 +01005076 let s:os_viewer = 'xdg-open'
shane.xb.qianc673b802024-12-20 19:36:40 +01005077" MacOS
Christian Brabandt8b0fa7a2024-10-31 09:21:23 +01005078elseif executable('open')
Luca Saccarolac363ca12024-12-19 20:16:18 +01005079 let s:os_viewer = 'open'
Christian Brabandt8b0fa7a2024-10-31 09:21:23 +01005080endif
5081
5082fun! s:viewer()
Christian Brabandt92b36662024-12-08 09:52:37 +01005083 " g:netrw_browsex_viewer could be a string of program + its arguments,
5084 " test if first argument is executable
5085 if exists('g:netrw_browsex_viewer') && executable(split(g:netrw_browsex_viewer)[0])
Christian Brabandt8b0fa7a2024-10-31 09:21:23 +01005086 " extract any viewing options. Assumes that they're set apart by spaces.
5087 " call Decho("extract any viewing options from g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
5088 if g:netrw_browsex_viewer =~ '\s'
5089 let viewer = substitute(g:netrw_browsex_viewer,'\s.*$','','')
5090 let viewopt = substitute(g:netrw_browsex_viewer,'^\S\+\s*','','')." "
5091 let oviewer = ''
5092 let cnt = 1
5093 while !executable(viewer) && viewer != oviewer
5094 let viewer = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\1','')
5095 let viewopt = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\3','')." "
5096 let cnt = cnt + 1
5097 let oviewer = viewer
5098 " call Decho("!exe: viewer<".viewer."> viewopt<".viewopt.">",'~'.expand("<slnum>"))
5099 endwhile
5100 else
5101 let viewer = g:netrw_browsex_viewer
5102 let viewopt = ""
5103 endif
5104 " call Decho("viewer<".viewer."> viewopt<".viewopt.">",'~'.expand("<slnum>"))
5105 return viewer .. ' ' .. viewopt
5106 else
5107 if !exists('s:os_viewer')
5108 call netrw#ErrorMsg(s:ERROR,"No program to open this path found. See :help Open for more information.",106)
5109 else
5110 return s:os_viewer
5111 endif
5112 endif
5113endfun
5114
5115fun! netrw#Open(file) abort
5116 call netrw#Launch(s:viewer() .. ' ' .. shellescape(a:file, 1))
shane.xb.qianc673b802024-12-20 19:36:40 +01005117endfun
Christian Brabandt8b0fa7a2024-10-31 09:21:23 +01005118
shane.xb.qianc673b802024-12-20 19:36:40 +01005119if !exists('g:netrw_regex_url')
5120 let g:netrw_regex_url = '\%(\%(http\|ftp\|irc\)s\?\|file\)://\S\{-}'
5121endif
5122
5123" ---------------------------------------------------------------------
5124" netrw#BrowseX: (implements "x" and "gx") executes a special "viewer" script or program for the {{{2
5125" given filename; typically this means given their extension.
5126" 0=local, 1=remote
5127fun! netrw#BrowseX(fname,remote)
5128 if a:remote == 1 && a:fname !~ '^https\=:' && a:fname =~ '/$'
5129 " remote directory, not a webpage access, looks like an attempt to do a directory listing
5130 norm! gf
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01005131 endif
5132
shane.xb.qianc673b802024-12-20 19:36:40 +01005133 if exists("g:netrw_browsex_viewer") && exists("g:netrw_browsex_support_remote") && !g:netrw_browsex_support_remote
5134 let remote = a:remote
5135 else
5136 let remote = 0
5137 endif
Bram Moolenaar89a9c152021-08-29 21:55:35 +02005138
shane.xb.qianc673b802024-12-20 19:36:40 +01005139 let ykeep = @@
5140 let screenposn = winsaveview()
Bram Moolenaar97d62492012-11-15 21:28:22 +01005141
shane.xb.qianc673b802024-12-20 19:36:40 +01005142 " need to save and restore aw setting as gx can invoke this function from non-netrw buffers
5143 let awkeep = &aw
5144 set noaw
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01005145
shane.xb.qianc673b802024-12-20 19:36:40 +01005146 " special core dump handler
5147 if a:fname =~ '/core\(\.\d\+\)\=$'
5148 if exists("g:Netrw_corehandler")
5149 if type(g:Netrw_corehandler) == 2
5150 " g:Netrw_corehandler is a function reference (see :help Funcref)
5151 call g:Netrw_corehandler(s:NetrwFile(a:fname))
5152 elseif type(g:Netrw_corehandler) == 3
5153 " g:Netrw_corehandler is a List of function references (see :help Funcref)
5154 for Fncref in g:Netrw_corehandler
5155 if type(Fncref) == 2
5156 call Fncref(a:fname)
5157 endif
5158 endfor
Bram Moolenaar5c736222010-01-06 20:54:52 +01005159 endif
shane.xb.qianc673b802024-12-20 19:36:40 +01005160 call winrestview(screenposn)
5161 let @@= ykeep
5162 let &aw= awkeep
5163 return
Luca Saccarolac363ca12024-12-19 20:16:18 +01005164 endif
shane.xb.qianc673b802024-12-20 19:36:40 +01005165 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01005166
shane.xb.qianc673b802024-12-20 19:36:40 +01005167 " set up the filename
5168 " (lower case the extension, make a local copy of a remote file)
5169 let exten= substitute(a:fname,'.*\.\(.\{-}\)','\1','e')
5170 if has("win32")
5171 let exten= substitute(exten,'^.*$','\L&\E','')
5172 endif
5173 if exten =~ "[\\/]"
5174 let exten= ""
5175 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01005176
shane.xb.qianc673b802024-12-20 19:36:40 +01005177 if remote == 1
5178 " create a local copy
5179 setl bh=delete
5180 call netrw#NetRead(3,a:fname)
5181 " attempt to rename tempfile
5182 let basename= substitute(a:fname,'^\(.*\)/\(.*\)\.\([^.]*\)$','\2','')
5183 let newname = substitute(s:netrw_tmpfile,'^\(.*\)/\(.*\)\.\([^.]*\)$','\1/'.basename.'.\3','')
5184 if s:netrw_tmpfile != newname && newname != ""
5185 if rename(s:netrw_tmpfile,newname) == 0
5186 " renaming succeeded
5187 let fname= newname
Luca Saccarolac363ca12024-12-19 20:16:18 +01005188 else
shane.xb.qianc673b802024-12-20 19:36:40 +01005189 " renaming failed
Luca Saccarolac363ca12024-12-19 20:16:18 +01005190 let fname= s:netrw_tmpfile
5191 endif
5192 else
shane.xb.qianc673b802024-12-20 19:36:40 +01005193 let fname= s:netrw_tmpfile
Luca Saccarolac363ca12024-12-19 20:16:18 +01005194 endif
shane.xb.qianc673b802024-12-20 19:36:40 +01005195 else
5196 let fname= a:fname
5197 " special ~ handler for local
5198 if fname =~ '^\~' && expand("$HOME") != ""
5199 let fname= s:NetrwFile(substitute(fname,'^\~',expand("$HOME"),''))
Bram Moolenaar5c736222010-01-06 20:54:52 +01005200 endif
shane.xb.qianc673b802024-12-20 19:36:40 +01005201 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +01005202
shane.xb.qianc673b802024-12-20 19:36:40 +01005203 " although shellescape(..., 1) is used in netrw#Open(), it's insufficient
5204 call netrw#Open(escape(fname, '#%'))
5205
5206 " cleanup: remove temporary file,
5207 " delete current buffer if success with handler,
5208 " return to prior buffer (directory listing)
5209 " Feb 12, 2008: had to de-activate removal of
5210 " temporary file because it wasn't getting seen.
5211 " if remote == 1 && fname != a:fname
5212 " call s:NetrwDelete(fname)
5213 " endif
5214
5215 if remote == 1
5216 setl bh=delete bt=nofile
5217 if g:netrw_use_noswf
5218 setl noswf
5219 endif
5220 exe "sil! NetrwKeepj norm! \<c-o>"
5221 endif
5222 call winrestview(screenposn)
5223 let @@ = ykeep
5224 let &aw= awkeep
5225endfun
5226
5227" ---------------------------------------------------------------------
5228" netrw#GX: gets word under cursor for gx support {{{2
5229" See also: netrw#BrowseXVis
5230" netrw#BrowseX
5231fun! netrw#GX()
5232 " call Dfunc("netrw#GX()")
5233 if &ft == "netrw"
5234 let fname= s:NetrwGetWord()
5235 else
5236 let fname= exists("g:netrw_gx")? expand(g:netrw_gx) : s:GetURL()
5237 endif
5238 " call Dret("netrw#GX <".fname.">")
5239 return fname
5240endfun
5241
5242fun! s:GetURL() abort
5243 let URL = ''
5244 if exists('*Netrw_get_URL_' .. &filetype)
5245 let URL = call('Netrw_get_URL_' .. &filetype, [])
5246 endif
5247 if !empty(URL) | return URL | endif
5248 " URLs end in letter, digit or forward slash
5249 let URL = matchstr(expand("<cWORD>"), '\<' .. g:netrw_regex_url .. '\ze[^A-Za-z0-9/]*$')
5250 if !empty(URL) | return URL | endif
5251
5252 " Is it a file in the current work dir ...
5253 let file = expand("<cfile>")
5254 if filereadable(file) | return file | endif
5255 " ... or in that of the current buffer?
5256 let path = fnamemodify(expand('%'), ':p')
5257 if isdirectory(path)
5258 let dir = path
5259 elseif filereadable(path)
5260 let dir = fnamemodify(path, ':h')
5261 endif
5262 if exists('dir') && filereadable(dir..'/'..file) | return dir..'/'..file | endif
5263
5264 return ''
5265endf
5266
5267" ---------------------------------------------------------------------
5268" netrw#BrowseXVis: used by gx in visual mode to select a file for browsing {{{2
5269fun! netrw#BrowseXVis()
5270 let dict={}
5271 let dict.a=[getreg('a'), getregtype('a')]
5272 norm! gv"ay
5273 let gxfile= @a
5274 call s:RestoreRegister(dict)
5275 call netrw#BrowseX(gxfile,netrw#CheckIfRemote(gxfile))
5276endfun
5277
5278" ---------------------------------------------------------------------
5279" s:NetrwBufRename: renames a buffer without the side effect of retaining an unlisted buffer having the old name {{{2
5280" Using the file command on a "[No Name]" buffer does not seem to cause the old "[No Name]" buffer
5281" to become an unlisted buffer, so in that case don't bwipe it.
5282fun! s:NetrwBufRename(newname)
5283 " call Dfunc("s:NetrwBufRename(newname<".a:newname.">) buf(%)#".bufnr("%")."<".bufname(bufnr("%")).">")
5284 " call Dredir("ls!","s:NetrwBufRename (before rename)")
5285 let oldbufname= bufname(bufnr("%"))
5286 " call Decho("buf#".bufnr("%").": oldbufname<".oldbufname.">",'~'.expand("<slnum>"))
5287
5288 if oldbufname != a:newname
5289 " call Decho("do buffer rename: oldbufname<".oldbufname."> ≠ a:newname<".a:newname.">",'~'.expand("<slnum>"))
5290 let b:junk= 1
5291 " call Decho("rename buffer: sil! keepj keepalt file ".fnameescape(a:newname),'~'.expand("<slnum>"))
5292 exe 'sil! keepj keepalt file '.fnameescape(a:newname)
5293 " call Dredir("ls!","s:NetrwBufRename (before bwipe)~".expand("<slnum>"))
5294 let oldbufnr= bufnr(oldbufname)
5295 " call Decho("oldbufname<".oldbufname."> oldbufnr#".oldbufnr,'~'.expand("<slnum>"))
5296 " call Decho("bufnr(%)=".bufnr("%"),'~'.expand("<slnum>"))
5297 if oldbufname != "" && oldbufnr != -1 && oldbufnr != bufnr("%")
5298 " call Decho("bwipe ".oldbufnr,'~'.expand("<slnum>"))
5299 exe "bwipe! ".oldbufnr
5300 " else " Decho
5301 " call Decho("did *not* bwipe buf#".oldbufnr,'~'.expand("<slnum>"))
5302 " call Decho("..reason: if oldbufname<".oldbufname."> is empty",'~'.expand("<slnum>"))"
5303 " call Decho("..reason: if oldbufnr#".oldbufnr." is -1",'~'.expand("<slnum>"))"
5304 " call Decho("..reason: if oldbufnr#".oldbufnr." != bufnr(%)#".bufnr("%"),'~'.expand("<slnum>"))"
5305 endif
5306 " call Dredir("ls!","s:NetrwBufRename (after rename)")
5307 " else " Decho
5308 " call Decho("oldbufname<".oldbufname."> == a:newname: did *not* rename",'~'.expand("<slnum>"))
5309 endif
5310
5311 " call Dret("s:NetrwBufRename : buf#".bufnr("%").": oldname<".oldbufname."> newname<".a:newname."> expand(%)<".expand("%").">")
5312endfun
5313
5314" ---------------------------------------------------------------------
5315" netrw#CheckIfRemote: returns 1 if current file looks like an url, 0 else {{{2
5316fun! netrw#CheckIfRemote(...)
5317 " call Dfunc("netrw#CheckIfRemote() a:0=".a:0)
5318 if a:0 > 0
5319 let curfile= a:1
5320 else
5321 let curfile= expand("%")
5322 endif
5323 " call Decho("curfile<".curfile.">")
5324 if curfile =~ '^\a\{3,}://'
5325 " call Dret("netrw#CheckIfRemote 1")
5326 return 1
5327 else
5328 " call Dret("netrw#CheckIfRemote 0")
5329 return 0
5330 endif
5331endfun
5332
5333" ---------------------------------------------------------------------
5334" s:NetrwChgPerm: (implements "gp") change file permission {{{2
5335fun! s:NetrwChgPerm(islocal,curdir)
5336 let ykeep = @@
5337 call inputsave()
5338 let newperm= input("Enter new permission: ")
5339 call inputrestore()
5340 let chgperm= substitute(g:netrw_chgperm,'\<FILENAME\>',s:ShellEscape(expand("<cfile>")),'')
5341 let chgperm= substitute(chgperm,'\<PERM\>',s:ShellEscape(newperm),'')
5342 call system(chgperm)
5343 if v:shell_error != 0
5344 NetrwKeepj call netrw#ErrorMsg(1,"changing permission on file<".expand("<cfile>")."> seems to have failed",75)
5345 endif
5346 if a:islocal
5347 NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
5348 endif
5349 let @@= ykeep
5350endfun
5351
5352" ---------------------------------------------------------------------
5353" s:CheckIfKde: checks if kdeinit is running {{{2
5354" Returns 0: kdeinit not running
5355" 1: kdeinit is running
5356fun! s:CheckIfKde()
5357 " call Dfunc("s:CheckIfKde()")
5358 " seems kde systems often have gnome-open due to dependencies, even though
5359 " gnome-open's subsidiary display tools are largely absent. Kde systems
5360 " usually have "kdeinit" running, though... (tnx Mikolaj Machowski)
5361 if !exists("s:haskdeinit")
5362 if has("unix") && executable("ps") && !has("win32unix")
5363 let s:haskdeinit= system("ps -e") =~ '\<kdeinit'
5364 if v:shell_error
5365 let s:haskdeinit = 0
5366 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02005367 else
shane.xb.qianc673b802024-12-20 19:36:40 +01005368 let s:haskdeinit= 0
Bram Moolenaar85850f32019-07-19 22:05:51 +02005369 endif
shane.xb.qianc673b802024-12-20 19:36:40 +01005370 " call Decho("setting s:haskdeinit=".s:haskdeinit,'~'.expand("<slnum>"))
5371 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00005372
shane.xb.qianc673b802024-12-20 19:36:40 +01005373 " call Dret("s:CheckIfKde ".s:haskdeinit)
5374 return s:haskdeinit
5375endfun
5376
5377" ---------------------------------------------------------------------
5378" s:NetrwClearExplore: clear explore variables (if any) {{{2
5379fun! s:NetrwClearExplore()
5380 " call Dfunc("s:NetrwClearExplore()")
5381 2match none
5382 if exists("s:explore_match") |unlet s:explore_match |endif
5383 if exists("s:explore_indx") |unlet s:explore_indx |endif
5384 if exists("s:netrw_explore_prvdir") |unlet s:netrw_explore_prvdir |endif
5385 if exists("s:dirstarstar") |unlet s:dirstarstar |endif
5386 if exists("s:explore_prvdir") |unlet s:explore_prvdir |endif
5387 if exists("w:netrw_explore_indx") |unlet w:netrw_explore_indx |endif
5388 if exists("w:netrw_explore_listlen")|unlet w:netrw_explore_listlen|endif
5389 if exists("w:netrw_explore_list") |unlet w:netrw_explore_list |endif
5390 if exists("w:netrw_explore_bufnr") |unlet w:netrw_explore_bufnr |endif
5391 " redraw!
5392 " call Dret("s:NetrwClearExplore")
5393endfun
5394
5395" ---------------------------------------------------------------------
5396" s:NetrwEditBuf: decides whether or not to use keepalt to edit a buffer {{{2
5397fun! s:NetrwEditBuf(bufnum)
5398 " call Dfunc("s:NetrwEditBuf(fname<".a:bufnum.">)")
5399 if exists("g:netrw_altfile") && g:netrw_altfile && &ft == "netrw"
5400 " call Decho("exe sil! NetrwKeepj keepalt noswapfile b ".fnameescape(a:bufnum))
5401 exe "sil! NetrwKeepj keepalt noswapfile b ".fnameescape(a:bufnum)
5402 else
5403 " call Decho("exe sil! NetrwKeepj noswapfile b ".fnameescape(a:bufnum))
5404 exe "sil! NetrwKeepj noswapfile b ".fnameescape(a:bufnum)
5405 endif
5406 " call Dret("s:NetrwEditBuf")
5407endfun
5408
5409" ---------------------------------------------------------------------
5410" s:NetrwEditFile: decides whether or not to use keepalt to edit a file {{{2
5411" NetrwKeepj [keepalt] <OPT> <CMD> <FILENAME>
5412fun! s:NetrwEditFile(cmd,opt,fname)
5413 " call Dfunc("s:NetrwEditFile(cmd<".a:cmd.">,opt<".a:opt.">,fname<".a:fname.">) ft<".&ft.">")
5414 if exists("g:netrw_altfile") && g:netrw_altfile && &ft == "netrw"
5415 " call Decho("exe NetrwKeepj keepalt ".a:opt." ".a:cmd." ".fnameescape(a:fname))
5416 exe "NetrwKeepj keepalt ".a:opt." ".a:cmd." ".fnameescape(a:fname)
5417 else
5418 " call Decho("exe NetrwKeepj ".a:opt." ".a:cmd." ".fnameescape(a:fname))
5419 if a:cmd =~# 'e\%[new]!' && !&hidden && getbufvar(bufname('%'), '&modified', 0)
5420 call setbufvar(bufname('%'), '&bufhidden', 'hide')
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01005421 endif
shane.xb.qianc673b802024-12-20 19:36:40 +01005422 exe "NetrwKeepj ".a:opt." ".a:cmd." ".fnameescape(a:fname)
5423 endif
5424 " call Dret("s:NetrwEditFile")
5425endfun
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01005426
shane.xb.qianc673b802024-12-20 19:36:40 +01005427" ---------------------------------------------------------------------
5428" s:NetrwExploreListUniq: {{{2
5429fun! s:NetrwExploreListUniq(explist)
5430 " this assumes that the list is already sorted
5431 let newexplist= []
5432 for member in a:explist
5433 if !exists("uniqmember") || member != uniqmember
5434 let uniqmember = member
5435 let newexplist = newexplist + [ member ]
Christian Brabandt98b73eb2024-06-04 18:15:57 +02005436 endif
shane.xb.qianc673b802024-12-20 19:36:40 +01005437 endfor
5438 return newexplist
5439endfun
Bram Moolenaar71badf92023-04-22 22:40:14 +01005440
shane.xb.qianc673b802024-12-20 19:36:40 +01005441" ---------------------------------------------------------------------
5442" s:NetrwForceChgDir: (gd support) Force treatment as a directory {{{2
5443fun! s:NetrwForceChgDir(islocal,newdir)
5444 let ykeep= @@
5445 if a:newdir !~ '/$'
5446 " ok, looks like force is needed to get directory-style treatment
5447 if a:newdir =~ '@$'
5448 let newdir= substitute(a:newdir,'@$','/','')
5449 elseif a:newdir =~ '[*=|\\]$'
5450 let newdir= substitute(a:newdir,'.$','/','')
5451 else
5452 let newdir= a:newdir.'/'
5453 endif
5454 else
5455 " should already be getting treatment as a directory
5456 let newdir= a:newdir
5457 endif
5458 let newdir= s:NetrwBrowseChgDir(a:islocal,newdir,0)
5459 call s:NetrwBrowse(a:islocal,newdir)
5460 let @@= ykeep
5461endfun
Bram Moolenaar5c736222010-01-06 20:54:52 +01005462
shane.xb.qianc673b802024-12-20 19:36:40 +01005463" ---------------------------------------------------------------------
5464" s:NetrwGlob: does glob() if local, remote listing otherwise {{{2
5465" direntry: this is the name of the directory. Will be fnameescape'd to prevent wildcard handling by glob()
5466" expr : this is the expression to follow the directory. Will use s:ComposePath()
5467" pare =1: remove the current directory from the resulting glob() filelist
5468" =0: leave the current directory in the resulting glob() filelist
5469fun! s:NetrwGlob(direntry,expr,pare)
5470 " call Dfunc("s:NetrwGlob(direntry<".a:direntry."> expr<".a:expr."> pare=".a:pare.")")
5471 if netrw#CheckIfRemote()
5472 keepalt 1sp
5473 keepalt enew
5474 let keep_liststyle = w:netrw_liststyle
5475 let w:netrw_liststyle = s:THINLIST
5476 if s:NetrwRemoteListing() == 0
5477 keepj keepalt %s@/@@
5478 let filelist= getline(1,$)
5479 q!
5480 else
5481 " remote listing error -- leave treedict unchanged
5482 let filelist= w:netrw_treedict[a:direntry]
5483 endif
5484 let w:netrw_liststyle= keep_liststyle
5485 else
5486 let path= s:ComposePath(fnameescape(a:direntry), a:expr)
5487 if has("win32")
5488 " escape [ so it is not detected as wildcard character, see :h wildcard
5489 let path= substitute(path, '[', '[[]', 'g')
5490 endif
5491 if v:version > 704 || (v:version == 704 && has("patch656"))
5492 let filelist= glob(path,0,1,1)
5493 else
5494 let filelist= glob(path,0,1)
5495 endif
5496 if a:pare
5497 let filelist= map(filelist,'substitute(v:val, "^.*/", "", "")')
5498 endif
5499 endif
5500 return filelist
5501endfun
Bram Moolenaaradc21822011-04-01 18:03:16 +02005502
shane.xb.qianc673b802024-12-20 19:36:40 +01005503" ---------------------------------------------------------------------
5504" s:NetrwForceFile: (gf support) Force treatment as a file {{{2
5505fun! s:NetrwForceFile(islocal,newfile)
5506 if a:newfile =~ '[/@*=|\\]$'
5507 let newfile= substitute(a:newfile,'.$','','')
5508 else
5509 let newfile= a:newfile
5510 endif
5511 if a:islocal
5512 call s:NetrwBrowseChgDir(a:islocal,newfile,0)
5513 else
5514 call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,newfile,0))
5515 endif
5516endfun
Bram Moolenaare0fa3742016-02-20 15:47:01 +01005517
shane.xb.qianc673b802024-12-20 19:36:40 +01005518" ---------------------------------------------------------------------
5519" s:NetrwHide: this function is invoked by the "a" map for browsing {{{2
5520" and switches the hiding mode. The actual hiding is done by
5521" s:NetrwListHide().
5522" g:netrw_hide= 0: show all
5523" 1: show not-hidden files
5524" 2: show hidden files only
5525fun! s:NetrwHide(islocal)
5526 let ykeep= @@
5527 let svpos= winsaveview()
Bram Moolenaaradc21822011-04-01 18:03:16 +02005528
shane.xb.qianc673b802024-12-20 19:36:40 +01005529 if exists("s:netrwmarkfilelist_{bufnr('%')}")
Bram Moolenaar446cb832008-06-24 21:56:24 +00005530
shane.xb.qianc673b802024-12-20 19:36:40 +01005531 " hide the files in the markfile list
5532 for fname in s:netrwmarkfilelist_{bufnr("%")}
5533 if match(g:netrw_list_hide,'\<'.fname.'\>') != -1
5534 " remove fname from hiding list
5535 let g:netrw_list_hide= substitute(g:netrw_list_hide,'..\<'.escape(fname,g:netrw_fname_escape).'\>..','','')
5536 let g:netrw_list_hide= substitute(g:netrw_list_hide,',,',',','g')
5537 let g:netrw_list_hide= substitute(g:netrw_list_hide,'^,\|,$','','')
Luca Saccarolac363ca12024-12-19 20:16:18 +01005538 else
shane.xb.qianc673b802024-12-20 19:36:40 +01005539 " append fname to hiding list
5540 if exists("g:netrw_list_hide") && g:netrw_list_hide != ""
5541 let g:netrw_list_hide= g:netrw_list_hide.',\<'.escape(fname,g:netrw_fname_escape).'\>'
Luca Saccarolac363ca12024-12-19 20:16:18 +01005542 else
shane.xb.qianc673b802024-12-20 19:36:40 +01005543 let g:netrw_list_hide= '\<'.escape(fname,g:netrw_fname_escape).'\>'
Luca Saccarolac363ca12024-12-19 20:16:18 +01005544 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01005545 endif
shane.xb.qianc673b802024-12-20 19:36:40 +01005546 endfor
5547 NetrwKeepj call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
5548 let g:netrw_hide= 1
Bram Moolenaar446cb832008-06-24 21:56:24 +00005549
shane.xb.qianc673b802024-12-20 19:36:40 +01005550 else
Bram Moolenaar446cb832008-06-24 21:56:24 +00005551
shane.xb.qianc673b802024-12-20 19:36:40 +01005552 " switch between show-all/show-not-hidden/show-hidden
5553 let g:netrw_hide=(g:netrw_hide+1)%3
5554 exe "NetrwKeepj norm! 0"
5555 if g:netrw_hide && g:netrw_list_hide == ""
5556 NetrwKeepj call netrw#ErrorMsg(s:WARNING,"your hiding list is empty!",49)
Luca Saccarolac363ca12024-12-19 20:16:18 +01005557 let @@= ykeep
shane.xb.qianc673b802024-12-20 19:36:40 +01005558 return
5559 endif
5560 endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +01005561
shane.xb.qianc673b802024-12-20 19:36:40 +01005562 NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
5563 NetrwKeepj call winrestview(svpos)
5564 let @@= ykeep
5565endfun
5566
5567" ---------------------------------------------------------------------
5568" s:NetrwHideEdit: allows user to edit the file/directory hiding list {{{2
5569fun! s:NetrwHideEdit(islocal)
5570 let ykeep= @@
5571 " save current cursor position
5572 let svpos= winsaveview()
5573
5574 " get new hiding list from user
5575 call inputsave()
5576 let newhide= input("Edit Hiding List: ",g:netrw_list_hide)
5577 call inputrestore()
5578 let g:netrw_list_hide= newhide
5579
5580 " refresh the listing
5581 sil NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,"./",0))
5582
5583 " restore cursor position
5584 call winrestview(svpos)
5585 let @@= ykeep
5586endfun
5587
5588" ---------------------------------------------------------------------
5589" s:NetrwHidden: invoked by "gh" {{{2
5590fun! s:NetrwHidden(islocal)
5591 let ykeep= @@
5592 " save current position
5593 let svpos = winsaveview()
5594
5595 if g:netrw_list_hide =~ '\(^\|,\)\\(^\\|\\s\\s\\)\\zs\\.\\S\\+'
5596 " remove .file pattern from hiding list
5597 let g:netrw_list_hide= substitute(g:netrw_list_hide,'\(^\|,\)\\(^\\|\\s\\s\\)\\zs\\.\\S\\+','','')
5598 elseif s:Strlen(g:netrw_list_hide) >= 1
5599 let g:netrw_list_hide= g:netrw_list_hide . ',\(^\|\s\s\)\zs\.\S\+'
5600 else
5601 let g:netrw_list_hide= '\(^\|\s\s\)\zs\.\S\+'
5602 endif
5603 if g:netrw_list_hide =~ '^,'
5604 let g:netrw_list_hide= strpart(g:netrw_list_hide,1)
5605 endif
5606
5607 " refresh screen and return to saved position
5608 NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
5609 NetrwKeepj call winrestview(svpos)
5610 let @@= ykeep
5611endfun
5612
5613" ---------------------------------------------------------------------
5614" s:NetrwHome: this function determines a "home" for saving bookmarks and history {{{2
5615fun! s:NetrwHome()
5616 if exists("g:netrw_home")
5617 let home= expand(g:netrw_home)
5618 else
5619 " go to vim plugin home
5620 for home in split(&rtp,',') + ['']
5621 if isdirectory(s:NetrwFile(home)) && filewritable(s:NetrwFile(home)) | break | endif
5622 let basehome= substitute(home,'[/\\]\.vim$','','')
5623 if isdirectory(s:NetrwFile(basehome)) && filewritable(s:NetrwFile(basehome))
5624 let home= basehome."/.vim"
5625 break
Luca Saccarolac363ca12024-12-19 20:16:18 +01005626 endif
shane.xb.qianc673b802024-12-20 19:36:40 +01005627 endfor
5628 if home == ""
5629 " just pick the first directory
5630 let home= substitute(&rtp,',.*$','','')
5631 endif
5632 if has("win32")
5633 let home= substitute(home,'/','\\','g')
5634 endif
5635 endif
5636 " insure that the home directory exists
5637 if g:netrw_dirhistmax > 0 && !isdirectory(s:NetrwFile(home))
5638 " call Decho("insure that the home<".home."> directory exists")
5639 if exists("g:netrw_mkdir")
5640 " call Decho("call system(".g:netrw_mkdir." ".s:ShellEscape(s:NetrwFile(home)).")")
5641 call system(g:netrw_mkdir." ".s:ShellEscape(s:NetrwFile(home)))
5642 else
5643 " call Decho("mkdir(".home.")")
5644 call mkdir(home)
5645 endif
5646 endif
5647 let g:netrw_home= home
5648 return home
5649endfun
Bram Moolenaar446cb832008-06-24 21:56:24 +00005650
shane.xb.qianc673b802024-12-20 19:36:40 +01005651" ---------------------------------------------------------------------
5652" s:NetrwLeftmouse: handles the <leftmouse> when in a netrw browsing window {{{2
5653fun! s:NetrwLeftmouse(islocal)
5654 if exists("s:netrwdrag")
5655 return
5656 endif
5657 if &ft != "netrw"
5658 return
5659 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00005660
shane.xb.qianc673b802024-12-20 19:36:40 +01005661 let ykeep= @@
5662 " check if the status bar was clicked on instead of a file/directory name
5663 while getchar(0) != 0
5664 "clear the input stream
5665 endwhile
5666 call feedkeys("\<LeftMouse>")
5667 let c = getchar()
5668 let mouse_lnum = v:mouse_lnum
5669 let wlastline = line('w$')
5670 let lastline = line('$')
5671 if mouse_lnum >= wlastline + 1 || v:mouse_win != winnr()
5672 " appears to be a status bar leftmouse click
5673 let @@= ykeep
5674 return
5675 endif
5676 " Dec 04, 2013: following test prevents leftmouse selection/deselection of directories and files in treelist mode
5677 " Windows are separated by vertical separator bars - but the mouse seems to be doing what it should when dragging that bar
5678 " without this test when its disabled.
5679 " May 26, 2014: edit file, :Lex, resize window -- causes refresh. Reinstated a modified test. See if problems develop.
5680 if v:mouse_col > virtcol('.')
5681 let @@= ykeep
5682 return
5683 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00005684
shane.xb.qianc673b802024-12-20 19:36:40 +01005685 if a:islocal
5686 if exists("b:netrw_curdir")
5687 NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord(),1))
5688 endif
5689 else
5690 if exists("b:netrw_curdir")
5691 NetrwKeepj call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord(),1))
5692 endif
5693 endif
5694 let @@= ykeep
5695endfun
Bram Moolenaar5c736222010-01-06 20:54:52 +01005696
shane.xb.qianc673b802024-12-20 19:36:40 +01005697" ---------------------------------------------------------------------
5698" s:NetrwCLeftmouse: used to select a file/directory for a target {{{2
5699fun! s:NetrwCLeftmouse(islocal)
5700 if &ft != "netrw"
5701 return
5702 endif
5703 call s:NetrwMarkFileTgt(a:islocal)
5704endfun
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01005705
shane.xb.qianc673b802024-12-20 19:36:40 +01005706" ---------------------------------------------------------------------
5707" s:NetrwServerEdit: edit file in a server gvim, usually NETRWSERVER (implements <c-r>){{{2
5708" a:islocal=0 : <c-r> not used, remote
5709" a:islocal=1 : <c-r> not used, local
5710" a:islocal=2 : <c-r> used, remote
5711" a:islocal=3 : <c-r> used, local
5712fun! s:NetrwServerEdit(islocal,fname)
5713 " call Dfunc("s:NetrwServerEdit(islocal=".a:islocal.",fname<".a:fname.">)")
5714 let islocal = a:islocal%2 " =0: remote =1: local
5715 let ctrlr = a:islocal >= 2 " =0: <c-r> not used =1: <c-r> used
Luca Saccarolac363ca12024-12-19 20:16:18 +01005716
shane.xb.qianc673b802024-12-20 19:36:40 +01005717 if (islocal && isdirectory(s:NetrwFile(a:fname))) || (!islocal && a:fname =~ '/$')
5718 " handle directories in the local window -- not in the remote vim server
5719 " user must have closed the NETRWSERVER window. Treat as normal editing from netrw.
5720 let g:netrw_browse_split= 0
5721 if exists("s:netrw_browse_split") && exists("s:netrw_browse_split_".winnr())
5722 let g:netrw_browse_split= s:netrw_browse_split_{winnr()}
5723 unlet s:netrw_browse_split_{winnr()}
5724 endif
5725 call s:NetrwBrowse(islocal,s:NetrwBrowseChgDir(islocal,a:fname,0))
5726 return
5727 endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01005728
shane.xb.qianc673b802024-12-20 19:36:40 +01005729 if has("clientserver") && executable("gvim")
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01005730
shane.xb.qianc673b802024-12-20 19:36:40 +01005731 if exists("g:netrw_browse_split") && type(g:netrw_browse_split) == 3
5732 let srvrname = g:netrw_browse_split[0]
5733 let tabnum = g:netrw_browse_split[1]
5734 let winnum = g:netrw_browse_split[2]
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01005735
shane.xb.qianc673b802024-12-20 19:36:40 +01005736 if serverlist() !~ '\<'.srvrname.'\>'
5737 if !ctrlr
5738 " user must have closed the server window and the user did not use <c-r>, but
5739 " used something like <cr>.
Luca Saccarolac363ca12024-12-19 20:16:18 +01005740 if exists("g:netrw_browse_split")
Luca Saccarolac363ca12024-12-19 20:16:18 +01005741 unlet g:netrw_browse_split
5742 endif
shane.xb.qianc673b802024-12-20 19:36:40 +01005743 let g:netrw_browse_split= 0
5744 if exists("s:netrw_browse_split_".winnr())
5745 let g:netrw_browse_split= s:netrw_browse_split_{winnr()}
Luca Saccarolac363ca12024-12-19 20:16:18 +01005746 endif
shane.xb.qianc673b802024-12-20 19:36:40 +01005747 call s:NetrwBrowseChgDir(islocal,a:fname,0)
5748 return
Luca Saccarolac363ca12024-12-19 20:16:18 +01005749
shane.xb.qianc673b802024-12-20 19:36:40 +01005750 elseif has("win32") && executable("start")
5751 " start up remote netrw server under windows
5752 call system("start gvim --servername ".srvrname)
5753
5754 else
5755 " start up remote netrw server under linux
5756 call system("gvim --servername ".srvrname)
Luca Saccarolac363ca12024-12-19 20:16:18 +01005757 endif
shane.xb.qianc673b802024-12-20 19:36:40 +01005758 endif
5759
5760 call remote_send(srvrname,":tabn ".tabnum."\<cr>")
5761 call remote_send(srvrname,":".winnum."wincmd w\<cr>")
5762 call remote_send(srvrname,":e ".fnameescape(s:NetrwFile(a:fname))."\<cr>")
5763 else
5764
5765 if serverlist() !~ '\<'.g:netrw_servername.'\>'
5766
5767 if !ctrlr
5768 if exists("g:netrw_browse_split")
5769 unlet g:netrw_browse_split
5770 endif
5771 let g:netrw_browse_split= 0
5772 call s:NetrwBrowse(islocal,s:NetrwBrowseChgDir(islocal,a:fname,0))
5773 return
5774
5775 else
5776 if has("win32") && executable("start")
5777 " start up remote netrw server under windows
5778 call system("start gvim --servername ".g:netrw_servername)
5779 else
5780 " start up remote netrw server under linux
5781 call system("gvim --servername ".g:netrw_servername)
5782 endif
5783 endif
5784 endif
5785
5786 while 1
5787 try
5788 call remote_send(g:netrw_servername,":e ".fnameescape(s:NetrwFile(a:fname))."\<cr>")
5789 break
5790 catch /^Vim\%((\a\+)\)\=:E241/
5791 sleep 200m
5792 endtry
Luca Saccarolac363ca12024-12-19 20:16:18 +01005793 endwhile
5794
shane.xb.qianc673b802024-12-20 19:36:40 +01005795 if exists("g:netrw_browse_split")
5796 if type(g:netrw_browse_split) != 3
5797 let s:netrw_browse_split_{winnr()}= g:netrw_browse_split
5798 endif
5799 unlet g:netrw_browse_split
Luca Saccarolac363ca12024-12-19 20:16:18 +01005800 endif
shane.xb.qianc673b802024-12-20 19:36:40 +01005801 let g:netrw_browse_split= [g:netrw_servername,1,1]
5802 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01005803
shane.xb.qianc673b802024-12-20 19:36:40 +01005804 else
5805 call netrw#ErrorMsg(s:ERROR,"you need a gui-capable vim and client-server to use <ctrl-r>",98)
5806 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01005807
shane.xb.qianc673b802024-12-20 19:36:40 +01005808endfun
Luca Saccarolac363ca12024-12-19 20:16:18 +01005809
shane.xb.qianc673b802024-12-20 19:36:40 +01005810" ---------------------------------------------------------------------
5811" s:NetrwSLeftmouse: marks the file under the cursor. May be dragged to select additional files {{{2
5812fun! s:NetrwSLeftmouse(islocal)
5813 if &ft != "netrw"
5814 return
5815 endif
5816 " call Dfunc("s:NetrwSLeftmouse(islocal=".a:islocal.")")
Luca Saccarolac363ca12024-12-19 20:16:18 +01005817
shane.xb.qianc673b802024-12-20 19:36:40 +01005818 let s:ngw= s:NetrwGetWord()
5819 call s:NetrwMarkFile(a:islocal,s:ngw)
Luca Saccarolac363ca12024-12-19 20:16:18 +01005820
shane.xb.qianc673b802024-12-20 19:36:40 +01005821 " call Dret("s:NetrwSLeftmouse")
5822endfun
5823
5824" ---------------------------------------------------------------------
5825" s:NetrwSLeftdrag: invoked via a shift-leftmouse and dragging {{{2
5826" Used to mark multiple files.
5827fun! s:NetrwSLeftdrag(islocal)
5828 " call Dfunc("s:NetrwSLeftdrag(islocal=".a:islocal.")")
5829 if !exists("s:netrwdrag")
5830 let s:netrwdrag = winnr()
5831 if a:islocal
5832 nno <silent> <s-leftrelease> <leftmouse>:<c-u>call <SID>NetrwSLeftrelease(1)<cr>
5833 else
5834 nno <silent> <s-leftrelease> <leftmouse>:<c-u>call <SID>NetrwSLeftrelease(0)<cr>
5835 endif
5836 endif
5837 let ngw = s:NetrwGetWord()
5838 if !exists("s:ngw") || s:ngw != ngw
5839 call s:NetrwMarkFile(a:islocal,ngw)
5840 endif
5841 let s:ngw= ngw
5842 " call Dret("s:NetrwSLeftdrag : s:netrwdrag=".s:netrwdrag." buf#".bufnr("%"))
5843endfun
5844
5845" ---------------------------------------------------------------------
5846" s:NetrwSLeftrelease: terminates shift-leftmouse dragging {{{2
5847fun! s:NetrwSLeftrelease(islocal)
5848 " call Dfunc("s:NetrwSLeftrelease(islocal=".a:islocal.") s:netrwdrag=".s:netrwdrag." buf#".bufnr("%"))
5849 if exists("s:netrwdrag")
5850 nunmap <s-leftrelease>
5851 let ngw = s:NetrwGetWord()
5852 if !exists("s:ngw") || s:ngw != ngw
5853 call s:NetrwMarkFile(a:islocal,ngw)
5854 endif
5855 if exists("s:ngw")
5856 unlet s:ngw
5857 endif
5858 unlet s:netrwdrag
5859 endif
5860 " call Dret("s:NetrwSLeftrelease")
5861endfun
5862
5863" ---------------------------------------------------------------------
5864" s:NetrwListHide: uses [range]g~...~d to delete files that match {{{2
5865" comma-separated patterns given in g:netrw_list_hide
5866fun! s:NetrwListHide()
5867 " call Dfunc("s:NetrwListHide() g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">")
5868 " call Decho("initial: ".string(getline(w:netrw_bannercnt,'$')))
5869 let ykeep= @@
5870
5871 " find a character not in the "hide" string to use as a separator for :g and :v commands
5872 " How-it-works: take the hiding command, convert it into a range.
5873 " Duplicate characters don't matter.
5874 " Remove all such characters from the '/~@#...890' string.
5875 " Use the first character left as a separator character.
5876 " call Decho("find a character not in the hide string to use as a separator",'~'.expand("<slnum>"))
5877 let listhide= g:netrw_list_hide
5878 let sep = strpart(substitute('~@#$%^&*{};:,<.>?|1234567890','['.escape(listhide,'-]^\').']','','ge'),1,1)
5879 " call Decho("sep<".sep."> (sep not in hide string)",'~'.expand("<slnum>"))
5880
5881 while listhide != ""
5882 if listhide =~ ','
5883 let hide = substitute(listhide,',.*$','','e')
5884 let listhide = substitute(listhide,'^.\{-},\(.*\)$','\1','e')
5885 else
5886 let hide = listhide
5887 let listhide = ""
5888 endif
5889 " call Decho("..extracted pattern from listhide: hide<".hide."> g:netrw_sort_by<".g:netrw_sort_by.'>','~'.expand("<slnum>"))
5890 if g:netrw_sort_by =~ '^[ts]'
5891 if hide =~ '^\^'
5892 " call Decho("..modify hide to handle a \"^...\" pattern",'~'.expand("<slnum>"))
5893 let hide= substitute(hide,'^\^','^\(\\d\\+/\)','')
5894 elseif hide =~ '^\\(\^'
5895 let hide= substitute(hide,'^\\(\^','\\(^\\(\\d\\+/\\)','')
Luca Saccarolac363ca12024-12-19 20:16:18 +01005896 endif
shane.xb.qianc673b802024-12-20 19:36:40 +01005897 " call Decho("..hide<".hide."> listhide<".listhide.'>','~'.expand("<slnum>"))
5898 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01005899
shane.xb.qianc673b802024-12-20 19:36:40 +01005900 " Prune the list by hiding any files which match
5901 " call Decho("..prune the list by hiding any files which ".((g:netrw_hide == 1)? "" : "don't")."match hide<".hide.">")
5902 if g:netrw_hide == 1
5903 " call Decho("..hiding<".hide.">",'~'.expand("<slnum>"))
5904 exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g'.sep.hide.sep.'d'
5905 elseif g:netrw_hide == 2
5906 " call Decho("..showing<".hide.">",'~'.expand("<slnum>"))
5907 exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g'.sep.hide.sep.'s@^@ /-KEEP-/ @'
5908 endif
5909 " call Decho("..result: ".string(getline(w:netrw_bannercnt,'$')),'~'.expand("<slnum>"))
5910 endwhile
Luca Saccarolac363ca12024-12-19 20:16:18 +01005911
shane.xb.qianc673b802024-12-20 19:36:40 +01005912 if g:netrw_hide == 2
5913 exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$v@^ /-KEEP-/ @d'
5914 " call Decho("..v KEEP: ".string(getline(w:netrw_bannercnt,'$')),'~'.expand("<slnum>"))
5915 exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s@^\%( /-KEEP-/ \)\+@@e'
5916 " call Decho("..g KEEP: ".string(getline(w:netrw_bannercnt,'$')),'~'.expand("<slnum>"))
5917 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01005918
shane.xb.qianc673b802024-12-20 19:36:40 +01005919 " remove any blank lines that have somehow remained.
5920 " This seems to happen under Windows.
5921 exe 'sil! NetrwKeepj 1,$g@^\s*$@d'
Luca Saccarolac363ca12024-12-19 20:16:18 +01005922
shane.xb.qianc673b802024-12-20 19:36:40 +01005923 let @@= ykeep
5924 " call Dret("s:NetrwListHide")
5925endfun
Luca Saccarolac363ca12024-12-19 20:16:18 +01005926
shane.xb.qianc673b802024-12-20 19:36:40 +01005927" ---------------------------------------------------------------------
5928" s:NetrwMakeDir: this function makes a directory (both local and remote) {{{2
5929" implements the "d" mapping.
5930fun! s:NetrwMakeDir(usrhost)
Luca Saccarolac363ca12024-12-19 20:16:18 +01005931
shane.xb.qianc673b802024-12-20 19:36:40 +01005932 let ykeep= @@
5933 " get name of new directory from user. A bare <CR> will skip.
5934 " if its currently a directory, also request will be skipped, but with
5935 " a message.
5936 call inputsave()
5937 let newdirname= input("Please give directory name: ")
5938 call inputrestore()
Luca Saccarolac363ca12024-12-19 20:16:18 +01005939
shane.xb.qianc673b802024-12-20 19:36:40 +01005940 if newdirname == ""
5941 let @@= ykeep
5942 return
5943 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01005944
shane.xb.qianc673b802024-12-20 19:36:40 +01005945 if a:usrhost == ""
Luca Saccarolac363ca12024-12-19 20:16:18 +01005946
shane.xb.qianc673b802024-12-20 19:36:40 +01005947 " Local mkdir:
5948 " sanity checks
5949 let fullnewdir= b:netrw_curdir.'/'.newdirname
5950 if isdirectory(s:NetrwFile(fullnewdir))
5951 if !exists("g:netrw_quiet")
5952 NetrwKeepj call netrw#ErrorMsg(s:WARNING,"<".newdirname."> is already a directory!",24)
Luca Saccarolac363ca12024-12-19 20:16:18 +01005953 endif
5954 let @@= ykeep
shane.xb.qianc673b802024-12-20 19:36:40 +01005955 return
5956 endif
5957 if s:FileReadable(fullnewdir)
5958 if !exists("g:netrw_quiet")
5959 NetrwKeepj call netrw#ErrorMsg(s:WARNING,"<".newdirname."> is already a file!",25)
Luca Saccarolac363ca12024-12-19 20:16:18 +01005960 endif
5961 let @@= ykeep
Luca Saccarolac363ca12024-12-19 20:16:18 +01005962 return
5963 endif
5964
shane.xb.qianc673b802024-12-20 19:36:40 +01005965 " requested new local directory is neither a pre-existing file or
5966 " directory, so make it!
5967 if exists("*mkdir")
5968 if has("unix")
5969 call mkdir(fullnewdir,"p",xor(0777, system("umask")))
Luca Saccarolac363ca12024-12-19 20:16:18 +01005970 else
shane.xb.qianc673b802024-12-20 19:36:40 +01005971 call mkdir(fullnewdir,"p")
Luca Saccarolac363ca12024-12-19 20:16:18 +01005972 endif
shane.xb.qianc673b802024-12-20 19:36:40 +01005973 else
5974 let netrw_origdir= s:NetrwGetcwd(1)
5975 if s:NetrwLcd(b:netrw_curdir)
5976 return
5977 endif
5978 call s:NetrwExe("sil! !".g:netrw_localmkdir.g:netrw_localmkdiropt.' '.s:ShellEscape(newdirname,1))
5979 if v:shell_error != 0
5980 let @@= ykeep
5981 call netrw#ErrorMsg(s:ERROR,"consider setting g:netrw_localmkdir<".g:netrw_localmkdir."> to something that works",80)
5982 return
5983 endif
5984 if !g:netrw_keepdir
5985 if s:NetrwLcd(netrw_origdir)
5986 return
5987 endif
5988 endif
5989 endif
5990
5991 if v:shell_error == 0
5992 " refresh listing
5993 let svpos= winsaveview()
5994 call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./',0))
5995 call winrestview(svpos)
5996 elseif !exists("g:netrw_quiet")
5997 call netrw#ErrorMsg(s:ERROR,"unable to make directory<".newdirname.">",26)
5998 endif
5999
6000 elseif !exists("b:netrw_method") || b:netrw_method == 4
6001 " Remote mkdir: using ssh
6002 let mkdircmd = s:MakeSshCmd(g:netrw_mkdir_cmd)
6003 let newdirname= substitute(b:netrw_curdir,'^\%(.\{-}/\)\{3}\(.*\)$','\1','').newdirname
6004 call s:NetrwExe("sil! !".mkdircmd." ".s:ShellEscape(newdirname,1))
6005 if v:shell_error == 0
6006 " refresh listing
6007 let svpos= winsaveview()
6008 NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./',0))
6009 NetrwKeepj call winrestview(svpos)
6010 elseif !exists("g:netrw_quiet")
6011 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"unable to make directory<".newdirname.">",27)
6012 endif
6013
6014 elseif b:netrw_method == 2
6015 " Remote mkdir: using ftp+.netrc
6016 let svpos= winsaveview()
6017 if exists("b:netrw_fname")
6018 let remotepath= b:netrw_fname
6019 else
6020 let remotepath= ""
6021 endif
6022 call s:NetrwRemoteFtpCmd(remotepath,g:netrw_remote_mkdir.' "'.newdirname.'"')
6023 NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./',0))
6024 NetrwKeepj call winrestview(svpos)
6025
6026 elseif b:netrw_method == 3
6027 " Remote mkdir: using ftp + machine, id, passwd, and fname (ie. no .netrc)
6028 let svpos= winsaveview()
6029 if exists("b:netrw_fname")
6030 let remotepath= b:netrw_fname
6031 else
6032 let remotepath= ""
6033 endif
6034 call s:NetrwRemoteFtpCmd(remotepath,g:netrw_remote_mkdir.' "'.newdirname.'"')
6035 NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./',0))
6036 NetrwKeepj call winrestview(svpos)
6037 endif
6038
6039 let @@= ykeep
6040endfun
6041
6042" ---------------------------------------------------------------------
6043" s:TreeSqueezeDir: allows a shift-cr (gvim only) to squeeze the current tree-listing directory {{{2
6044fun! s:TreeSqueezeDir(islocal)
6045 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
6046 " its a tree-listing style
6047 let curdepth = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e')
6048 let stopline = (exists("w:netrw_bannercnt")? (w:netrw_bannercnt + 1) : 1)
6049 let depth = strchars(substitute(curdepth,' ','','g'))
6050 let srch = -1
6051 if depth >= 2
6052 NetrwKeepj norm! 0
6053 let curdepthm1= substitute(curdepth,'^'.s:treedepthstring,'','')
6054 let srch = search('^'.curdepthm1.'\%('.s:treedepthstring.'\)\@!','bW',stopline)
6055 elseif depth == 1
6056 NetrwKeepj norm! 0
6057 let treedepthchr= substitute(s:treedepthstring,' ','','')
6058 let srch = search('^[^'.treedepthchr.']','bW',stopline)
6059 endif
6060 if srch > 0
6061 call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,s:NetrwGetWord(),1))
6062 exe srch
6063 endif
6064 endif
6065endfun
6066
6067" ---------------------------------------------------------------------
6068" s:NetrwMaps: {{{2
6069fun! s:NetrwMaps(islocal)
6070
6071 " mouse <Plug> maps: {{{3
6072 if g:netrw_mousemaps && g:netrw_retmap
6073 " call Decho("set up Rexplore 2-leftmouse",'~'.expand("<slnum>"))
6074 if !hasmapto("<Plug>NetrwReturn")
6075 if maparg("<2-leftmouse>","n") == "" || maparg("<2-leftmouse>","n") =~ '^-$'
6076 nmap <unique> <silent> <2-leftmouse> <Plug>NetrwReturn
6077 elseif maparg("<c-leftmouse>","n") == ""
6078 nmap <unique> <silent> <c-leftmouse> <Plug>NetrwReturn
6079 endif
6080 endif
6081 nno <silent> <Plug>NetrwReturn :Rexplore<cr>
6082 endif
6083
6084 " generate default <Plug> maps {{{3
6085 if !hasmapto('<Plug>NetrwHide') |nmap <buffer> <silent> <nowait> a <Plug>NetrwHide_a|endif
6086 if !hasmapto('<Plug>NetrwBrowseUpDir') |nmap <buffer> <silent> <nowait> - <Plug>NetrwBrowseUpDir|endif
6087 if !hasmapto('<Plug>NetrwOpenFile') |nmap <buffer> <silent> <nowait> % <Plug>NetrwOpenFile|endif
6088 if !hasmapto('<Plug>NetrwBadd_cb') |nmap <buffer> <silent> <nowait> cb <Plug>NetrwBadd_cb|endif
6089 if !hasmapto('<Plug>NetrwBadd_cB') |nmap <buffer> <silent> <nowait> cB <Plug>NetrwBadd_cB|endif
6090 if !hasmapto('<Plug>NetrwLcd') |nmap <buffer> <silent> <nowait> cd <Plug>NetrwLcd|endif
6091 if !hasmapto('<Plug>NetrwSetChgwin') |nmap <buffer> <silent> <nowait> C <Plug>NetrwSetChgwin|endif
6092 if !hasmapto('<Plug>NetrwRefresh') |nmap <buffer> <silent> <nowait> <c-l> <Plug>NetrwRefresh|endif
6093 if !hasmapto('<Plug>NetrwLocalBrowseCheck') |nmap <buffer> <silent> <nowait> <cr> <Plug>NetrwLocalBrowseCheck|endif
6094 if !hasmapto('<Plug>NetrwServerEdit') |nmap <buffer> <silent> <nowait> <c-r> <Plug>NetrwServerEdit|endif
6095 if !hasmapto('<Plug>NetrwMakeDir') |nmap <buffer> <silent> <nowait> d <Plug>NetrwMakeDir|endif
6096 if !hasmapto('<Plug>NetrwBookHistHandler_gb')|nmap <buffer> <silent> <nowait> gb <Plug>NetrwBookHistHandler_gb|endif
6097
6098 if a:islocal
6099 " local normal-mode maps {{{3
6100 nnoremap <buffer> <silent> <Plug>NetrwHide_a :<c-u>call <SID>NetrwHide(1)<cr>
6101 nnoremap <buffer> <silent> <Plug>NetrwBrowseUpDir :<c-u>call <SID>NetrwBrowseUpDir(1)<cr>
6102 nnoremap <buffer> <silent> <Plug>NetrwOpenFile :<c-u>call <SID>NetrwOpenFile(1)<cr>
6103 nnoremap <buffer> <silent> <Plug>NetrwBadd_cb :<c-u>call <SID>NetrwBadd(1,0)<cr>
6104 nnoremap <buffer> <silent> <Plug>NetrwBadd_cB :<c-u>call <SID>NetrwBadd(1,1)<cr>
6105 nnoremap <buffer> <silent> <Plug>NetrwLcd :<c-u>call <SID>NetrwLcd(b:netrw_curdir)<cr>
6106 nnoremap <buffer> <silent> <Plug>NetrwSetChgwin :<c-u>call <SID>NetrwSetChgwin()<cr>
6107 nnoremap <buffer> <silent> <Plug>NetrwLocalBrowseCheck :<c-u>call netrw#LocalBrowseCheck(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1))<cr>
6108 nnoremap <buffer> <silent> <Plug>NetrwServerEdit :<c-u>call <SID>NetrwServerEdit(3,<SID>NetrwGetWord())<cr>
6109 nnoremap <buffer> <silent> <Plug>NetrwMakeDir :<c-u>call <SID>NetrwMakeDir("")<cr>
6110 nnoremap <buffer> <silent> <Plug>NetrwBookHistHandler_gb :<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr>
6111 " ---------------------------------------------------------------------
6112 nnoremap <buffer> <silent> <nowait> gd :<c-u>call <SID>NetrwForceChgDir(1,<SID>NetrwGetWord())<cr>
6113 nnoremap <buffer> <silent> <nowait> gf :<c-u>call <SID>NetrwForceFile(1,<SID>NetrwGetWord())<cr>
6114 nnoremap <buffer> <silent> <nowait> gh :<c-u>call <SID>NetrwHidden(1)<cr>
6115 nnoremap <buffer> <silent> <nowait> gn :<c-u>call netrw#SetTreetop(0,<SID>NetrwGetWord())<cr>
6116 nnoremap <buffer> <silent> <nowait> gp :<c-u>call <SID>NetrwChgPerm(1,b:netrw_curdir)<cr>
6117 nnoremap <buffer> <silent> <nowait> I :<c-u>call <SID>NetrwBannerCtrl(1)<cr>
6118 nnoremap <buffer> <silent> <nowait> i :<c-u>call <SID>NetrwListStyle(1)<cr>
6119 nnoremap <buffer> <silent> <nowait> ma :<c-u>call <SID>NetrwMarkFileArgList(1,0)<cr>
6120 nnoremap <buffer> <silent> <nowait> mA :<c-u>call <SID>NetrwMarkFileArgList(1,1)<cr>
6121 nnoremap <buffer> <silent> <nowait> mb :<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
6122 nnoremap <buffer> <silent> <nowait> mB :<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
6123 nnoremap <buffer> <silent> <nowait> mc :<c-u>call <SID>NetrwMarkFileCopy(1)<cr>
6124 nnoremap <buffer> <silent> <nowait> md :<c-u>call <SID>NetrwMarkFileDiff(1)<cr>
6125 nnoremap <buffer> <silent> <nowait> me :<c-u>call <SID>NetrwMarkFileEdit(1)<cr>
6126 nnoremap <buffer> <silent> <nowait> mf :<c-u>call <SID>NetrwMarkFile(1,<SID>NetrwGetWord())<cr>
6127 nnoremap <buffer> <silent> <nowait> mF :<c-u>call <SID>NetrwUnmarkList(bufnr("%"),b:netrw_curdir)<cr>
6128 nnoremap <buffer> <silent> <nowait> mg :<c-u>call <SID>NetrwMarkFileGrep(1)<cr>
6129 nnoremap <buffer> <silent> <nowait> mh :<c-u>call <SID>NetrwMarkHideSfx(1)<cr>
6130 nnoremap <buffer> <silent> <nowait> mm :<c-u>call <SID>NetrwMarkFileMove(1)<cr>
6131 nnoremap <buffer> <silent> <nowait> mp :<c-u>call <SID>NetrwMarkFilePrint(1)<cr>
6132 nnoremap <buffer> <silent> <nowait> mr :<c-u>call <SID>NetrwMarkFileRegexp(1)<cr>
6133 nnoremap <buffer> <silent> <nowait> ms :<c-u>call <SID>NetrwMarkFileSource(1)<cr>
6134 nnoremap <buffer> <silent> <nowait> mT :<c-u>call <SID>NetrwMarkFileTag(1)<cr>
6135 nnoremap <buffer> <silent> <nowait> mt :<c-u>call <SID>NetrwMarkFileTgt(1)<cr>
6136 nnoremap <buffer> <silent> <nowait> mu :<c-u>call <SID>NetrwUnMarkFile(1)<cr>
6137 nnoremap <buffer> <silent> <nowait> mv :<c-u>call <SID>NetrwMarkFileVimCmd(1)<cr>
6138 nnoremap <buffer> <silent> <nowait> mx :<c-u>call <SID>NetrwMarkFileExe(1,0)<cr>
6139 nnoremap <buffer> <silent> <nowait> mX :<c-u>call <SID>NetrwMarkFileExe(1,1)<cr>
6140 nnoremap <buffer> <silent> <nowait> mz :<c-u>call <SID>NetrwMarkFileCompress(1)<cr>
6141 nnoremap <buffer> <silent> <nowait> O :<c-u>call <SID>NetrwObtain(1)<cr>
6142 nnoremap <buffer> <silent> <nowait> o :call <SID>NetrwSplit(3)<cr>
6143 nnoremap <buffer> <silent> <nowait> p :<c-u>call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1,1))<cr>
6144 nnoremap <buffer> <silent> <nowait> P :<c-u>call <SID>NetrwPrevWinOpen(1)<cr>
6145 nnoremap <buffer> <silent> <nowait> qb :<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
6146 nnoremap <buffer> <silent> <nowait> qf :<c-u>call <SID>NetrwFileInfo(1,<SID>NetrwGetWord())<cr>
6147 nnoremap <buffer> <silent> <nowait> qF :<c-u>call <SID>NetrwMarkFileQFEL(1,getqflist())<cr>
6148 nnoremap <buffer> <silent> <nowait> qL :<c-u>call <SID>NetrwMarkFileQFEL(1,getloclist(v:count))<cr>
6149 nnoremap <buffer> <silent> <nowait> s :call <SID>NetrwSortStyle(1)<cr>
6150 nnoremap <buffer> <silent> <nowait> S :<c-u>call <SID>NetSortSequence(1)<cr>
6151 nnoremap <buffer> <silent> <nowait> Tb :<c-u>call <SID>NetrwSetTgt(1,'b',v:count1)<cr>
6152 nnoremap <buffer> <silent> <nowait> t :call <SID>NetrwSplit(4)<cr>
6153 nnoremap <buffer> <silent> <nowait> Th :<c-u>call <SID>NetrwSetTgt(1,'h',v:count)<cr>
6154 nnoremap <buffer> <silent> <nowait> u :<c-u>call <SID>NetrwBookHistHandler(4,expand("%"))<cr>
6155 nnoremap <buffer> <silent> <nowait> U :<c-u>call <SID>NetrwBookHistHandler(5,expand("%"))<cr>
6156 nnoremap <buffer> <silent> <nowait> v :call <SID>NetrwSplit(5)<cr>
6157 nnoremap <buffer> <silent> <nowait> x :<c-u>call netrw#BrowseX(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1,0),0)"<cr>
6158 nnoremap <buffer> <silent> <nowait> X :<c-u>call <SID>NetrwLocalExecute(expand("<cword>"))"<cr>
6159
6160 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>
6161 if !hasmapto('<Plug>NetrwHideEdit')
6162 nmap <buffer> <unique> <c-h> <Plug>NetrwHideEdit
6163 endif
6164 nnoremap <buffer> <silent> <Plug>NetrwHideEdit :call <SID>NetrwHideEdit(1)<cr>
6165 if !hasmapto('<Plug>NetrwRefresh')
6166 nmap <buffer> <unique> <c-l> <Plug>NetrwRefresh
6167 endif
6168 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>
6169 if s:didstarstar || !mapcheck("<s-down>","n")
6170 nnoremap <buffer> <silent> <s-down> :Nexplore<cr>
6171 endif
6172 if s:didstarstar || !mapcheck("<s-up>","n")
6173 nnoremap <buffer> <silent> <s-up> :Pexplore<cr>
6174 endif
6175 if !hasmapto('<Plug>NetrwTreeSqueeze')
6176 nmap <buffer> <silent> <nowait> <s-cr> <Plug>NetrwTreeSqueeze
6177 endif
6178 nnoremap <buffer> <silent> <Plug>NetrwTreeSqueeze :call <SID>TreeSqueezeDir(1)<cr>
6179 let mapsafecurdir = escape(b:netrw_curdir, s:netrw_map_escape)
6180 if g:netrw_mousemaps == 1
6181 nmap <buffer> <leftmouse> <Plug>NetrwLeftmouse
6182 nmap <buffer> <c-leftmouse> <Plug>NetrwCLeftmouse
6183 nmap <buffer> <middlemouse> <Plug>NetrwMiddlemouse
6184 nmap <buffer> <s-leftmouse> <Plug>NetrwSLeftmouse
6185 nmap <buffer> <s-leftdrag> <Plug>NetrwSLeftdrag
6186 nmap <buffer> <2-leftmouse> <Plug>Netrw2Leftmouse
6187 imap <buffer> <leftmouse> <Plug>ILeftmouse
6188 imap <buffer> <middlemouse> <Plug>IMiddlemouse
6189 nno <buffer> <silent> <Plug>NetrwLeftmouse :exec "norm! \<lt>leftmouse>"<bar>call <SID>NetrwLeftmouse(1)<cr>
6190 nno <buffer> <silent> <Plug>NetrwCLeftmouse :exec "norm! \<lt>leftmouse>"<bar>call <SID>NetrwCLeftmouse(1)<cr>
6191 nno <buffer> <silent> <Plug>NetrwMiddlemouse :exec "norm! \<lt>leftmouse>"<bar>call <SID>NetrwPrevWinOpen(1)<cr>
6192 nno <buffer> <silent> <Plug>NetrwSLeftmouse :exec "norm! \<lt>leftmouse>"<bar>call <SID>NetrwSLeftmouse(1)<cr>
6193 nno <buffer> <silent> <Plug>NetrwSLeftdrag :exec "norm! \<lt>leftmouse>"<bar>call <SID>NetrwSLeftdrag(1)<cr>
6194 nmap <buffer> <silent> <Plug>Netrw2Leftmouse -
6195 exe 'nnoremap <buffer> <silent> <rightmouse> :exec "norm! \<lt>leftmouse>"<bar>call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6196 exe 'vnoremap <buffer> <silent> <rightmouse> :exec "norm! \<lt>leftmouse>"<bar>call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6197 endif
6198 exe 'nnoremap <buffer> <silent> <nowait> <del> :call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6199 exe 'nnoremap <buffer> <silent> <nowait> D :call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6200 exe 'nnoremap <buffer> <silent> <nowait> R :call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'
6201 exe 'nnoremap <buffer> <silent> <nowait> d :call <SID>NetrwMakeDir("")<cr>'
6202 exe 'vnoremap <buffer> <silent> <nowait> <del> :call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6203 exe 'vnoremap <buffer> <silent> <nowait> D :call <SID>NetrwLocalRm("'.mapsafecurdir.'")<cr>'
6204 exe 'vnoremap <buffer> <silent> <nowait> R :call <SID>NetrwLocalRename("'.mapsafecurdir.'")<cr>'
6205 nnoremap <buffer> <F1> :he netrw-quickhelp<cr>
6206
6207 " support user-specified maps
6208 call netrw#UserMaps(1)
6209
6210 else
6211 " remote normal-mode maps {{{3
6212 call s:RemotePathAnalysis(b:netrw_curdir)
6213 nnoremap <buffer> <silent> <Plug>NetrwHide_a :<c-u>call <SID>NetrwHide(0)<cr>
6214 nnoremap <buffer> <silent> <Plug>NetrwBrowseUpDir :<c-u>call <SID>NetrwBrowseUpDir(0)<cr>
6215 nnoremap <buffer> <silent> <Plug>NetrwOpenFile :<c-u>call <SID>NetrwOpenFile(0)<cr>
6216 nnoremap <buffer> <silent> <Plug>NetrwBadd_cb :<c-u>call <SID>NetrwBadd(0,0)<cr>
6217 nnoremap <buffer> <silent> <Plug>NetrwBadd_cB :<c-u>call <SID>NetrwBadd(0,1)<cr>
6218 nnoremap <buffer> <silent> <Plug>NetrwLcd :<c-u>call <SID>NetrwLcd(b:netrw_curdir)<cr>
6219 nnoremap <buffer> <silent> <Plug>NetrwSetChgwin :<c-u>call <SID>NetrwSetChgwin()<cr>
6220 nnoremap <buffer> <silent> <Plug>NetrwRefresh :<c-u>call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./',0))<cr>
6221 nnoremap <buffer> <silent> <Plug>NetrwLocalBrowseCheck :<c-u>call <SID>NetrwBrowse(0,<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord(),1))<cr>
6222 nnoremap <buffer> <silent> <Plug>NetrwServerEdit :<c-u>call <SID>NetrwServerEdit(2,<SID>NetrwGetWord())<cr>
6223 nnoremap <buffer> <silent> <Plug>NetrwBookHistHandler_gb :<c-u>call <SID>NetrwBookHistHandler(1,b:netrw_curdir)<cr>
6224 " ---------------------------------------------------------------------
6225 nnoremap <buffer> <silent> <nowait> gd :<c-u>call <SID>NetrwForceChgDir(0,<SID>NetrwGetWord())<cr>
6226 nnoremap <buffer> <silent> <nowait> gf :<c-u>call <SID>NetrwForceFile(0,<SID>NetrwGetWord())<cr>
6227 nnoremap <buffer> <silent> <nowait> gh :<c-u>call <SID>NetrwHidden(0)<cr>
6228 nnoremap <buffer> <silent> <nowait> gp :<c-u>call <SID>NetrwChgPerm(0,b:netrw_curdir)<cr>
6229 nnoremap <buffer> <silent> <nowait> I :<c-u>call <SID>NetrwBannerCtrl(1)<cr>
6230 nnoremap <buffer> <silent> <nowait> i :<c-u>call <SID>NetrwListStyle(0)<cr>
6231 nnoremap <buffer> <silent> <nowait> ma :<c-u>call <SID>NetrwMarkFileArgList(0,0)<cr>
6232 nnoremap <buffer> <silent> <nowait> mA :<c-u>call <SID>NetrwMarkFileArgList(0,1)<cr>
6233 nnoremap <buffer> <silent> <nowait> mb :<c-u>call <SID>NetrwBookHistHandler(0,b:netrw_curdir)<cr>
6234 nnoremap <buffer> <silent> <nowait> mB :<c-u>call <SID>NetrwBookHistHandler(6,b:netrw_curdir)<cr>
6235 nnoremap <buffer> <silent> <nowait> mc :<c-u>call <SID>NetrwMarkFileCopy(0)<cr>
6236 nnoremap <buffer> <silent> <nowait> md :<c-u>call <SID>NetrwMarkFileDiff(0)<cr>
6237 nnoremap <buffer> <silent> <nowait> me :<c-u>call <SID>NetrwMarkFileEdit(0)<cr>
6238 nnoremap <buffer> <silent> <nowait> mf :<c-u>call <SID>NetrwMarkFile(0,<SID>NetrwGetWord())<cr>
6239 nnoremap <buffer> <silent> <nowait> mF :<c-u>call <SID>NetrwUnmarkList(bufnr("%"),b:netrw_curdir)<cr>
6240 nnoremap <buffer> <silent> <nowait> mg :<c-u>call <SID>NetrwMarkFileGrep(0)<cr>
6241 nnoremap <buffer> <silent> <nowait> mh :<c-u>call <SID>NetrwMarkHideSfx(0)<cr>
6242 nnoremap <buffer> <silent> <nowait> mm :<c-u>call <SID>NetrwMarkFileMove(0)<cr>
6243 nnoremap <buffer> <silent> <nowait> mp :<c-u>call <SID>NetrwMarkFilePrint(0)<cr>
6244 nnoremap <buffer> <silent> <nowait> mr :<c-u>call <SID>NetrwMarkFileRegexp(0)<cr>
6245 nnoremap <buffer> <silent> <nowait> ms :<c-u>call <SID>NetrwMarkFileSource(0)<cr>
6246 nnoremap <buffer> <silent> <nowait> mT :<c-u>call <SID>NetrwMarkFileTag(0)<cr>
6247 nnoremap <buffer> <silent> <nowait> mt :<c-u>call <SID>NetrwMarkFileTgt(0)<cr>
6248 nnoremap <buffer> <silent> <nowait> mu :<c-u>call <SID>NetrwUnMarkFile(0)<cr>
6249 nnoremap <buffer> <silent> <nowait> mv :<c-u>call <SID>NetrwMarkFileVimCmd(0)<cr>
6250 nnoremap <buffer> <silent> <nowait> mx :<c-u>call <SID>NetrwMarkFileExe(0,0)<cr>
6251 nnoremap <buffer> <silent> <nowait> mX :<c-u>call <SID>NetrwMarkFileExe(0,1)<cr>
6252 nnoremap <buffer> <silent> <nowait> mz :<c-u>call <SID>NetrwMarkFileCompress(0)<cr>
6253 nnoremap <buffer> <silent> <nowait> O :<c-u>call <SID>NetrwObtain(0)<cr>
6254 nnoremap <buffer> <silent> <nowait> o :call <SID>NetrwSplit(0)<cr>
6255 nnoremap <buffer> <silent> <nowait> p :<c-u>call <SID>NetrwPreview(<SID>NetrwBrowseChgDir(1,<SID>NetrwGetWord(),1,1))<cr>
6256 nnoremap <buffer> <silent> <nowait> P :<c-u>call <SID>NetrwPrevWinOpen(0)<cr>
6257 nnoremap <buffer> <silent> <nowait> qb :<c-u>call <SID>NetrwBookHistHandler(2,b:netrw_curdir)<cr>
6258 nnoremap <buffer> <silent> <nowait> qf :<c-u>call <SID>NetrwFileInfo(0,<SID>NetrwGetWord())<cr>
6259 nnoremap <buffer> <silent> <nowait> qF :<c-u>call <SID>NetrwMarkFileQFEL(0,getqflist())<cr>
6260 nnoremap <buffer> <silent> <nowait> qL :<c-u>call <SID>NetrwMarkFileQFEL(0,getloclist(v:count))<cr>
6261 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>
6262 nnoremap <buffer> <silent> <nowait> s :call <SID>NetrwSortStyle(0)<cr>
6263 nnoremap <buffer> <silent> <nowait> S :<c-u>call <SID>NetSortSequence(0)<cr>
6264 nnoremap <buffer> <silent> <nowait> Tb :<c-u>call <SID>NetrwSetTgt(0,'b',v:count1)<cr>
6265 nnoremap <buffer> <silent> <nowait> t :call <SID>NetrwSplit(1)<cr>
6266 nnoremap <buffer> <silent> <nowait> Th :<c-u>call <SID>NetrwSetTgt(0,'h',v:count)<cr>
6267 nnoremap <buffer> <silent> <nowait> u :<c-u>call <SID>NetrwBookHistHandler(4,b:netrw_curdir)<cr>
6268 nnoremap <buffer> <silent> <nowait> U :<c-u>call <SID>NetrwBookHistHandler(5,b:netrw_curdir)<cr>
6269 nnoremap <buffer> <silent> <nowait> v :call <SID>NetrwSplit(2)<cr>
6270 nnoremap <buffer> <silent> <nowait> x :<c-u>call netrw#BrowseX(<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord(),1),1)<cr>
6271 nmap <buffer> <nowait> gx x
6272 if !hasmapto('<Plug>NetrwHideEdit')
6273 nmap <buffer> <c-h> <Plug>NetrwHideEdit
6274 endif
6275 nnoremap <buffer> <silent> <Plug>NetrwHideEdit :call <SID>NetrwHideEdit(0)<cr>
6276 if !hasmapto('<Plug>NetrwRefresh')
6277 nmap <buffer> <c-l> <Plug>NetrwRefresh
6278 endif
6279 if !hasmapto('<Plug>NetrwTreeSqueeze')
6280 nmap <buffer> <silent> <nowait> <s-cr> <Plug>NetrwTreeSqueeze
6281 endif
6282 nnoremap <buffer> <silent> <Plug>NetrwTreeSqueeze :call <SID>TreeSqueezeDir(0)<cr>
6283
6284 let mapsafepath = escape(s:path, s:netrw_map_escape)
6285 let mapsafeusermach = escape(((s:user == "")? "" : s:user."@").s:machine, s:netrw_map_escape)
6286
6287 nnoremap <buffer> <silent> <Plug>NetrwRefresh :call <SID>NetrwRefresh(0,<SID>NetrwBrowseChgDir(0,'./',0))<cr>
6288 if g:netrw_mousemaps == 1
6289 nmap <buffer> <leftmouse> <Plug>NetrwLeftmouse
6290 nno <buffer> <silent> <Plug>NetrwLeftmouse :exec "norm! \<lt>leftmouse>"<bar>call <SID>NetrwLeftmouse(0)<cr>
6291 nmap <buffer> <c-leftmouse> <Plug>NetrwCLeftmouse
6292 nno <buffer> <silent> <Plug>NetrwCLeftmouse :exec "norm! \<lt>leftmouse>"<bar>call <SID>NetrwCLeftmouse(0)<cr>
6293 nmap <buffer> <s-leftmouse> <Plug>NetrwSLeftmouse
6294 nno <buffer> <silent> <Plug>NetrwSLeftmouse :exec "norm! \<lt>leftmouse>"<bar>call <SID>NetrwSLeftmouse(0)<cr>
6295 nmap <buffer> <s-leftdrag> <Plug>NetrwSLeftdrag
6296 nno <buffer> <silent> <Plug>NetrwSLeftdrag :exec "norm! \<lt>leftmouse>"<bar>call <SID>NetrwSLeftdrag(0)<cr>
6297 nmap <middlemouse> <Plug>NetrwMiddlemouse
6298 nno <buffer> <silent> <middlemouse> <Plug>NetrwMiddlemouse :exec "norm! \<lt>leftmouse>"<bar>call <SID>NetrwPrevWinOpen(0)<cr>
6299 nmap <buffer> <2-leftmouse> <Plug>Netrw2Leftmouse
6300 nmap <buffer> <silent> <Plug>Netrw2Leftmouse -
6301 imap <buffer> <leftmouse> <Plug>ILeftmouse
6302 imap <buffer> <middlemouse> <Plug>IMiddlemouse
6303 imap <buffer> <s-leftmouse> <Plug>ISLeftmouse
6304 exe 'nnoremap <buffer> <silent> <rightmouse> :exec "norm! \<lt>leftmouse>"<bar>call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6305 exe 'vnoremap <buffer> <silent> <rightmouse> :exec "norm! \<lt>leftmouse>"<bar>call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6306 endif
6307 exe 'nnoremap <buffer> <silent> <nowait> <del> :call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6308 exe 'nnoremap <buffer> <silent> <nowait> d :call <SID>NetrwMakeDir("'.mapsafeusermach.'")<cr>'
6309 exe 'nnoremap <buffer> <silent> <nowait> D :call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6310 exe 'nnoremap <buffer> <silent> <nowait> R :call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6311 exe 'vnoremap <buffer> <silent> <nowait> <del> :call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6312 exe 'vnoremap <buffer> <silent> <nowait> D :call <SID>NetrwRemoteRm("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6313 exe 'vnoremap <buffer> <silent> <nowait> R :call <SID>NetrwRemoteRename("'.mapsafeusermach.'","'.mapsafepath.'")<cr>'
6314 nnoremap <buffer> <F1> :he netrw-quickhelp<cr>
6315
6316 " support user-specified maps
6317 call netrw#UserMaps(0)
6318 endif " }}}3
6319endfun
6320
6321" ---------------------------------------------------------------------
6322" s:NetrwCommands: set up commands {{{2
6323" If -buffer, the command is only available from within netrw buffers
6324" Otherwise, the command is available from any window, so long as netrw
6325" has been used at least once in the session.
6326fun! s:NetrwCommands(islocal)
6327 " call Dfunc("s:NetrwCommands(islocal=".a:islocal.")")
6328
6329 com! -nargs=* -complete=file -bang NetrwMB call s:NetrwBookmark(<bang>0,<f-args>)
6330 com! -nargs=* NetrwC call s:NetrwSetChgwin(<q-args>)
6331 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
6332 if a:islocal
6333 com! -buffer -nargs=+ -complete=file MF call s:NetrwMarkFiles(1,<f-args>)
6334 else
6335 com! -buffer -nargs=+ -complete=file MF call s:NetrwMarkFiles(0,<f-args>)
6336 endif
6337 com! -buffer -nargs=? -complete=file MT call s:NetrwMarkTarget(<q-args>)
6338
6339 " call Dret("s:NetrwCommands")
6340endfun
6341
6342" ---------------------------------------------------------------------
6343" s:NetrwMarkFiles: apply s:NetrwMarkFile() to named file(s) {{{2
6344" glob()ing only works with local files
6345fun! s:NetrwMarkFiles(islocal,...)
6346 " call Dfunc("s:NetrwMarkFiles(islocal=".a:islocal."...) a:0=".a:0)
6347 let curdir = s:NetrwGetCurdir(a:islocal)
6348 let i = 1
6349 while i <= a:0
6350 if a:islocal
6351 if v:version > 704 || (v:version == 704 && has("patch656"))
6352 let mffiles= glob(a:{i},0,1,1)
6353 else
6354 let mffiles= glob(a:{i},0,1)
6355 endif
6356 else
6357 let mffiles= [a:{i}]
6358 endif
6359 " call Decho("mffiles".string(mffiles),'~'.expand("<slnum>"))
6360 for mffile in mffiles
6361 " call Decho("mffile<".mffile.">",'~'.expand("<slnum>"))
6362 call s:NetrwMarkFile(a:islocal,mffile)
6363 endfor
6364 let i= i + 1
6365 endwhile
6366 " call Dret("s:NetrwMarkFiles")
6367endfun
6368
6369" ---------------------------------------------------------------------
6370" s:NetrwMarkTarget: implements :MT (mark target) {{{2
6371fun! s:NetrwMarkTarget(...)
6372 if a:0 == 0 || (a:0 == 1 && a:1 == "")
6373 let curdir = s:NetrwGetCurdir(1)
6374 let tgt = b:netrw_curdir
6375 else
6376 let curdir = s:NetrwGetCurdir((a:1 =~ '^\a\{3,}://')? 0 : 1)
6377 let tgt = a:1
6378 endif
6379 let s:netrwmftgt = tgt
6380 let s:netrwmftgt_islocal = tgt !~ '^\a\{3,}://'
6381 let curislocal = b:netrw_curdir !~ '^\a\{3,}://'
6382 let svpos = winsaveview()
6383 call s:NetrwRefresh(curislocal,s:NetrwBrowseChgDir(curislocal,'./',0))
6384 call winrestview(svpos)
6385endfun
6386
6387" ---------------------------------------------------------------------
6388" s:NetrwMarkFile: (invoked by mf) This function is used to both {{{2
6389" mark and unmark files. If a markfile list exists,
6390" then the rename and delete functions will use it instead
6391" of whatever may happen to be under the cursor at that
6392" moment. When the mouse and gui are available,
6393" shift-leftmouse may also be used to mark files.
6394"
6395" Creates two lists
6396" s:netrwmarkfilelist -- holds complete paths to all marked files
6397" s:netrwmarkfilelist_# -- holds list of marked files in current-buffer's directory (#==bufnr())
6398"
6399" Creates a marked file match string
6400" s:netrwmarfilemtch_# -- used with 2match to display marked files
6401"
6402" Creates a buffer version of islocal
6403" b:netrw_islocal
6404fun! s:NetrwMarkFile(islocal,fname)
6405 " call Dfunc("s:NetrwMarkFile(islocal=".a:islocal." fname<".a:fname.">)")
6406 " call Decho("bufnr(%)=".bufnr("%").": ".bufname("%"),'~'.expand("<slnum>"))
6407
6408 " sanity check
6409 if empty(a:fname)
6410 " call Dret("s:NetrwMarkFile : empty fname")
6411 return
6412 endif
6413 let curdir = s:NetrwGetCurdir(a:islocal)
6414
6415 let ykeep = @@
6416 let curbufnr= bufnr("%")
6417 let leader= '\%(^\|\s\)\zs'
6418 if a:fname =~ '\a$'
6419 let trailer = '\>[@=|\/\*]\=\ze\%( \|\t\|$\)'
6420 else
6421 let trailer = '[@=|\/\*]\=\ze\%( \|\t\|$\)'
6422 endif
6423
6424 if exists("s:netrwmarkfilelist_".curbufnr)
6425 " markfile list pre-exists
6426 " call Decho("case s:netrwmarkfilelist_".curbufnr." already exists",'~'.expand("<slnum>"))
6427 " call Decho("starting s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6428 " call Decho("starting s:netrwmarkfilemtch_".curbufnr."<".s:netrwmarkfilemtch_{curbufnr}.">",'~'.expand("<slnum>"))
6429 let b:netrw_islocal= a:islocal
6430
6431 if index(s:netrwmarkfilelist_{curbufnr},a:fname) == -1
6432 " append filename to buffer's markfilelist
6433 " call Decho("append filename<".a:fname."> to local markfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6434 call add(s:netrwmarkfilelist_{curbufnr},a:fname)
6435 let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.'\|'.leader.escape(a:fname,g:netrw_markfileesc).trailer
Luca Saccarolac363ca12024-12-19 20:16:18 +01006436
Bram Moolenaarc236c162008-07-13 17:41:49 +00006437 else
shane.xb.qianc673b802024-12-20 19:36:40 +01006438 " remove filename from buffer's markfilelist
6439 " call Decho("remove filename<".a:fname."> from local markfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6440 call filter(s:netrwmarkfilelist_{curbufnr},'v:val != a:fname')
6441 if s:netrwmarkfilelist_{curbufnr} == []
6442 " local markfilelist is empty; remove it entirely
6443 " call Decho("markfile list now empty",'~'.expand("<slnum>"))
6444 call s:NetrwUnmarkList(curbufnr,curdir)
6445 else
6446 " rebuild match list to display markings correctly
6447 " call Decho("rebuild s:netrwmarkfilemtch_".curbufnr,'~'.expand("<slnum>"))
6448 let s:netrwmarkfilemtch_{curbufnr}= ""
6449 let first = 1
6450 for fname in s:netrwmarkfilelist_{curbufnr}
6451 if first
6452 let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.leader.escape(fname,g:netrw_markfileesc).trailer
6453 else
6454 let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.'\|'.leader.escape(fname,g:netrw_markfileesc).trailer
6455 endif
6456 let first= 0
6457 endfor
6458 " call Decho("ending s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6459 endif
6460 endif
Bram Moolenaarc236c162008-07-13 17:41:49 +00006461
shane.xb.qianc673b802024-12-20 19:36:40 +01006462 else
6463 " initialize new markfilelist
6464 " call Decho("case: initialize new markfilelist",'~'.expand("<slnum>"))
6465
6466 " call Decho("add fname<".a:fname."> to new markfilelist_".curbufnr,'~'.expand("<slnum>"))
6467 let s:netrwmarkfilelist_{curbufnr}= []
6468 call add(s:netrwmarkfilelist_{curbufnr},substitute(a:fname,'[|@]$','',''))
6469 " call Decho("ending s:netrwmarkfilelist_{curbufnr}<".string(s:netrwmarkfilelist_{curbufnr}).">",'~'.expand("<slnum>"))
6470
6471 " build initial markfile matching pattern
6472 if a:fname =~ '/$'
6473 let s:netrwmarkfilemtch_{curbufnr}= leader.escape(a:fname,g:netrw_markfileesc)
6474 else
6475 let s:netrwmarkfilemtch_{curbufnr}= leader.escape(a:fname,g:netrw_markfileesc).trailer
6476 endif
6477 " call Decho("ending s:netrwmarkfilemtch_".curbufnr."<".s:netrwmarkfilemtch_{curbufnr}.">",'~'.expand("<slnum>"))
6478 endif
6479
6480 " handle global markfilelist
6481 if exists("s:netrwmarkfilelist")
6482 let dname= s:ComposePath(b:netrw_curdir,a:fname)
6483 if index(s:netrwmarkfilelist,dname) == -1
6484 " append new filename to global markfilelist
6485 call add(s:netrwmarkfilelist,s:ComposePath(b:netrw_curdir,a:fname))
6486 " call Decho("append filename<".a:fname."> to global s:markfilelist<".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
6487 else
6488 " remove new filename from global markfilelist
6489 " call Decho("remove new filename from global s:markfilelist",'~'.expand("<slnum>"))
6490 " call Decho("..filter(".string(s:netrwmarkfilelist).",'v:val != '.".dname.")",'~'.expand("<slnum>"))
6491 call filter(s:netrwmarkfilelist,'v:val != "'.dname.'"')
6492 " call Decho("..ending s:netrwmarkfilelist <".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
6493 if s:netrwmarkfilelist == []
6494 " call Decho("s:netrwmarkfilelist is empty; unlet it",'~'.expand("<slnum>"))
6495 unlet s:netrwmarkfilelist
6496 endif
6497 endif
6498 else
6499 " initialize new global-directory markfilelist
6500 let s:netrwmarkfilelist= []
6501 call add(s:netrwmarkfilelist,s:ComposePath(b:netrw_curdir,a:fname))
6502 " call Decho("init s:netrwmarkfilelist<".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
6503 endif
6504
6505 " set up 2match'ing to netrwmarkfilemtch_# list
6506 if has("syntax") && exists("g:syntax_on") && g:syntax_on
6507 if exists("s:netrwmarkfilemtch_{curbufnr}") && s:netrwmarkfilemtch_{curbufnr} != ""
6508 " " call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{curbufnr}."/",'~'.expand("<slnum>"))
6509 if exists("g:did_drchip_netrwlist_syntax")
6510 exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{curbufnr}."/"
6511 endif
6512 else
6513 " " call Decho("2match none",'~'.expand("<slnum>"))
6514 2match none
6515 endif
6516 endif
6517 let @@= ykeep
6518 " call Decho("s:netrwmarkfilelist[".(exists("s:netrwmarkfilelist")? string(s:netrwmarkfilelist) : "")."] (avail in all buffers)",'~'.expand("<slnum>"))
6519 " call Dret("s:NetrwMarkFile : s:netrwmarkfilelist_".curbufnr."<".(exists("s:netrwmarkfilelist_{curbufnr}")? string(s:netrwmarkfilelist_{curbufnr}) : " doesn't exist")."> (buf#".curbufnr."list)")
6520endfun
6521
6522" ---------------------------------------------------------------------
6523" s:NetrwMarkFileArgList: ma: move the marked file list to the argument list (tomflist=0) {{{2
6524" mA: move the argument list to marked file list (tomflist=1)
6525" Uses the global marked file list
6526fun! s:NetrwMarkFileArgList(islocal,tomflist)
6527 let svpos = winsaveview()
6528 let curdir = s:NetrwGetCurdir(a:islocal)
6529 let curbufnr = bufnr("%")
6530
6531 if a:tomflist
6532 " mA: move argument list to marked file list
6533 while argc()
6534 let fname= argv(0)
6535 exe "argdel ".fnameescape(fname)
6536 call s:NetrwMarkFile(a:islocal,fname)
6537 endwhile
6538
6539 else
6540 " ma: move marked file list to argument list
6541 if exists("s:netrwmarkfilelist")
6542
6543 " for every filename in the marked list
6544 for fname in s:netrwmarkfilelist
6545 exe "argadd ".fnameescape(fname)
6546 endfor " for every file in the marked list
6547
6548 " unmark list and refresh
6549 call s:NetrwUnmarkList(curbufnr,curdir)
6550 NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
6551 NetrwKeepj call winrestview(svpos)
6552 endif
6553 endif
6554endfun
6555
6556" ---------------------------------------------------------------------
6557" s:NetrwMarkFileCompress: (invoked by mz) This function is used to {{{2
6558" compress/decompress files using the programs
6559" in g:netrw_compress and g:netrw_uncompress,
6560" using g:netrw_compress_suffix to know which to
6561" do. By default:
6562" g:netrw_compress = "gzip"
6563" g:netrw_decompress = { ".gz" : "gunzip" , ".bz2" : "bunzip2" , ".zip" : "unzip" , ".tar" : "tar -xf", ".xz" : "unxz"}
6564fun! s:NetrwMarkFileCompress(islocal)
6565 let svpos = winsaveview()
6566 let curdir = s:NetrwGetCurdir(a:islocal)
6567 let curbufnr = bufnr("%")
6568
6569 " sanity check
6570 if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
6571 NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
6572 return
6573 endif
6574
6575 if exists("s:netrwmarkfilelist_{curbufnr}") && exists("g:netrw_compress") && exists("g:netrw_decompress")
6576
6577 " for every filename in the marked list
6578 for fname in s:netrwmarkfilelist_{curbufnr}
6579 let sfx= substitute(fname,'^.\{-}\(\.[[:alnum:]]\+\)$','\1','')
6580 if exists("g:netrw_decompress['".sfx."']")
6581 " fname has a suffix indicating that its compressed; apply associated decompression routine
6582 let exe= g:netrw_decompress[sfx]
6583 let exe= netrw#WinPath(exe)
6584 if a:islocal
6585 if g:netrw_keepdir
6586 let fname= s:ShellEscape(s:ComposePath(curdir,fname))
6587 endif
6588 call system(exe." ".fname)
6589 if v:shell_error
6590 NetrwKeepj call netrw#ErrorMsg(s:WARNING,"unable to apply<".exe."> to file<".fname.">",50)
6591 endif
6592 else
6593 let fname= s:ShellEscape(b:netrw_curdir.fname,1)
6594 NetrwKeepj call s:RemoteSystem(exe." ".fname)
6595 endif
6596
6597 endif
6598 unlet sfx
6599
6600 if exists("exe")
6601 unlet exe
6602 elseif a:islocal
6603 " fname not a compressed file, so compress it
6604 call system(netrw#WinPath(g:netrw_compress)." ".s:ShellEscape(s:ComposePath(b:netrw_curdir,fname)))
6605 if v:shell_error
6606 call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_compress<".g:netrw_compress."> to something that works",104)
6607 endif
6608 else
6609 " fname not a compressed file, so compress it
6610 NetrwKeepj call s:RemoteSystem(netrw#WinPath(g:netrw_compress)." ".s:ShellEscape(fname))
6611 endif
6612 endfor " for every file in the marked list
6613
6614 call s:NetrwUnmarkList(curbufnr,curdir)
6615 NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
6616 NetrwKeepj call winrestview(svpos)
6617 endif
6618endfun
6619
6620" ---------------------------------------------------------------------
6621" s:NetrwMarkFileCopy: (invoked by mc) copy marked files to target {{{2
6622" If no marked files, then set up directory as the
6623" target. Currently does not support copying entire
6624" directories. Uses the local-buffer marked file list.
6625" Returns 1=success (used by NetrwMarkFileMove())
6626" 0=failure
6627fun! s:NetrwMarkFileCopy(islocal,...)
6628 " call Dfunc("s:NetrwMarkFileCopy(islocal=".a:islocal.") target<".(exists("s:netrwmftgt")? s:netrwmftgt : '---')."> a:0=".a:0)
6629
6630 let curdir = s:NetrwGetCurdir(a:islocal)
6631 let curbufnr = bufnr("%")
6632 if b:netrw_curdir !~ '/$'
6633 if !exists("b:netrw_curdir")
6634 let b:netrw_curdir= curdir
6635 endif
6636 let b:netrw_curdir= b:netrw_curdir."/"
6637 endif
6638
6639 " sanity check
6640 if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
6641 NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
6642 " call Dret("s:NetrwMarkFileCopy")
6643 return
6644 endif
6645 " call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
6646
6647 if !exists("s:netrwmftgt")
6648 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"your marked file target is empty! (:help netrw-mt)",67)
6649 " call Dret("s:NetrwMarkFileCopy 0")
6650 return 0
6651 endif
6652 " call Decho("sanity chk passed: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
6653
6654 if a:islocal && s:netrwmftgt_islocal
6655 " Copy marked files, local directory to local directory
6656 " call Decho("copy from local to local",'~'.expand("<slnum>"))
6657 if !executable(g:netrw_localcopycmd)
6658 call netrw#ErrorMsg(s:ERROR,"g:netrw_localcopycmd<".g:netrw_localcopycmd."> not executable on your system, aborting",91)
6659 " call Dfunc("s:NetrwMarkFileMove : g:netrw_localcopycmd<".g:netrw_localcopycmd."> n/a!")
6660 return
6661 endif
6662
6663 " copy marked files while within the same directory (ie. allow renaming)
6664 if s:StripTrailingSlash(simplify(s:netrwmftgt)) == s:StripTrailingSlash(simplify(b:netrw_curdir))
6665 if len(s:netrwmarkfilelist_{bufnr('%')}) == 1
6666 " only one marked file
6667 " call Decho("case: only one marked file",'~'.expand("<slnum>"))
6668 let args = s:ShellEscape(b:netrw_curdir.s:netrwmarkfilelist_{bufnr('%')}[0])
6669 let oldname = s:netrwmarkfilelist_{bufnr('%')}[0]
6670 elseif a:0 == 1
6671 " call Decho("case: handling one input argument",'~'.expand("<slnum>"))
6672 " this happens when the next case was used to recursively call s:NetrwMarkFileCopy()
6673 let args = s:ShellEscape(b:netrw_curdir.a:1)
6674 let oldname = a:1
6675 else
6676 " copy multiple marked files inside the same directory
6677 " call Decho("case: handling a multiple marked files",'~'.expand("<slnum>"))
6678 let s:recursive= 1
6679 for oldname in s:netrwmarkfilelist_{bufnr("%")}
6680 let ret= s:NetrwMarkFileCopy(a:islocal,oldname)
6681 if ret == 0
6682 break
6683 endif
6684 endfor
6685 unlet s:recursive
6686 call s:NetrwUnmarkList(curbufnr,curdir)
6687 " call Dret("s:NetrwMarkFileCopy ".ret)
6688 return ret
Bram Moolenaar446cb832008-06-24 21:56:24 +00006689 endif
6690
shane.xb.qianc673b802024-12-20 19:36:40 +01006691 call inputsave()
6692 let newname= input("Copy ".oldname." to : ",oldname,"file")
6693 call inputrestore()
6694 if newname == ""
6695 " call Dret("s:NetrwMarkFileCopy 0")
6696 return 0
6697 endif
6698 let args= s:ShellEscape(oldname)
6699 let tgt = s:ShellEscape(s:netrwmftgt.'/'.newname)
6700 else
6701 let args= join(map(deepcopy(s:netrwmarkfilelist_{bufnr('%')}),"s:ShellEscape(b:netrw_curdir.\"/\".v:val)"))
6702 let tgt = s:ShellEscape(s:netrwmftgt)
6703 endif
6704 if !g:netrw_cygwin && has("win32")
6705 let args= substitute(args,'/','\\','g')
6706 let tgt = substitute(tgt, '/','\\','g')
6707 endif
6708 if args =~ "'" |let args= substitute(args,"'\\(.*\\)'",'\1','')|endif
6709 if tgt =~ "'" |let tgt = substitute(tgt ,"'\\(.*\\)'",'\1','')|endif
6710 if args =~ '//'|let args= substitute(args,'//','/','g')|endif
6711 if tgt =~ '//'|let tgt = substitute(tgt ,'//','/','g')|endif
6712 " call Decho("args <".args.">",'~'.expand("<slnum>"))
6713 " call Decho("tgt <".tgt.">",'~'.expand("<slnum>"))
6714 if isdirectory(s:NetrwFile(args))
6715 " call Decho("args<".args."> is a directory",'~'.expand("<slnum>"))
6716 let copycmd= g:netrw_localcopydircmd
6717 " call Decho("using copydircmd<".copycmd.">",'~'.expand("<slnum>"))
6718 if !g:netrw_cygwin && has("win32")
6719 " window's xcopy doesn't copy a directory to a target properly. Instead, it copies a directory's
6720 " contents to a target. One must append the source directory name to the target to get xcopy to
6721 " do the right thing.
6722 let tgt= tgt.'\'.substitute(a:1,'^.*[\\/]','','')
6723 " call Decho("modified tgt for xcopy",'~'.expand("<slnum>"))
6724 endif
6725 else
6726 let copycmd= g:netrw_localcopycmd
6727 endif
6728 if g:netrw_localcopycmd =~ '\s'
6729 let copycmd = substitute(copycmd,'\s.*$','','')
6730 let copycmdargs = substitute(copycmd,'^.\{-}\(\s.*\)$','\1','')
6731 let copycmd = netrw#WinPath(copycmd).copycmdargs
6732 else
6733 let copycmd = netrw#WinPath(copycmd)
6734 endif
6735 " call Decho("args <".args.">",'~'.expand("<slnum>"))
6736 " call Decho("tgt <".tgt.">",'~'.expand("<slnum>"))
6737 " call Decho("copycmd<".copycmd.">",'~'.expand("<slnum>"))
6738 " call Decho("system(".copycmd." '".args."' '".tgt."')",'~'.expand("<slnum>"))
6739 call system(copycmd.g:netrw_localcopycmdopt." '".args."' '".tgt."'")
6740 if v:shell_error != 0
6741 if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && g:netrw_keepdir
6742 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)
6743 else
6744 call netrw#ErrorMsg(s:ERROR,"tried using g:netrw_localcopycmd<".g:netrw_localcopycmd.">; it doesn't work!",80)
6745 endif
6746 " call Dret("s:NetrwMarkFileCopy 0 : failed: system(".g:netrw_localcopycmd." ".args." ".s:ShellEscape(s:netrwmftgt))
6747 return 0
6748 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00006749
shane.xb.qianc673b802024-12-20 19:36:40 +01006750 elseif a:islocal && !s:netrwmftgt_islocal
6751 " Copy marked files, local directory to remote directory
6752 " call Decho("copy from local to remote",'~'.expand("<slnum>"))
6753 NetrwKeepj call s:NetrwUpload(s:netrwmarkfilelist_{bufnr('%')},s:netrwmftgt)
6754
6755 elseif !a:islocal && s:netrwmftgt_islocal
6756 " Copy marked files, remote directory to local directory
6757 " call Decho("copy from remote to local",'~'.expand("<slnum>"))
6758 NetrwKeepj call netrw#Obtain(a:islocal,s:netrwmarkfilelist_{bufnr('%')},s:netrwmftgt)
6759
6760 elseif !a:islocal && !s:netrwmftgt_islocal
6761 " Copy marked files, remote directory to remote directory
6762 " call Decho("copy from remote to remote",'~'.expand("<slnum>"))
6763 let curdir = getcwd()
6764 let tmpdir = s:GetTempfile("")
6765 if tmpdir !~ '/'
6766 let tmpdir= curdir."/".tmpdir
6767 endif
6768 if exists("*mkdir")
6769 call mkdir(tmpdir)
6770 else
6771 call s:NetrwExe("sil! !".g:netrw_localmkdir.g:netrw_localmkdiropt.' '.s:ShellEscape(tmpdir,1))
6772 if v:shell_error != 0
6773 call netrw#ErrorMsg(s:WARNING,"consider setting g:netrw_localmkdir<".g:netrw_localmkdir."> to something that works",80)
6774 " call Dret("s:NetrwMarkFileCopy : failed: sil! !".g:netrw_localmkdir.' '.s:ShellEscape(tmpdir,1) )
6775 return
6776 endif
6777 endif
6778 if isdirectory(s:NetrwFile(tmpdir))
6779 if s:NetrwLcd(tmpdir)
6780 " call Dret("s:NetrwMarkFileCopy : lcd failure")
6781 return
6782 endif
6783 NetrwKeepj call netrw#Obtain(a:islocal,s:netrwmarkfilelist_{bufnr('%')},tmpdir)
6784 let localfiles= map(deepcopy(s:netrwmarkfilelist_{bufnr('%')}),'substitute(v:val,"^.*/","","")')
6785 NetrwKeepj call s:NetrwUpload(localfiles,s:netrwmftgt)
6786 if getcwd() == tmpdir
6787 for fname in s:netrwmarkfilelist_{bufnr('%')}
6788 NetrwKeepj call s:NetrwDelete(fname)
6789 endfor
6790 if s:NetrwLcd(curdir)
6791 " call Dret("s:NetrwMarkFileCopy : lcd failure")
6792 return
6793 endif
6794 if delete(tmpdir,"d")
6795 call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".tmpdir.">!",103)
6796 endif
6797 else
6798 if s:NetrwLcd(curdir)
6799 " call Dret("s:NetrwMarkFileCopy : lcd failure")
6800 return
6801 endif
6802 endif
6803 endif
6804 endif
6805
6806 " -------
6807 " cleanup
6808 " -------
6809 " call Decho("cleanup",'~'.expand("<slnum>"))
6810 " remove markings from local buffer
6811 call s:NetrwUnmarkList(curbufnr,curdir) " remove markings from local buffer
6812 " call Decho(" g:netrw_fastbrowse =".g:netrw_fastbrowse,'~'.expand("<slnum>"))
6813 " call Decho(" s:netrwmftgt =".s:netrwmftgt,'~'.expand("<slnum>"))
6814 " call Decho(" s:netrwmftgt_islocal=".s:netrwmftgt_islocal,'~'.expand("<slnum>"))
6815 " call Decho(" curdir =".curdir,'~'.expand("<slnum>"))
6816 " call Decho(" a:islocal =".a:islocal,'~'.expand("<slnum>"))
6817 " call Decho(" curbufnr =".curbufnr,'~'.expand("<slnum>"))
6818 if exists("s:recursive")
6819 " call Decho(" s:recursive =".s:recursive,'~'.expand("<slnum>"))
6820 else
6821 " call Decho(" s:recursive =n/a",'~'.expand("<slnum>"))
6822 endif
6823 " see s:LocalFastBrowser() for g:netrw_fastbrowse interpretation (refreshing done for both slow and medium)
6824 if g:netrw_fastbrowse <= 1
6825 NetrwKeepj call s:LocalBrowseRefresh()
6826 else
6827 " refresh local and targets for fast browsing
6828 if !exists("s:recursive")
6829 " remove markings from local buffer
6830 " call Decho(" remove markings from local buffer",'~'.expand("<slnum>"))
6831 NetrwKeepj call s:NetrwUnmarkList(curbufnr,curdir)
6832 endif
6833
6834 " refresh buffers
6835 if s:netrwmftgt_islocal
6836 " call Decho(" refresh s:netrwmftgt=".s:netrwmftgt,'~'.expand("<slnum>"))
6837 NetrwKeepj call s:NetrwRefreshDir(s:netrwmftgt_islocal,s:netrwmftgt)
6838 endif
6839 if a:islocal && s:netrwmftgt != curdir
6840 " call Decho(" refresh curdir=".curdir,'~'.expand("<slnum>"))
6841 NetrwKeepj call s:NetrwRefreshDir(a:islocal,curdir)
6842 endif
6843 endif
6844
6845 " call Dret("s:NetrwMarkFileCopy 1")
6846 return 1
6847endfun
6848
6849" ---------------------------------------------------------------------
6850" s:NetrwMarkFileDiff: (invoked by md) This function is used to {{{2
6851" invoke vim's diff mode on the marked files.
6852" Either two or three files can be so handled.
6853" Uses the global marked file list.
6854fun! s:NetrwMarkFileDiff(islocal)
6855 " call Dfunc("s:NetrwMarkFileDiff(islocal=".a:islocal.") b:netrw_curdir<".b:netrw_curdir.">")
6856 let curbufnr= bufnr("%")
6857
6858 " sanity check
6859 if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
6860 NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
6861 " call Dret("s:NetrwMarkFileDiff")
6862 return
6863 endif
6864 let curdir= s:NetrwGetCurdir(a:islocal)
6865 " call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
6866
6867 if exists("s:netrwmarkfilelist_{".curbufnr."}")
6868 let cnt = 0
6869 for fname in s:netrwmarkfilelist
6870 let cnt= cnt + 1
6871 if cnt == 1
6872 " call Decho("diffthis: fname<".fname.">",'~'.expand("<slnum>"))
6873 exe "NetrwKeepj e ".fnameescape(fname)
6874 diffthis
6875 elseif cnt == 2 || cnt == 3
6876 below vsplit
6877 " call Decho("diffthis: ".fname,'~'.expand("<slnum>"))
6878 exe "NetrwKeepj e ".fnameescape(fname)
6879 diffthis
6880 else
6881 break
6882 endif
6883 endfor
6884 call s:NetrwUnmarkList(curbufnr,curdir)
6885 endif
6886
6887 " call Dret("s:NetrwMarkFileDiff")
6888endfun
6889
6890" ---------------------------------------------------------------------
6891" s:NetrwMarkFileEdit: (invoked by me) put marked files on arg list and start editing them {{{2
6892" Uses global markfilelist
6893fun! s:NetrwMarkFileEdit(islocal)
6894 " call Dfunc("s:NetrwMarkFileEdit(islocal=".a:islocal.")")
6895
6896 let curdir = s:NetrwGetCurdir(a:islocal)
6897 let curbufnr = bufnr("%")
6898
6899 " sanity check
6900 if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
6901 NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
6902 " call Dret("s:NetrwMarkFileEdit")
6903 return
6904 endif
6905 " call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
6906
6907 if exists("s:netrwmarkfilelist_{curbufnr}")
6908 call s:SetRexDir(a:islocal,curdir)
6909 let flist= join(map(deepcopy(s:netrwmarkfilelist), "fnameescape(v:val)"))
6910 " unmark markedfile list
6911 " call s:NetrwUnmarkList(curbufnr,curdir)
6912 call s:NetrwUnmarkAll()
6913 " call Decho("exe sil args ".flist,'~'.expand("<slnum>"))
6914 exe "sil args ".flist
6915 endif
6916 echo "(use :bn, :bp to navigate files; :Rex to return)"
6917
6918 " call Dret("s:NetrwMarkFileEdit")
6919endfun
6920
6921" ---------------------------------------------------------------------
6922" s:NetrwMarkFileQFEL: convert a quickfix-error or location list into a marked file list {{{2
6923fun! s:NetrwMarkFileQFEL(islocal,qfel)
6924 " call Dfunc("s:NetrwMarkFileQFEL(islocal=".a:islocal.",qfel)")
6925 call s:NetrwUnmarkAll()
6926 let curbufnr= bufnr("%")
6927
6928 if !empty(a:qfel)
6929 for entry in a:qfel
6930 let bufnmbr= entry["bufnr"]
6931 " call Decho("bufname(".bufnmbr.")<".bufname(bufnmbr)."> line#".entry["lnum"]." text=".entry["text"],'~'.expand("<slnum>"))
6932 if !exists("s:netrwmarkfilelist_{curbufnr}")
6933 " call Decho("case: no marked file list",'~'.expand("<slnum>"))
6934 call s:NetrwMarkFile(a:islocal,bufname(bufnmbr))
6935 elseif index(s:netrwmarkfilelist_{curbufnr},bufname(bufnmbr)) == -1
6936 " s:NetrwMarkFile will remove duplicate entries from the marked file list.
6937 " So, this test lets two or more hits on the same pattern to be ignored.
6938 " call Decho("case: ".bufname(bufnmbr)." not currently in marked file list",'~'.expand("<slnum>"))
6939 call s:NetrwMarkFile(a:islocal,bufname(bufnmbr))
6940 else
6941 " call Decho("case: ".bufname(bufnmbr)." already in marked file list",'~'.expand("<slnum>"))
6942 endif
6943 endfor
6944 echo "(use me to edit marked files)"
6945 else
6946 call netrw#ErrorMsg(s:WARNING,"can't convert quickfix error list; its empty!",92)
6947 endif
6948
6949 " call Dret("s:NetrwMarkFileQFEL")
6950endfun
6951
6952" ---------------------------------------------------------------------
6953" s:NetrwMarkFileExe: (invoked by mx and mX) execute arbitrary system command on marked files {{{2
6954" mx enbloc=0: Uses the local marked-file list, applies command to each file individually
6955" mX enbloc=1: Uses the global marked-file list, applies command to entire list
6956fun! s:NetrwMarkFileExe(islocal,enbloc)
6957 let svpos = winsaveview()
6958 let curdir = s:NetrwGetCurdir(a:islocal)
6959 let curbufnr = bufnr("%")
6960
6961 if a:enbloc == 0
6962 " individually apply command to files, one at a time
6963 " sanity check
6964 if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
6965 NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
6966 return
6967 endif
6968
6969 if exists("s:netrwmarkfilelist_{curbufnr}")
6970 " get the command
6971 call inputsave()
6972 let cmd= input("Enter command: ","","file")
6973 call inputrestore()
6974 if cmd == ""
6975 return
6976 endif
6977
6978 " apply command to marked files, individually. Substitute: filename -> %
6979 " If no %, then append a space and the filename to the command
6980 for fname in s:netrwmarkfilelist_{curbufnr}
6981 if a:islocal
6982 if g:netrw_keepdir
6983 let fname= s:ShellEscape(netrw#WinPath(s:ComposePath(curdir,fname)))
6984 endif
6985 else
6986 let fname= s:ShellEscape(netrw#WinPath(b:netrw_curdir.fname))
6987 endif
6988 if cmd =~ '%'
6989 let xcmd= substitute(cmd,'%',fname,'g')
6990 else
6991 let xcmd= cmd.' '.fname
6992 endif
6993 if a:islocal
6994 let ret= system(xcmd)
6995 else
6996 let ret= s:RemoteSystem(xcmd)
6997 endif
6998 if v:shell_error < 0
6999 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"command<".xcmd."> failed, aborting",54)
7000 break
7001 else
7002 if ret !=# ''
7003 echo "\n"
7004 " skip trailing new line
7005 echo ret[0:-2]
7006 else
7007 echo ret
7008 endif
7009 endif
7010 endfor
7011
7012 " unmark marked file list
7013 call s:NetrwUnmarkList(curbufnr,curdir)
7014
7015 " refresh the listing
7016 NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
7017 NetrwKeepj call winrestview(svpos)
7018 else
7019 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7020 endif
7021
7022 else " apply command to global list of files, en bloc
7023
7024 call inputsave()
7025 let cmd= input("Enter command: ","","file")
7026 call inputrestore()
7027 if cmd == ""
7028 return
7029 endif
7030 if cmd =~ '%'
7031 let cmd= substitute(cmd,'%',join(map(s:netrwmarkfilelist,'s:ShellEscape(v:val)'),' '),'g')
7032 else
7033 let cmd= cmd.' '.join(map(s:netrwmarkfilelist,'s:ShellEscape(v:val)'),' ')
7034 endif
7035 if a:islocal
7036 call system(cmd)
7037 if v:shell_error < 0
7038 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"command<".xcmd."> failed, aborting",54)
7039 endif
7040 else
7041 let ret= s:RemoteSystem(cmd)
7042 endif
7043 call s:NetrwUnmarkAll()
7044
7045 " refresh the listing
7046 NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
7047 NetrwKeepj call winrestview(svpos)
7048
7049 endif
7050endfun
7051
7052" ---------------------------------------------------------------------
7053" s:NetrwMarkHideSfx: (invoked by mh) (un)hide files having same suffix
7054" as the marked file(s) (toggles suffix presence)
7055" Uses the local marked file list.
7056fun! s:NetrwMarkHideSfx(islocal)
7057 let svpos = winsaveview()
7058 let curbufnr = bufnr("%")
7059
7060 " s:netrwmarkfilelist_{curbufnr}: the List of marked files
7061 if exists("s:netrwmarkfilelist_{curbufnr}")
7062
7063 for fname in s:netrwmarkfilelist_{curbufnr}
7064 " construct suffix pattern
7065 if fname =~ '\.'
7066 let sfxpat= "^.*".substitute(fname,'^.*\(\.[^. ]\+\)$','\1','')
7067 else
7068 let sfxpat= '^\%(\%(\.\)\@!.\)*$'
7069 endif
7070 " determine if its in the hiding list or not
7071 let inhidelist= 0
7072 if g:netrw_list_hide != ""
7073 let itemnum = 0
7074 let hidelist= split(g:netrw_list_hide,',')
7075 for hidepat in hidelist
7076 if sfxpat == hidepat
7077 let inhidelist= 1
7078 break
7079 endif
7080 let itemnum= itemnum + 1
7081 endfor
7082 endif
7083 if inhidelist
7084 " remove sfxpat from list
7085 call remove(hidelist,itemnum)
7086 let g:netrw_list_hide= join(hidelist,",")
7087 elseif g:netrw_list_hide != ""
7088 " append sfxpat to non-empty list
7089 let g:netrw_list_hide= g:netrw_list_hide.",".sfxpat
7090 else
7091 " set hiding list to sfxpat
7092 let g:netrw_list_hide= sfxpat
7093 endif
7094 endfor
7095
7096 " refresh the listing
7097 NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
7098 NetrwKeepj call winrestview(svpos)
7099 else
7100 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7101 endif
7102endfun
7103
7104" ---------------------------------------------------------------------
7105" s:NetrwMarkFileVimCmd: (invoked by mv) execute arbitrary vim command on marked files, one at a time {{{2
7106" Uses the local marked-file list.
7107fun! s:NetrwMarkFileVimCmd(islocal)
7108 let svpos = winsaveview()
7109 let curdir = s:NetrwGetCurdir(a:islocal)
7110 let curbufnr = bufnr("%")
7111
7112 " sanity check
7113 if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7114 NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7115 return
7116 endif
7117
7118 if exists("s:netrwmarkfilelist_{curbufnr}")
7119 " get the command
7120 call inputsave()
7121 let cmd= input("Enter vim command: ","","file")
7122 call inputrestore()
7123 if cmd == ""
7124 return
7125 endif
7126
7127 " apply command to marked files. Substitute: filename -> %
7128 " If no %, then append a space and the filename to the command
7129 for fname in s:netrwmarkfilelist_{curbufnr}
7130 if a:islocal
7131 1split
7132 exe "sil! NetrwKeepj keepalt e ".fnameescape(fname)
7133 exe cmd
7134 exe "sil! keepalt wq!"
7135 else
7136 echo "sorry, \"mv\" not supported yet for remote files"
7137 endif
7138 endfor
7139
7140 " unmark marked file list
7141 call s:NetrwUnmarkList(curbufnr,curdir)
7142
7143 " refresh the listing
7144 NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
7145 NetrwKeepj call winrestview(svpos)
7146 else
7147 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7148 endif
7149endfun
7150
7151" ---------------------------------------------------------------------
7152" s:NetrwMarkHideSfx: (invoked by mh) (un)hide files having same suffix
7153" as the marked file(s) (toggles suffix presence)
7154" Uses the local marked file list.
7155fun! s:NetrwMarkHideSfx(islocal)
7156 let svpos = winsaveview()
7157 let curbufnr = bufnr("%")
7158
7159 " s:netrwmarkfilelist_{curbufnr}: the List of marked files
7160 if exists("s:netrwmarkfilelist_{curbufnr}")
7161
7162 for fname in s:netrwmarkfilelist_{curbufnr}
7163 " construct suffix pattern
7164 if fname =~ '\.'
7165 let sfxpat= "^.*".substitute(fname,'^.*\(\.[^. ]\+\)$','\1','')
7166 else
7167 let sfxpat= '^\%(\%(\.\)\@!.\)*$'
7168 endif
7169 " determine if its in the hiding list or not
7170 let inhidelist= 0
7171 if g:netrw_list_hide != ""
7172 let itemnum = 0
7173 let hidelist= split(g:netrw_list_hide,',')
7174 for hidepat in hidelist
7175 if sfxpat == hidepat
7176 let inhidelist= 1
7177 break
7178 endif
7179 let itemnum= itemnum + 1
7180 endfor
7181 endif
7182 if inhidelist
7183 " remove sfxpat from list
7184 call remove(hidelist,itemnum)
7185 let g:netrw_list_hide= join(hidelist,",")
7186 elseif g:netrw_list_hide != ""
7187 " append sfxpat to non-empty list
7188 let g:netrw_list_hide= g:netrw_list_hide.",".sfxpat
7189 else
7190 " set hiding list to sfxpat
7191 let g:netrw_list_hide= sfxpat
7192 endif
7193 endfor
7194
7195 " refresh the listing
7196 NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
7197 NetrwKeepj call winrestview(svpos)
7198 else
7199 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"no files marked!",59)
7200 endif
7201endfun
7202
7203" ---------------------------------------------------------------------
7204" s:NetrwMarkFileGrep: (invoked by mg) This function applies vimgrep to marked files {{{2
7205" Uses the global markfilelist
7206fun! s:NetrwMarkFileGrep(islocal)
7207 " call Dfunc("s:NetrwMarkFileGrep(islocal=".a:islocal.")")
7208 let svpos = winsaveview()
7209 " call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7210 let curbufnr = bufnr("%")
7211 let curdir = s:NetrwGetCurdir(a:islocal)
7212
7213 if exists("s:netrwmarkfilelist")
7214 " call Decho("using s:netrwmarkfilelist".string(s:netrwmarkfilelist).">",'~'.expand("<slnum>"))
7215 let netrwmarkfilelist= join(map(deepcopy(s:netrwmarkfilelist), "fnameescape(v:val)"))
7216 " call Decho("keeping copy of s:netrwmarkfilelist in function-local variable,'~'.expand("<slnum>"))"
7217 call s:NetrwUnmarkAll()
7218 else
7219 " call Decho('no marked files, using "*"','~'.expand("<slnum>"))
7220 let netrwmarkfilelist= "*"
7221 endif
7222
7223 " ask user for pattern
7224 " call Decho("ask user for search pattern",'~'.expand("<slnum>"))
7225 call inputsave()
7226 let pat= input("Enter pattern: ","")
7227 call inputrestore()
7228 let patbang = ""
7229 if pat =~ '^!'
7230 let patbang = "!"
7231 let pat = strpart(pat,2)
7232 endif
7233 if pat =~ '^\i'
7234 let pat = escape(pat,'/')
7235 let pat = '/'.pat.'/'
7236 else
7237 let nonisi = pat[0]
7238 endif
7239
7240 " use vimgrep for both local and remote
7241 " call Decho("exe vimgrep".patbang." ".pat." ".netrwmarkfilelist,'~'.expand("<slnum>"))
7242 try
7243 exe "NetrwKeepj noautocmd vimgrep".patbang." ".pat." ".netrwmarkfilelist
7244 catch /^Vim\%((\a\+)\)\=:E480/
7245 NetrwKeepj call netrw#ErrorMsg(s:WARNING,"no match with pattern<".pat.">",76)
7246 " call Dret("s:NetrwMarkFileGrep : unable to find pattern<".pat.">")
7247 return
7248 endtry
7249 echo "(use :cn, :cp to navigate, :Rex to return)"
7250
7251 2match none
7252 " call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
7253 NetrwKeepj call winrestview(svpos)
7254
7255 if exists("nonisi")
7256 " original, user-supplied pattern did not begin with a character from isident
7257 " call Decho("looking for trailing nonisi<".nonisi."> followed by a j, gj, or jg",'~'.expand("<slnum>"))
7258 if pat =~# nonisi.'j$\|'.nonisi.'gj$\|'.nonisi.'jg$'
7259 call s:NetrwMarkFileQFEL(a:islocal,getqflist())
7260 endif
7261 endif
7262
7263 " call Dret("s:NetrwMarkFileGrep")
7264endfun
7265
7266" ---------------------------------------------------------------------
7267" s:NetrwMarkFileMove: (invoked by mm) execute arbitrary command on marked files, one at a time {{{2
7268" uses the global marked file list
7269" s:netrwmfloc= 0: target directory is remote
7270" = 1: target directory is local
7271fun! s:NetrwMarkFileMove(islocal)
7272 " call Dfunc("s:NetrwMarkFileMove(islocal=".a:islocal.")")
7273 let curdir = s:NetrwGetCurdir(a:islocal)
7274 let curbufnr = bufnr("%")
7275
7276 " sanity check
7277 if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7278 NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7279 " call Dret("s:NetrwMarkFileMove")
7280 return
7281 endif
7282 " call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7283
7284 if !exists("s:netrwmftgt")
7285 NetrwKeepj call netrw#ErrorMsg(2,"your marked file target is empty! (:help netrw-mt)",67)
7286 " call Dret("s:NetrwMarkFileCopy 0")
7287 return 0
7288 endif
7289 " call Decho("sanity chk passed: s:netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7290
7291 if a:islocal && s:netrwmftgt_islocal
7292 " move: local -> local
7293 " call Decho("move from local to local",'~'.expand("<slnum>"))
7294 " call Decho("local to local move",'~'.expand("<slnum>"))
7295 if !executable(g:netrw_localmovecmd)
7296 call netrw#ErrorMsg(s:ERROR,"g:netrw_localmovecmd<".g:netrw_localmovecmd."> not executable on your system, aborting",90)
7297 " call Dfunc("s:NetrwMarkFileMove : g:netrw_localmovecmd<".g:netrw_localmovecmd."> n/a!")
7298 return
7299 endif
7300 let tgt = s:ShellEscape(s:netrwmftgt)
7301 " call Decho("tgt<".tgt.">",'~'.expand("<slnum>"))
7302 if !g:netrw_cygwin && has("win32")
7303 let tgt= substitute(tgt, '/','\\','g')
7304 " call Decho("windows exception: tgt<".tgt.">",'~'.expand("<slnum>"))
7305 if g:netrw_localmovecmd =~ '\s'
7306 let movecmd = substitute(g:netrw_localmovecmd,'\s.*$','','')
7307 let movecmdargs = substitute(g:netrw_localmovecmd,'^.\{-}\(\s.*\)$','\1','')
7308 let movecmd = netrw#WinPath(movecmd).movecmdargs
7309 " call Decho("windows exception: movecmd<".movecmd."> (#1: had a space)",'~'.expand("<slnum>"))
7310 else
7311 let movecmd = netrw#WinPath(g:netrw_localmovecmd)
7312 " call Decho("windows exception: movecmd<".movecmd."> (#2: no space)",'~'.expand("<slnum>"))
7313 endif
7314 else
7315 let movecmd = netrw#WinPath(g:netrw_localmovecmd)
7316 " call Decho("movecmd<".movecmd."> (#3 linux or cygwin)",'~'.expand("<slnum>"))
7317 endif
7318 for fname in s:netrwmarkfilelist_{bufnr("%")}
7319 if g:netrw_keepdir
7320 " Jul 19, 2022: fixing file move when g:netrw_keepdir is 1
7321 let fname= b:netrw_curdir."/".fname
7322 endif
7323 if !g:netrw_cygwin && has("win32")
7324 let fname= substitute(fname,'/','\\','g')
7325 endif
7326 " call Decho("system(".movecmd." ".s:ShellEscape(fname)." ".tgt.")",'~'.expand("<slnum>"))
7327 let ret= system(movecmd.g:netrw_localmovecmdopt." ".s:ShellEscape(fname)." ".tgt)
7328 if v:shell_error != 0
7329 if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && !g:netrw_keepdir
7330 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)
7331 else
7332 call netrw#ErrorMsg(s:ERROR,"tried using g:netrw_localmovecmd<".g:netrw_localmovecmd.">; it doesn't work!",54)
7333 endif
7334 break
7335 endif
7336 endfor
7337
7338 elseif a:islocal && !s:netrwmftgt_islocal
7339 " move: local -> remote
7340 " call Decho("move from local to remote",'~'.expand("<slnum>"))
7341 " call Decho("copy",'~'.expand("<slnum>"))
7342 let mflist= s:netrwmarkfilelist_{bufnr("%")}
7343 NetrwKeepj call s:NetrwMarkFileCopy(a:islocal)
7344 " call Decho("remove",'~'.expand("<slnum>"))
7345 for fname in mflist
7346 let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
7347 let ok = s:NetrwLocalRmFile(b:netrw_curdir,barefname,1)
7348 endfor
7349 unlet mflist
7350
7351 elseif !a:islocal && s:netrwmftgt_islocal
7352 " move: remote -> local
7353 " call Decho("move from remote to local",'~'.expand("<slnum>"))
7354 " call Decho("copy",'~'.expand("<slnum>"))
7355 let mflist= s:netrwmarkfilelist_{bufnr("%")}
7356 NetrwKeepj call s:NetrwMarkFileCopy(a:islocal)
7357 " call Decho("remove",'~'.expand("<slnum>"))
7358 for fname in mflist
7359 let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
7360 let ok = s:NetrwRemoteRmFile(b:netrw_curdir,barefname,1)
7361 endfor
7362 unlet mflist
7363
7364 elseif !a:islocal && !s:netrwmftgt_islocal
7365 " move: remote -> remote
7366 " call Decho("move from remote to remote",'~'.expand("<slnum>"))
7367 " call Decho("copy",'~'.expand("<slnum>"))
7368 let mflist= s:netrwmarkfilelist_{bufnr("%")}
7369 NetrwKeepj call s:NetrwMarkFileCopy(a:islocal)
7370 " call Decho("remove",'~'.expand("<slnum>"))
7371 for fname in mflist
7372 let barefname = substitute(fname,'^\(.*/\)\(.\{-}\)$','\2','')
7373 let ok = s:NetrwRemoteRmFile(b:netrw_curdir,barefname,1)
7374 endfor
7375 unlet mflist
7376 endif
7377
7378 " -------
7379 " cleanup
7380 " -------
7381 " call Decho("cleanup",'~'.expand("<slnum>"))
7382
7383 " remove markings from local buffer
7384 call s:NetrwUnmarkList(curbufnr,curdir) " remove markings from local buffer
7385
7386 " refresh buffers
7387 if !s:netrwmftgt_islocal
7388 " call Decho("refresh netrwmftgt<".s:netrwmftgt.">",'~'.expand("<slnum>"))
7389 NetrwKeepj call s:NetrwRefreshDir(s:netrwmftgt_islocal,s:netrwmftgt)
7390 endif
7391 if a:islocal
7392 " call Decho("refresh b:netrw_curdir<".b:netrw_curdir.">",'~'.expand("<slnum>"))
7393 NetrwKeepj call s:NetrwRefreshDir(a:islocal,b:netrw_curdir)
7394 endif
7395 if g:netrw_fastbrowse <= 1
7396 " call Decho("since g:netrw_fastbrowse=".g:netrw_fastbrowse.", perform shell cmd refresh",'~'.expand("<slnum>"))
7397 NetrwKeepj call s:LocalBrowseRefresh()
7398 endif
7399
7400 " call Dret("s:NetrwMarkFileMove")
7401endfun
7402
7403" ---------------------------------------------------------------------
7404" s:NetrwMarkFilePrint: (invoked by mp) This function prints marked files {{{2
7405" using the hardcopy command. Local marked-file list only.
7406fun! s:NetrwMarkFilePrint(islocal)
7407 " call Dfunc("s:NetrwMarkFilePrint(islocal=".a:islocal.")")
7408 let curbufnr= bufnr("%")
7409
7410 " sanity check
7411 if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7412 NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7413 " call Dret("s:NetrwMarkFilePrint")
7414 return
7415 endif
7416 " call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7417 let curdir= s:NetrwGetCurdir(a:islocal)
7418
7419 if exists("s:netrwmarkfilelist_{curbufnr}")
7420 let netrwmarkfilelist = s:netrwmarkfilelist_{curbufnr}
7421 call s:NetrwUnmarkList(curbufnr,curdir)
7422 for fname in netrwmarkfilelist
7423 if a:islocal
7424 if g:netrw_keepdir
7425 let fname= s:ComposePath(curdir,fname)
7426 endif
7427 else
7428 let fname= curdir.fname
7429 endif
7430 1split
7431 " the autocmds will handle both local and remote files
7432 " call Decho("exe sil e ".escape(fname,' '),'~'.expand("<slnum>"))
7433 exe "sil NetrwKeepj e ".fnameescape(fname)
7434 " call Decho("hardcopy",'~'.expand("<slnum>"))
7435 hardcopy
7436 q
7437 endfor
7438 2match none
7439 endif
7440 " call Dret("s:NetrwMarkFilePrint")
7441endfun
7442
7443" ---------------------------------------------------------------------
7444" s:NetrwMarkFileRegexp: (invoked by mr) This function is used to mark {{{2
7445" files when given a regexp (for which a prompt is
7446" issued) (matches to name of files).
7447fun! s:NetrwMarkFileRegexp(islocal)
7448 " call Dfunc("s:NetrwMarkFileRegexp(islocal=".a:islocal.")")
7449
7450 " get the regular expression
7451 call inputsave()
7452 let regexp= input("Enter regexp: ","","file")
7453 call inputrestore()
7454
7455 if a:islocal
7456 let curdir= s:NetrwGetCurdir(a:islocal)
7457 " call Decho("curdir<".fnameescape(curdir).">")
7458 " get the matching list of files using local glob()
7459 " call Decho("handle local regexp",'~'.expand("<slnum>"))
7460 let dirname = escape(b:netrw_curdir,g:netrw_glob_escape)
7461 if v:version > 704 || (v:version == 704 && has("patch656"))
7462 let filelist= glob(s:ComposePath(dirname,regexp),0,1,1)
7463 else
7464 let files = glob(s:ComposePath(dirname,regexp),0,0)
7465 let filelist= split(files,"\n")
7466 endif
7467 " call Decho("files<".string(filelist).">",'~'.expand("<slnum>"))
7468
7469 " mark the list of files
7470 for fname in filelist
7471 if fname =~ '^'.fnameescape(curdir)
7472 " call Decho("fname<".substitute(fname,'^'.fnameescape(curdir).'/','','').">",'~'.expand("<slnum>"))
7473 NetrwKeepj call s:NetrwMarkFile(a:islocal,substitute(fname,'^'.fnameescape(curdir).'/','',''))
7474 else
7475 " call Decho("fname<".fname.">",'~'.expand("<slnum>"))
7476 NetrwKeepj call s:NetrwMarkFile(a:islocal,substitute(fname,'^.*/','',''))
7477 endif
7478 endfor
7479
7480 else
7481 " call Decho("handle remote regexp",'~'.expand("<slnum>"))
7482
7483 " convert displayed listing into a filelist
7484 let eikeep = &ei
7485 let areg = @a
7486 sil NetrwKeepj %y a
7487 setl ei=all ma
7488 " call Decho("setl ei=all ma",'~'.expand("<slnum>"))
7489 1split
7490 NetrwKeepj call s:NetrwEnew()
7491 NetrwKeepj call s:NetrwOptionsSafe(a:islocal)
7492 sil NetrwKeepj norm! "ap
7493 NetrwKeepj 2
7494 let bannercnt= search('^" =====','W')
7495 exe "sil NetrwKeepj 1,".bannercnt."d"
7496 setl bt=nofile
7497 if g:netrw_liststyle == s:LONGLIST
7498 sil NetrwKeepj %s/\s\{2,}\S.*$//e
7499 call histdel("/",-1)
7500 elseif g:netrw_liststyle == s:WIDELIST
7501 sil NetrwKeepj %s/\s\{2,}/\r/ge
7502 call histdel("/",-1)
7503 elseif g:netrw_liststyle == s:TREELIST
7504 exe 'sil NetrwKeepj %s/^'.s:treedepthstring.' //e'
7505 sil! NetrwKeepj g/^ .*$/d
7506 call histdel("/",-1)
7507 call histdel("/",-1)
7508 endif
7509 " convert regexp into the more usual glob-style format
7510 let regexp= substitute(regexp,'\*','.*','g')
7511 " call Decho("regexp<".regexp.">",'~'.expand("<slnum>"))
7512 exe "sil! NetrwKeepj v/".escape(regexp,'/')."/d"
7513 call histdel("/",-1)
7514 let filelist= getline(1,line("$"))
7515 q!
7516 for filename in filelist
7517 NetrwKeepj call s:NetrwMarkFile(a:islocal,substitute(filename,'^.*/','',''))
7518 endfor
7519 unlet filelist
7520 let @a = areg
7521 let &ei = eikeep
7522 endif
7523 echo " (use me to edit marked files)"
7524
7525 " call Dret("s:NetrwMarkFileRegexp")
7526endfun
7527
7528" ---------------------------------------------------------------------
7529" s:NetrwMarkFileSource: (invoked by ms) This function sources marked files {{{2
7530" Uses the local marked file list.
7531fun! s:NetrwMarkFileSource(islocal)
7532 " call Dfunc("s:NetrwMarkFileSource(islocal=".a:islocal.")")
7533 let curbufnr= bufnr("%")
7534
7535 " sanity check
7536 if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7537 NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7538 " call Dret("s:NetrwMarkFileSource")
7539 return
7540 endif
7541 " call Decho("sanity chk passed: s:netrwmarkfilelist_".curbufnr."<".string(s:netrwmarkfilelist_{curbufnr}),'~'.expand("<slnum>"))
7542 let curdir= s:NetrwGetCurdir(a:islocal)
7543
7544 if exists("s:netrwmarkfilelist_{curbufnr}")
7545 let netrwmarkfilelist = s:netrwmarkfilelist_{bufnr("%")}
7546 call s:NetrwUnmarkList(curbufnr,curdir)
7547 for fname in netrwmarkfilelist
7548 if a:islocal
7549 if g:netrw_keepdir
7550 let fname= s:ComposePath(curdir,fname)
7551 endif
7552 else
7553 let fname= curdir.fname
7554 endif
7555 " the autocmds will handle sourcing both local and remote files
7556 " call Decho("exe so ".fnameescape(fname),'~'.expand("<slnum>"))
7557 exe "so ".fnameescape(fname)
7558 endfor
7559 2match none
7560 endif
7561 " call Dret("s:NetrwMarkFileSource")
7562endfun
7563
7564" ---------------------------------------------------------------------
7565" s:NetrwMarkFileTag: (invoked by mT) This function applies g:netrw_ctags to marked files {{{2
7566" Uses the global markfilelist
7567fun! s:NetrwMarkFileTag(islocal)
7568 let svpos = winsaveview()
7569 let curdir = s:NetrwGetCurdir(a:islocal)
7570 let curbufnr = bufnr("%")
7571
7572 " sanity check
7573 if !exists("s:netrwmarkfilelist_{curbufnr}") || empty(s:netrwmarkfilelist_{curbufnr})
7574 NetrwKeepj call netrw#ErrorMsg(2,"there are no marked files in this window (:help netrw-mf)",66)
7575 return
7576 endif
7577
7578 if exists("s:netrwmarkfilelist")
7579 let netrwmarkfilelist= join(map(deepcopy(s:netrwmarkfilelist), "s:ShellEscape(v:val,".!a:islocal.")"))
7580 call s:NetrwUnmarkAll()
7581
7582 if a:islocal
7583
7584 call system(g:netrw_ctags." ".netrwmarkfilelist)
7585 if v:shell_error
7586 call netrw#ErrorMsg(s:ERROR,"g:netrw_ctags<".g:netrw_ctags."> is not executable!",51)
7587 endif
7588
7589 else
7590 let cmd = s:RemoteSystem(g:netrw_ctags." ".netrwmarkfilelist)
7591 call netrw#Obtain(a:islocal,"tags")
7592 let curdir= b:netrw_curdir
7593 1split
7594 NetrwKeepj e tags
7595 let path= substitute(curdir,'^\(.*\)/[^/]*$','\1/','')
7596 exe 'NetrwKeepj %s/\t\(\S\+\)\t/\t'.escape(path,"/\n\r\\").'\1\t/e'
7597 call histdel("/",-1)
7598 wq!
7599 endif
7600 2match none
7601 call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
7602 call winrestview(svpos)
7603 endif
7604endfun
7605
7606" ---------------------------------------------------------------------
7607" s:NetrwMarkFileTgt: (invoked by mt) This function sets up a marked file target {{{2
7608" Sets up two variables,
7609" s:netrwmftgt : holds the target directory
7610" s:netrwmftgt_islocal : 0=target directory is remote
7611" 1=target directory is local
7612fun! s:NetrwMarkFileTgt(islocal)
7613 let svpos = winsaveview()
7614 let curdir = s:NetrwGetCurdir(a:islocal)
7615 let hadtgt = exists("s:netrwmftgt")
7616 if !exists("w:netrw_bannercnt")
7617 let w:netrw_bannercnt= b:netrw_bannercnt
7618 endif
7619
7620 " set up target
7621 if line(".") < w:netrw_bannercnt
7622 " if cursor in banner region, use b:netrw_curdir for the target unless its already the target
7623 if exists("s:netrwmftgt") && exists("s:netrwmftgt_islocal") && s:netrwmftgt == b:netrw_curdir
7624 unlet s:netrwmftgt s:netrwmftgt_islocal
7625 if g:netrw_fastbrowse <= 1
7626 call s:LocalBrowseRefresh()
7627 endif
7628 call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
7629 call winrestview(svpos)
7630 return
7631 else
7632 let s:netrwmftgt= b:netrw_curdir
7633 endif
7634
7635 else
7636 " get word under cursor.
7637 " * If directory, use it for the target.
7638 " * If file, use b:netrw_curdir for the target
7639 let curword= s:NetrwGetWord()
7640 let tgtdir = s:ComposePath(curdir,curword)
7641 if a:islocal && isdirectory(s:NetrwFile(tgtdir))
7642 let s:netrwmftgt = tgtdir
7643 elseif !a:islocal && tgtdir =~ '/$'
7644 let s:netrwmftgt = tgtdir
7645 else
7646 let s:netrwmftgt = curdir
7647 endif
7648 endif
7649 if a:islocal
7650 " simplify the target (eg. /abc/def/../ghi -> /abc/ghi)
7651 let s:netrwmftgt= simplify(s:netrwmftgt)
7652 endif
7653 if g:netrw_cygwin
7654 let s:netrwmftgt= substitute(system("cygpath ".s:ShellEscape(s:netrwmftgt)),'\n$','','')
7655 let s:netrwmftgt= substitute(s:netrwmftgt,'\n$','','')
7656 endif
7657 let s:netrwmftgt_islocal= a:islocal
7658
7659 " need to do refresh so that the banner will be updated
7660 " s:LocalBrowseRefresh handles all local-browsing buffers when not fast browsing
7661 if g:netrw_fastbrowse <= 1
7662 call s:LocalBrowseRefresh()
7663 endif
7664 " call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
7665 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
7666 call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,w:netrw_treetop,0))
7667 else
7668 call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
7669 endif
7670 call winrestview(svpos)
7671 if !hadtgt
7672 sil! NetrwKeepj norm! j
7673 endif
7674endfun
7675
7676" ---------------------------------------------------------------------
7677" s:NetrwGetCurdir: gets current directory and sets up b:netrw_curdir if necessary {{{2
7678fun! s:NetrwGetCurdir(islocal)
7679 " call Dfunc("s:NetrwGetCurdir(islocal=".a:islocal.")")
7680
7681 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
7682 let b:netrw_curdir = s:NetrwTreePath(w:netrw_treetop)
7683 " call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used s:NetrwTreeDir)",'~'.expand("<slnum>"))
7684 elseif !exists("b:netrw_curdir")
7685 let b:netrw_curdir= getcwd()
7686 " call Decho("set b:netrw_curdir<".b:netrw_curdir."> (used getcwd)",'~'.expand("<slnum>"))
7687 endif
7688
7689 " call Decho("b:netrw_curdir<".b:netrw_curdir."> ".((b:netrw_curdir !~ '\<\a\{3,}://')? "does not match" : "matches")." url pattern",'~'.expand("<slnum>"))
7690 if b:netrw_curdir !~ '\<\a\{3,}://'
7691 let curdir= b:netrw_curdir
7692 " call Decho("g:netrw_keepdir=".g:netrw_keepdir,'~'.expand("<slnum>"))
7693 if g:netrw_keepdir == 0
7694 call s:NetrwLcd(curdir)
7695 endif
7696 endif
7697
7698 " call Dret("s:NetrwGetCurdir <".curdir.">")
7699 return b:netrw_curdir
7700endfun
7701
7702" ---------------------------------------------------------------------
7703" s:NetrwOpenFile: query user for a filename and open it {{{2
7704fun! s:NetrwOpenFile(islocal)
7705 " call Dfunc("s:NetrwOpenFile(islocal=".a:islocal.")")
7706 let ykeep= @@
7707 call inputsave()
7708 let fname= input("Enter filename: ")
7709 call inputrestore()
7710 " call Decho("(s:NetrwOpenFile) fname<".fname.">",'~'.expand("<slnum>"))
7711
7712 " determine if Lexplore is in use
7713 if exists("t:netrw_lexbufnr")
7714 " check if t:netrw_lexbufnr refers to a netrw window
7715 " call Decho("(s:netrwOpenFile) ..t:netrw_lexbufnr=".t:netrw_lexbufnr,'~'.expand("<slnum>"))
7716 let lexwinnr = bufwinnr(t:netrw_lexbufnr)
7717 if lexwinnr != -1 && exists("g:netrw_chgwin") && g:netrw_chgwin != -1
7718 " call Decho("(s:netrwOpenFile) ..Lexplore in use",'~'.expand("<slnum>"))
7719 exe "NetrwKeepj keepalt ".g:netrw_chgwin."wincmd w"
7720 exe "NetrwKeepj e ".fnameescape(fname)
7721 let @@= ykeep
7722 " call Dret("s:NetrwOpenFile : creating a file with Lexplore mode")
7723 endif
7724 endif
7725
7726 " Does the filename contain a path?
7727 if fname !~ '[/\\]'
7728 if exists("b:netrw_curdir")
7729 if exists("g:netrw_quiet")
7730 let netrw_quiet_keep = g:netrw_quiet
7731 endif
7732 let g:netrw_quiet = 1
7733 " save position for benefit of Rexplore
7734 let s:rexposn_{bufnr("%")}= winsaveview()
7735 " call Decho("saving posn to s:rexposn_".bufnr("%")."<".string(s:rexposn_{bufnr("%")}).">",'~'.expand("<slnum>"))
7736 if b:netrw_curdir =~ '/$'
7737 exe "NetrwKeepj e ".fnameescape(b:netrw_curdir.fname)
7738 else
7739 exe "e ".fnameescape(b:netrw_curdir."/".fname)
7740 endif
7741 if exists("netrw_quiet_keep")
7742 let g:netrw_quiet= netrw_quiet_keep
7743 else
7744 unlet g:netrw_quiet
7745 endif
7746 endif
7747 else
7748 exe "NetrwKeepj e ".fnameescape(fname)
7749 endif
7750 let @@= ykeep
7751 " call Dret("s:NetrwOpenFile")
7752endfun
7753
7754" ---------------------------------------------------------------------
7755" netrw#Shrink: shrinks/expands a netrw or Lexplorer window {{{2
7756" For the mapping to this function be made via
7757" netrwPlugin, you'll need to have had
7758" g:netrw_usetab set to non-zero.
7759fun! netrw#Shrink()
7760 " call Dfunc("netrw#Shrink() ft<".&ft."> winwidth=".winwidth(0)." lexbuf#".((exists("t:netrw_lexbufnr"))? t:netrw_lexbufnr : 'n/a'))
7761 let curwin = winnr()
7762 let wiwkeep = &wiw
7763 set wiw=1
7764
7765 if &ft == "netrw"
7766 if winwidth(0) > g:netrw_wiw
7767 let t:netrw_winwidth= winwidth(0)
7768 exe "vert resize ".g:netrw_wiw
7769 wincmd l
7770 if winnr() == curwin
7771 wincmd h
7772 endif
7773 " call Decho("vert resize 0",'~'.expand("<slnum>"))
7774 else
7775 exe "vert resize ".t:netrw_winwidth
7776 " call Decho("vert resize ".t:netrw_winwidth,'~'.expand("<slnum>"))
7777 endif
7778
7779 elseif exists("t:netrw_lexbufnr")
7780 exe bufwinnr(t:netrw_lexbufnr)."wincmd w"
7781 if winwidth(bufwinnr(t:netrw_lexbufnr)) > g:netrw_wiw
7782 let t:netrw_winwidth= winwidth(0)
7783 exe "vert resize ".g:netrw_wiw
7784 wincmd l
7785 if winnr() == curwin
7786 wincmd h
7787 endif
7788 " call Decho("vert resize 0",'~'.expand("<slnum>"))
7789 elseif winwidth(bufwinnr(t:netrw_lexbufnr)) >= 0
7790 exe "vert resize ".t:netrw_winwidth
7791 " call Decho("vert resize ".t:netrw_winwidth,'~'.expand("<slnum>"))
7792 else
7793 call netrw#Lexplore(0,0)
7794 endif
7795
7796 else
7797 call netrw#Lexplore(0,0)
7798 endif
7799 let wiw= wiwkeep
7800
7801 " call Dret("netrw#Shrink")
7802endfun
7803
7804" ---------------------------------------------------------------------
7805" s:NetSortSequence: allows user to edit the sorting sequence {{{2
7806fun! s:NetSortSequence(islocal)
7807 let ykeep= @@
7808 let svpos= winsaveview()
7809 call inputsave()
7810 let newsortseq= input("Edit Sorting Sequence: ",g:netrw_sort_sequence)
7811 call inputrestore()
7812
7813 " refresh the listing
7814 let g:netrw_sort_sequence= newsortseq
7815 NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
7816 NetrwKeepj call winrestview(svpos)
7817 let @@= ykeep
7818endfun
7819
7820" ---------------------------------------------------------------------
7821" s:NetrwUnmarkList: delete local marked file list and remove their contents from the global marked-file list {{{2
7822" User access provided by the <mF> mapping. (see :help netrw-mF)
7823" Used by many MarkFile functions.
7824fun! s:NetrwUnmarkList(curbufnr,curdir)
7825 " call Dfunc("s:NetrwUnmarkList(curbufnr=".a:curbufnr." curdir<".a:curdir.">)")
7826
7827 " remove all files in local marked-file list from global list
7828 if exists("s:netrwmarkfilelist")
7829 for mfile in s:netrwmarkfilelist_{a:curbufnr}
7830 let dfile = s:ComposePath(a:curdir,mfile) " prepend directory to mfile
7831 let idx = index(s:netrwmarkfilelist,dfile) " get index in list of dfile
7832 call remove(s:netrwmarkfilelist,idx) " remove from global list
7833 endfor
7834 if s:netrwmarkfilelist == []
7835 unlet s:netrwmarkfilelist
7836 endif
7837
7838 " getting rid of the local marked-file lists is easy
7839 unlet s:netrwmarkfilelist_{a:curbufnr}
7840 endif
7841 if exists("s:netrwmarkfilemtch_{a:curbufnr}")
7842 unlet s:netrwmarkfilemtch_{a:curbufnr}
7843 endif
7844 2match none
7845 " call Dret("s:NetrwUnmarkList")
7846endfun
7847
7848" ---------------------------------------------------------------------
7849" s:NetrwUnmarkAll: remove the global marked file list and all local ones {{{2
7850fun! s:NetrwUnmarkAll()
7851 " call Dfunc("s:NetrwUnmarkAll()")
7852 if exists("s:netrwmarkfilelist")
7853 unlet s:netrwmarkfilelist
7854 endif
7855 sil call s:NetrwUnmarkAll2()
7856 2match none
7857 " call Dret("s:NetrwUnmarkAll")
7858endfun
7859
7860" ---------------------------------------------------------------------
7861" s:NetrwUnmarkAll2: unmark all files from all buffers {{{2
7862fun! s:NetrwUnmarkAll2()
7863 " call Dfunc("s:NetrwUnmarkAll2()")
7864 redir => netrwmarkfilelist_let
7865 let
7866 redir END
7867 let netrwmarkfilelist_list= split(netrwmarkfilelist_let,'\n') " convert let string into a let list
7868 call filter(netrwmarkfilelist_list,"v:val =~ '^s:netrwmarkfilelist_'") " retain only those vars that start as s:netrwmarkfilelist_
7869 call map(netrwmarkfilelist_list,"substitute(v:val,'\\s.*$','','')") " remove what the entries are equal to
7870 for flist in netrwmarkfilelist_list
7871 let curbufnr= substitute(flist,'s:netrwmarkfilelist_','','')
7872 unlet s:netrwmarkfilelist_{curbufnr}
7873 unlet s:netrwmarkfilemtch_{curbufnr}
7874 endfor
7875 " call Dret("s:NetrwUnmarkAll2")
7876endfun
7877
7878" ---------------------------------------------------------------------
7879" s:NetrwUnMarkFile: called via mu map; unmarks *all* marked files, both global and buffer-local {{{2
7880"
7881" Marked files are in two types of lists:
7882" s:netrwmarkfilelist -- holds complete paths to all marked files
7883" s:netrwmarkfilelist_# -- holds list of marked files in current-buffer's directory (#==bufnr())
7884"
7885" Marked files suitable for use with 2match are in:
7886" s:netrwmarkfilemtch_# -- used with 2match to display marked files
7887fun! s:NetrwUnMarkFile(islocal)
7888 let svpos = winsaveview()
7889 let curbufnr = bufnr("%")
7890
7891 " unmark marked file list
7892 " (although I expect s:NetrwUpload() to do it, I'm just making sure)
7893 if exists("s:netrwmarkfilelist")
7894 " " call Decho("unlet'ing: s:netrwmarkfilelist",'~'.expand("<slnum>"))
7895 unlet s:netrwmarkfilelist
7896 endif
7897
7898 let ibuf= 1
7899 while ibuf < bufnr("$")
7900 if exists("s:netrwmarkfilelist_".ibuf)
7901 unlet s:netrwmarkfilelist_{ibuf}
7902 unlet s:netrwmarkfilemtch_{ibuf}
7903 endif
7904 let ibuf = ibuf + 1
7905 endwhile
7906 2match none
7907
7908 " call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
7909 call winrestview(svpos)
7910endfun
7911
7912" ---------------------------------------------------------------------
7913" s:NetrwMenu: generates the menu for gvim and netrw {{{2
7914fun! s:NetrwMenu(domenu)
7915
7916 if !exists("g:NetrwMenuPriority")
7917 let g:NetrwMenuPriority= 80
7918 endif
7919
7920 if has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
7921 " call Dfunc("NetrwMenu(domenu=".a:domenu.")")
7922
7923 if !exists("s:netrw_menu_enabled") && a:domenu
7924 " call Decho("initialize menu",'~'.expand("<slnum>"))
7925 let s:netrw_menu_enabled= 1
7926 exe 'sil! menu '.g:NetrwMenuPriority.'.1 '.g:NetrwTopLvlMenu.'Help<tab><F1> <F1>'
7927 exe 'sil! menu '.g:NetrwMenuPriority.'.5 '.g:NetrwTopLvlMenu.'-Sep1- :'
7928 exe 'sil! menu '.g:NetrwMenuPriority.'.6 '.g:NetrwTopLvlMenu.'Go\ Up\ Directory<tab>- -'
7929 exe 'sil! menu '.g:NetrwMenuPriority.'.7 '.g:NetrwTopLvlMenu.'Apply\ Special\ Viewer<tab>x x'
7930 if g:netrw_dirhistmax > 0
7931 exe 'sil! menu '.g:NetrwMenuPriority.'.8.1 '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Bookmark\ Current\ Directory<tab>mb mb'
7932 exe 'sil! menu '.g:NetrwMenuPriority.'.8.4 '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Goto\ Prev\ Dir\ (History)<tab>u u'
7933 exe 'sil! menu '.g:NetrwMenuPriority.'.8.5 '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.Goto\ Next\ Dir\ (History)<tab>U U'
7934 exe 'sil! menu '.g:NetrwMenuPriority.'.8.6 '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History.List<tab>qb qb'
7935 else
7936 exe 'sil! menu '.g:NetrwMenuPriority.'.8 '.g:NetrwTopLvlMenu.'Bookmarks\ and\ History :echo "(disabled)"'."\<cr>"
7937 endif
7938 exe 'sil! menu '.g:NetrwMenuPriority.'.9.1 '.g:NetrwTopLvlMenu.'Browsing\ Control.Horizontal\ Split<tab>o o'
7939 exe 'sil! menu '.g:NetrwMenuPriority.'.9.2 '.g:NetrwTopLvlMenu.'Browsing\ Control.Vertical\ Split<tab>v v'
7940 exe 'sil! menu '.g:NetrwMenuPriority.'.9.3 '.g:NetrwTopLvlMenu.'Browsing\ Control.New\ Tab<tab>t t'
7941 exe 'sil! menu '.g:NetrwMenuPriority.'.9.4 '.g:NetrwTopLvlMenu.'Browsing\ Control.Preview<tab>p p'
7942 exe 'sil! menu '.g:NetrwMenuPriority.'.9.5 '.g:NetrwTopLvlMenu.'Browsing\ Control.Edit\ File\ Hiding\ List<tab><ctrl-h>'." \<c-h>'"
7943 exe 'sil! menu '.g:NetrwMenuPriority.'.9.6 '.g:NetrwTopLvlMenu.'Browsing\ Control.Edit\ Sorting\ Sequence<tab>S S'
7944 exe 'sil! menu '.g:NetrwMenuPriority.'.9.7 '.g:NetrwTopLvlMenu.'Browsing\ Control.Quick\ Hide/Unhide\ Dot\ Files<tab>'."gh gh"
7945 exe 'sil! menu '.g:NetrwMenuPriority.'.9.8 '.g:NetrwTopLvlMenu.'Browsing\ Control.Refresh\ Listing<tab>'."<ctrl-l> \<c-l>"
7946 exe 'sil! menu '.g:NetrwMenuPriority.'.9.9 '.g:NetrwTopLvlMenu.'Browsing\ Control.Settings/Options<tab>:NetrwSettings '.":NetrwSettings\<cr>"
7947 exe 'sil! menu '.g:NetrwMenuPriority.'.10 '.g:NetrwTopLvlMenu.'Delete\ File/Directory<tab>D D'
7948 exe 'sil! menu '.g:NetrwMenuPriority.'.11.1 '.g:NetrwTopLvlMenu.'Edit\ File/Dir.Create\ New\ File<tab>% %'
7949 exe 'sil! menu '.g:NetrwMenuPriority.'.11.1 '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ Current\ Window<tab><cr> '."\<cr>"
7950 exe 'sil! menu '.g:NetrwMenuPriority.'.11.2 '.g:NetrwTopLvlMenu.'Edit\ File/Dir.Preview\ File/Directory<tab>p p'
7951 exe 'sil! menu '.g:NetrwMenuPriority.'.11.3 '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ Previous\ Window<tab>P P'
7952 exe 'sil! menu '.g:NetrwMenuPriority.'.11.4 '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Window<tab>o o'
7953 exe 'sil! menu '.g:NetrwMenuPriority.'.11.5 '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Tab<tab>t t'
7954 exe 'sil! menu '.g:NetrwMenuPriority.'.11.5 '.g:NetrwTopLvlMenu.'Edit\ File/Dir.In\ New\ Vertical\ Window<tab>v v'
7955 exe 'sil! menu '.g:NetrwMenuPriority.'.12.1 '.g:NetrwTopLvlMenu.'Explore.Directory\ Name :Explore '
7956 exe 'sil! menu '.g:NetrwMenuPriority.'.12.2 '.g:NetrwTopLvlMenu.'Explore.Filenames\ Matching\ Pattern\ (curdir\ only)<tab>:Explore\ */ :Explore */'
7957 exe 'sil! menu '.g:NetrwMenuPriority.'.12.2 '.g:NetrwTopLvlMenu.'Explore.Filenames\ Matching\ Pattern\ (+subdirs)<tab>:Explore\ **/ :Explore **/'
7958 exe 'sil! menu '.g:NetrwMenuPriority.'.12.3 '.g:NetrwTopLvlMenu.'Explore.Files\ Containing\ String\ Pattern\ (curdir\ only)<tab>:Explore\ *// :Explore *//'
7959 exe 'sil! menu '.g:NetrwMenuPriority.'.12.4 '.g:NetrwTopLvlMenu.'Explore.Files\ Containing\ String\ Pattern\ (+subdirs)<tab>:Explore\ **// :Explore **//'
7960 exe 'sil! menu '.g:NetrwMenuPriority.'.12.4 '.g:NetrwTopLvlMenu.'Explore.Next\ Match<tab>:Nexplore :Nexplore<cr>'
7961 exe 'sil! menu '.g:NetrwMenuPriority.'.12.4 '.g:NetrwTopLvlMenu.'Explore.Prev\ Match<tab>:Pexplore :Pexplore<cr>'
7962 exe 'sil! menu '.g:NetrwMenuPriority.'.13 '.g:NetrwTopLvlMenu.'Make\ Subdirectory<tab>d d'
7963 exe 'sil! menu '.g:NetrwMenuPriority.'.14.1 '.g:NetrwTopLvlMenu.'Marked\ Files.Mark\ File<tab>mf mf'
7964 exe 'sil! menu '.g:NetrwMenuPriority.'.14.2 '.g:NetrwTopLvlMenu.'Marked\ Files.Mark\ Files\ by\ Regexp<tab>mr mr'
7965 exe 'sil! menu '.g:NetrwMenuPriority.'.14.3 '.g:NetrwTopLvlMenu.'Marked\ Files.Hide-Show-List\ Control<tab>a a'
7966 exe 'sil! menu '.g:NetrwMenuPriority.'.14.4 '.g:NetrwTopLvlMenu.'Marked\ Files.Copy\ To\ Target<tab>mc mc'
7967 exe 'sil! menu '.g:NetrwMenuPriority.'.14.5 '.g:NetrwTopLvlMenu.'Marked\ Files.Delete<tab>D D'
7968 exe 'sil! menu '.g:NetrwMenuPriority.'.14.6 '.g:NetrwTopLvlMenu.'Marked\ Files.Diff<tab>md md'
7969 exe 'sil! menu '.g:NetrwMenuPriority.'.14.7 '.g:NetrwTopLvlMenu.'Marked\ Files.Edit<tab>me me'
7970 exe 'sil! menu '.g:NetrwMenuPriority.'.14.8 '.g:NetrwTopLvlMenu.'Marked\ Files.Exe\ Cmd<tab>mx mx'
7971 exe 'sil! menu '.g:NetrwMenuPriority.'.14.9 '.g:NetrwTopLvlMenu.'Marked\ Files.Move\ To\ Target<tab>mm mm'
7972 exe 'sil! menu '.g:NetrwMenuPriority.'.14.10 '.g:NetrwTopLvlMenu.'Marked\ Files.Obtain<tab>O O'
7973 exe 'sil! menu '.g:NetrwMenuPriority.'.14.11 '.g:NetrwTopLvlMenu.'Marked\ Files.Print<tab>mp mp'
7974 exe 'sil! menu '.g:NetrwMenuPriority.'.14.12 '.g:NetrwTopLvlMenu.'Marked\ Files.Replace<tab>R R'
7975 exe 'sil! menu '.g:NetrwMenuPriority.'.14.13 '.g:NetrwTopLvlMenu.'Marked\ Files.Set\ Target<tab>mt mt'
7976 exe 'sil! menu '.g:NetrwMenuPriority.'.14.14 '.g:NetrwTopLvlMenu.'Marked\ Files.Tag<tab>mT mT'
7977 exe 'sil! menu '.g:NetrwMenuPriority.'.14.15 '.g:NetrwTopLvlMenu.'Marked\ Files.Zip/Unzip/Compress/Uncompress<tab>mz mz'
7978 exe 'sil! menu '.g:NetrwMenuPriority.'.15 '.g:NetrwTopLvlMenu.'Obtain\ File<tab>O O'
7979 exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.thin<tab>i :let w:netrw_liststyle=0<cr><c-L>'
7980 exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.long<tab>i :let w:netrw_liststyle=1<cr><c-L>'
7981 exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.wide<tab>i :let w:netrw_liststyle=2<cr><c-L>'
7982 exe 'sil! menu '.g:NetrwMenuPriority.'.16.1.1 '.g:NetrwTopLvlMenu.'Style.Listing.tree<tab>i :let w:netrw_liststyle=3<cr><c-L>'
7983 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>'
7984 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>'
7985 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>'
7986 exe 'sil! menu '.g:NetrwMenuPriority.'.16.3 '.g:NetrwTopLvlMenu.'Style.Reverse\ Sorting\ Order<tab>'."r r"
7987 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>'
7988 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>'
7989 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>'
7990 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>'
7991 exe 'sil! menu '.g:NetrwMenuPriority.'.17 '.g:NetrwTopLvlMenu.'Rename\ File/Directory<tab>R R'
7992 exe 'sil! menu '.g:NetrwMenuPriority.'.18 '.g:NetrwTopLvlMenu.'Set\ Current\ Directory<tab>c c'
7993 let s:netrw_menucnt= 28
7994 call s:NetrwBookmarkMenu() " provide some history! uses priorities 2,3, reserves 4, 8.2.x
7995 call s:NetrwTgtMenu() " let bookmarks and history be easy targets
7996
7997 elseif !a:domenu
7998 let s:netrwcnt = 0
7999 let curwin = winnr()
8000 windo if getline(2) =~# "Netrw" | let s:netrwcnt= s:netrwcnt + 1 | endif
8001 exe curwin."wincmd w"
8002
8003 if s:netrwcnt <= 1
8004 " call Decho("clear menus",'~'.expand("<slnum>"))
8005 exe 'sil! unmenu '.g:NetrwTopLvlMenu
8006 " call Decho('exe sil! unmenu '.g:NetrwTopLvlMenu.'*','~'.expand("<slnum>"))
8007 sil! unlet s:netrw_menu_enabled
8008 endif
8009 endif
8010 " call Dret("NetrwMenu")
8011 return
8012 endif
8013
8014endfun
8015
8016" ---------------------------------------------------------------------
8017" s:NetrwObtain: obtain file under cursor or from markfile list {{{2
8018" Used by the O maps (as <SID>NetrwObtain())
8019fun! s:NetrwObtain(islocal)
8020 " call Dfunc("NetrwObtain(islocal=".a:islocal.")")
8021
8022 let ykeep= @@
8023 if exists("s:netrwmarkfilelist_{bufnr('%')}")
8024 let islocal= s:netrwmarkfilelist_{bufnr('%')}[1] !~ '^\a\{3,}://'
8025 call netrw#Obtain(islocal,s:netrwmarkfilelist_{bufnr('%')})
8026 call s:NetrwUnmarkList(bufnr('%'),b:netrw_curdir)
8027 else
8028 call netrw#Obtain(a:islocal,s:NetrwGetWord())
8029 endif
8030 let @@= ykeep
8031
8032 " call Dret("NetrwObtain")
8033endfun
8034
8035" ---------------------------------------------------------------------
8036" s:NetrwPrevWinOpen: open file/directory in previous window. {{{2
8037" If there's only one window, then the window will first be split.
8038" Returns:
8039" choice = 0 : didn't have to choose
8040" choice = 1 : saved modified file in window first
8041" choice = 2 : didn't save modified file, opened window
8042" choice = 3 : cancel open
8043fun! s:NetrwPrevWinOpen(islocal)
8044 let ykeep= @@
8045 " grab a copy of the b:netrw_curdir to pass it along to newly split windows
8046 let curdir = b:netrw_curdir
8047
8048 " get last window number and the word currently under the cursor
8049 let origwin = winnr()
8050 let lastwinnr = winnr("$")
8051 let curword = s:NetrwGetWord()
8052 let choice = 0
8053 let s:prevwinopen= 1 " lets s:NetrwTreeDir() know that NetrwPrevWinOpen called it (s:NetrwTreeDir() will unlet s:prevwinopen)
8054 let s:treedir = s:NetrwTreeDir(a:islocal)
8055 let curdir = s:treedir
8056
8057 let didsplit = 0
8058 if lastwinnr == 1
8059 " if only one window, open a new one first
8060 " g:netrw_preview=0: preview window shown in a horizontally split window
8061 " g:netrw_preview=1: preview window shown in a vertically split window
8062 if g:netrw_preview
8063 " vertically split preview window
8064 let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
8065 exe (g:netrw_alto? "top " : "bot ")."vert ".winsz."wincmd s"
8066 else
8067 " horizontally split preview window
8068 let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
8069 exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
8070 endif
8071 let didsplit = 1
8072
8073 else
8074 NetrwKeepj call s:SaveBufVars()
8075 let eikeep= &ei
8076 setl ei=all
8077 wincmd p
8078
8079 if exists("s:lexplore_win") && s:lexplore_win == winnr()
8080 " whoops -- user trying to open file in the Lexplore window.
8081 " Use Lexplore's opening-file window instead.
8082 " exe g:netrw_chgwin."wincmd w"
8083 wincmd p
8084 call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord(),1))
8085 endif
8086
8087 " prevwinnr: the window number of the "prev" window
8088 " prevbufnr: the buffer number of the buffer in the "prev" window
8089 " bnrcnt : the qty of windows open on the "prev" buffer
8090 let prevwinnr = winnr()
8091 let prevbufnr = bufnr("%")
8092 let prevbufname = bufname("%")
8093 let prevmod = &mod
8094 let bnrcnt = 0
8095 NetrwKeepj call s:RestoreBufVars()
8096
8097 " if the previous window's buffer has been changed (ie. its modified flag is set),
8098 " and it doesn't appear in any other extant window, then ask the
8099 " user if s/he wants to abandon modifications therein.
8100 if prevmod
8101 windo if winbufnr(0) == prevbufnr | let bnrcnt=bnrcnt+1 | endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01008102 exe prevwinnr."wincmd w"
8103
8104 if bnrcnt == 1 && &hidden == 0
8105 " only one copy of the modified buffer in a window, and
8106 " hidden not set, so overwriting will lose the modified file. Ask first...
8107 let choice = confirm("Save modified buffer<".prevbufname."> first?","&Yes\n&No\n&Cancel")
8108 let &ei= eikeep
8109
8110 if choice == 1
8111 " Yes -- write file & then browse
8112 let v:errmsg= ""
8113 sil w
8114 if v:errmsg != ""
8115 call netrw#ErrorMsg(s:ERROR,"unable to write <".(exists("prevbufname")? prevbufname : 'n/a').">!",30)
8116 exe origwin."wincmd w"
8117 let &ei = eikeep
8118 let @@ = ykeep
8119 return choice
8120 endif
8121
8122 elseif choice == 2
8123 " No -- don't worry about changed file, just browse anyway
8124 echomsg "**note** changes to ".prevbufname." abandoned"
8125
8126 else
8127 " Cancel -- don't do this
8128 exe origwin."wincmd w"
8129 let &ei= eikeep
8130 let @@ = ykeep
8131 return choice
8132 endif
8133 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008134 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01008135 let &ei= eikeep
Bram Moolenaar446cb832008-06-24 21:56:24 +00008136 endif
8137
8138 " restore b:netrw_curdir (window split/enew may have lost it)
8139 let b:netrw_curdir= curdir
8140 if a:islocal < 2
Luca Saccarolac363ca12024-12-19 20:16:18 +01008141 if a:islocal
8142 call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(a:islocal,curword,0))
8143 else
8144 call s:NetrwBrowse(a:islocal,s:NetrwBrowseChgDir(a:islocal,curword,0))
8145 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008146 endif
Bram Moolenaar97d62492012-11-15 21:28:22 +01008147 let @@= ykeep
Bram Moolenaar446cb832008-06-24 21:56:24 +00008148 return choice
8149endfun
8150
8151" ---------------------------------------------------------------------
8152" s:NetrwUpload: load fname to tgt (used by NetrwMarkFileCopy()) {{{2
8153" Always assumed to be local -> remote
8154" call s:NetrwUpload(filename, target)
8155" call s:NetrwUpload(filename, target, fromdirectory)
8156fun! s:NetrwUpload(fname,tgt,...)
Luca Saccarolac363ca12024-12-19 20:16:18 +01008157 " 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 +00008158
Bram Moolenaara0f849e2015-10-30 14:37:44 +01008159 if a:tgt =~ '^\a\{3,}://'
Luca Saccarolac363ca12024-12-19 20:16:18 +01008160 let tgtdir= substitute(a:tgt,'^\a\{3,}://[^/]\+/\(.\{-}\)$','\1','')
Bram Moolenaar446cb832008-06-24 21:56:24 +00008161 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01008162 let tgtdir= substitute(a:tgt,'^\(.*\)/[^/]*$','\1','')
Bram Moolenaar446cb832008-06-24 21:56:24 +00008163 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01008164 " call Decho("tgtdir<".tgtdir.">",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00008165
8166 if a:0 > 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01008167 let fromdir= a:1
Bram Moolenaar446cb832008-06-24 21:56:24 +00008168 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01008169 let fromdir= getcwd()
Bram Moolenaar446cb832008-06-24 21:56:24 +00008170 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01008171 " call Decho("fromdir<".fromdir.">",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00008172
8173 if type(a:fname) == 1
Luca Saccarolac363ca12024-12-19 20:16:18 +01008174 " handle uploading a single file using NetWrite
8175 " call Decho("handle uploading a single file via NetWrite",'~'.expand("<slnum>"))
8176 1split
8177 " call Decho("exe e ".fnameescape(s:NetrwFile(a:fname)),'~'.expand("<slnum>"))
8178 exe "NetrwKeepj e ".fnameescape(s:NetrwFile(a:fname))
8179 " call Decho("now locally editing<".expand("%").">, has ".line("$")." lines",'~'.expand("<slnum>"))
8180 if a:tgt =~ '/$'
8181 let wfname= substitute(a:fname,'^.*/','','')
8182 " call Decho("exe w! ".fnameescape(wfname),'~'.expand("<slnum>"))
8183 exe "w! ".fnameescape(a:tgt.wfname)
8184 else
8185 " call Decho("writing local->remote: exe w ".fnameescape(a:tgt),'~'.expand("<slnum>"))
8186 exe "w ".fnameescape(a:tgt)
8187 " call Decho("done writing local->remote",'~'.expand("<slnum>"))
8188 endif
8189 q!
Bram Moolenaar446cb832008-06-24 21:56:24 +00008190
8191 elseif type(a:fname) == 3
Luca Saccarolac363ca12024-12-19 20:16:18 +01008192 " handle uploading a list of files via scp
8193 " call Decho("handle uploading a list of files via scp",'~'.expand("<slnum>"))
8194 let curdir= getcwd()
8195 if a:tgt =~ '^scp:'
8196 if s:NetrwLcd(fromdir)
8197 " call Dret("s:NetrwUpload : lcd failure")
8198 return
Bram Moolenaar5b435d62012-04-05 17:33:26 +02008199 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01008200 let filelist= deepcopy(s:netrwmarkfilelist_{bufnr('%')})
8201 let args = join(map(filelist,"s:ShellEscape(v:val, 1)"))
8202 if exists("g:netrw_port") && g:netrw_port != ""
8203 let useport= " ".g:netrw_scpport." ".g:netrw_port
8204 else
8205 let useport= ""
8206 endif
8207 let machine = substitute(a:tgt,'^scp://\([^/:]\+\).*$','\1','')
8208 let tgt = substitute(a:tgt,'^scp://[^/]\+/\(.*\)$','\1','')
8209 call s:NetrwExe(s:netrw_silentxfer."!".g:netrw_scp_cmd.s:ShellEscape(useport,1)." ".args." ".s:ShellEscape(machine.":".tgt,1))
8210 if s:NetrwLcd(curdir)
8211 " call Dret("s:NetrwUpload : lcd failure")
8212 return
8213 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008214
Luca Saccarolac363ca12024-12-19 20:16:18 +01008215 elseif a:tgt =~ '^ftp:'
8216 call s:NetrwMethod(a:tgt)
Bram Moolenaar446cb832008-06-24 21:56:24 +00008217
Luca Saccarolac363ca12024-12-19 20:16:18 +01008218 if b:netrw_method == 2
8219 " handle uploading a list of files via ftp+.netrc
8220 let netrw_fname = b:netrw_fname
8221 sil NetrwKeepj new
8222 " call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00008223
Luca Saccarolac363ca12024-12-19 20:16:18 +01008224 NetrwKeepj put =g:netrw_ftpmode
8225 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00008226
Luca Saccarolac363ca12024-12-19 20:16:18 +01008227 if exists("g:netrw_ftpextracmd")
8228 NetrwKeepj put =g:netrw_ftpextracmd
8229 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8230 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008231
Luca Saccarolac363ca12024-12-19 20:16:18 +01008232 NetrwKeepj call setline(line("$")+1,'lcd "'.fromdir.'"')
8233 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8234
8235 if tgtdir == ""
8236 let tgtdir= '/'
8237 endif
8238 NetrwKeepj call setline(line("$")+1,'cd "'.tgtdir.'"')
8239 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8240
8241 for fname in a:fname
8242 NetrwKeepj call setline(line("$")+1,'put "'.s:NetrwFile(fname).'"')
8243 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8244 endfor
8245
8246 if exists("g:netrw_port") && g:netrw_port != ""
8247 call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)." ".s:ShellEscape(g:netrw_port,1))
8248 else
8249 " call Decho("filter input window#".winnr(),'~'.expand("<slnum>"))
8250 call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1))
8251 endif
8252 " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
8253 sil NetrwKeepj g/Local directory now/d
8254 call histdel("/",-1)
8255 if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
8256 call netrw#ErrorMsg(s:ERROR,getline(1),14)
8257 else
8258 bw!|q
8259 endif
8260
8261 elseif b:netrw_method == 3
8262 " upload with ftp + machine, id, passwd, and fname (ie. no .netrc)
8263 let netrw_fname= b:netrw_fname
8264 NetrwKeepj call s:SaveBufVars()|sil NetrwKeepj new|NetrwKeepj call s:RestoreBufVars()
8265 let tmpbufnr= bufnr("%")
8266 setl ff=unix
8267
8268 if exists("g:netrw_port") && g:netrw_port != ""
8269 NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
shane.xb.qianc673b802024-12-20 19:36:40 +01008270 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
Luca Saccarolac363ca12024-12-19 20:16:18 +01008271 else
8272 NetrwKeepj put ='open '.g:netrw_machine
8273 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8274 endif
8275
8276 if exists("g:netrw_uid") && g:netrw_uid != ""
8277 if exists("g:netrw_ftp") && g:netrw_ftp == 1
8278 NetrwKeepj put =g:netrw_uid
8279 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8280 if exists("s:netrw_passwd")
8281 NetrwKeepj call setline(line("$")+1,'"'.s:netrw_passwd.'"')
8282 endif
shane.xb.qianc673b802024-12-20 19:36:40 +01008283 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
Luca Saccarolac363ca12024-12-19 20:16:18 +01008284 elseif exists("s:netrw_passwd")
8285 NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
8286 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8287 endif
8288 endif
8289
8290 NetrwKeepj call setline(line("$")+1,'lcd "'.fromdir.'"')
8291 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8292
8293 if exists("b:netrw_fname") && b:netrw_fname != ""
8294 NetrwKeepj call setline(line("$")+1,'cd "'.b:netrw_fname.'"')
8295 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8296 endif
8297
8298 if exists("g:netrw_ftpextracmd")
8299 NetrwKeepj put =g:netrw_ftpextracmd
8300 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8301 endif
8302
8303 for fname in a:fname
8304 NetrwKeepj call setline(line("$")+1,'put "'.fname.'"')
8305 " call Decho("filter input: ".getline('$'),'~'.expand("<slnum>"))
8306 endfor
8307
8308 " perform ftp:
8309 " -i : turns off interactive prompting from ftp
8310 " -n unix : DON'T use <.netrc>, even though it exists
8311 " -n win32: quit being obnoxious about password
8312 NetrwKeepj norm! 1G"_dd
8313 call s:NetrwExe(s:netrw_silentxfer."%!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
8314 " If the result of the ftp operation isn't blank, show an error message (tnx to Doug Claar)
8315 sil NetrwKeepj g/Local directory now/d
8316 call histdel("/",-1)
8317 if getline(1) !~ "^$" && !exists("g:netrw_quiet") && getline(1) !~ '^Trying '
8318 let debugkeep= &debug
8319 setl debug=msg
8320 call netrw#ErrorMsg(s:ERROR,getline(1),15)
8321 let &debug = debugkeep
8322 let mod = 1
8323 else
8324 bw!|q
8325 endif
8326 elseif !exists("b:netrw_method") || b:netrw_method < 0
8327 " call Dret("s:#NetrwUpload : unsupported method")
8328 return
8329 endif
8330 else
8331 call netrw#ErrorMsg(s:ERROR,"can't obtain files with protocol from<".a:tgt.">",63)
Bram Moolenaar446cb832008-06-24 21:56:24 +00008332 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008333 endif
8334
Luca Saccarolac363ca12024-12-19 20:16:18 +01008335 " call Dret("s:NetrwUpload")
Bram Moolenaar446cb832008-06-24 21:56:24 +00008336endfun
8337
8338" ---------------------------------------------------------------------
Bram Moolenaar85850f32019-07-19 22:05:51 +02008339" s:NetrwPreview: supports netrw's "p" map {{{2
Bram Moolenaar446cb832008-06-24 21:56:24 +00008340fun! s:NetrwPreview(path) range
Luca Saccarolac363ca12024-12-19 20:16:18 +01008341 " call Dfunc("NetrwPreview(path<".a:path.">)")
8342 " call Decho("g:netrw_alto =".(exists("g:netrw_alto")? g:netrw_alto : 'n/a'),'~'.expand("<slnum>"))
8343 " call Decho("g:netrw_preview=".(exists("g:netrw_preview")? g:netrw_preview : 'n/a'),'~'.expand("<slnum>"))
Bram Moolenaar97d62492012-11-15 21:28:22 +01008344 let ykeep= @@
Bram Moolenaar85850f32019-07-19 22:05:51 +02008345 NetrwKeepj call s:NetrwOptionsSave("s:")
8346 if a:path !~ '^\*\{1,2}/' && a:path !~ '^\a\{3,}://'
Luca Saccarolac363ca12024-12-19 20:16:18 +01008347 NetrwKeepj call s:NetrwOptionsSafe(1)
Bram Moolenaar85850f32019-07-19 22:05:51 +02008348 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01008349 NetrwKeepj call s:NetrwOptionsSafe(0)
Bram Moolenaar85850f32019-07-19 22:05:51 +02008350 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008351 if has("quickfix")
Luca Saccarolac363ca12024-12-19 20:16:18 +01008352 " call Decho("has quickfix",'~'.expand("<slnum>"))
8353 if !isdirectory(s:NetrwFile(a:path))
8354 " call Decho("good; not previewing a directory",'~'.expand("<slnum>"))
8355 if g:netrw_preview
8356 " vertical split
8357 let pvhkeep = &pvh
8358 let winsz = (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
8359 let &pvh = winwidth(0) - winsz
shane.xb.qianc673b802024-12-20 19:36:40 +01008360 " call Decho("g:netrw_preview: winsz=".winsz." &pvh=".&pvh." (temporarily) g:netrw_winsize=".g:netrw_winsize,'~'.expand("<slnum>"))
Luca Saccarolac363ca12024-12-19 20:16:18 +01008361 else
8362 " horizontal split
8363 let pvhkeep = &pvh
8364 let winsz = (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
8365 let &pvh = winheight(0) - winsz
8366 " call Decho("!g:netrw_preview: winsz=".winsz." &pvh=".&pvh." (temporarily) g:netrw_winsize=".g:netrw_winsize,'~'.expand("<slnum>"))
8367 endif
8368 " g:netrw_preview g:netrw_alto
8369 " 1 : vert 1: top -- preview window is vertically split off and on the left
8370 " 1 : vert 0: bot -- preview window is vertically split off and on the right
8371 " 0 : 1: top -- preview window is horizontally split off and on the top
8372 " 0 : 0: bot -- preview window is horizontally split off and on the bottom
8373 "
8374 " Note that the file being previewed is already known to not be a directory, hence we can avoid doing a LocalBrowseCheck() check via
8375 " the BufEnter event set up in netrwPlugin.vim
8376 " call Decho("exe ".(g:netrw_alto? "top " : "bot ").(g:netrw_preview? "vert " : "")."pedit ".fnameescape(a:path),'~'.expand("<slnum>"))
8377 let eikeep = &ei
8378 set ei=BufEnter
8379 exe (g:netrw_alto? "top " : "bot ").(g:netrw_preview? "vert " : "")."pedit ".fnameescape(a:path)
8380 let &ei= eikeep
8381 " call Decho("winnr($)=".winnr("$"),'~'.expand("<slnum>"))
8382 if exists("pvhkeep")
8383 let &pvh= pvhkeep
8384 endif
8385 elseif !exists("g:netrw_quiet")
8386 NetrwKeepj call netrw#ErrorMsg(s:WARNING,"sorry, cannot preview a directory such as <".a:path.">",38)
Bram Moolenaar00a927d2010-05-14 23:24:24 +02008387 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008388 elseif !exists("g:netrw_quiet")
Luca Saccarolac363ca12024-12-19 20:16:18 +01008389 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 +00008390 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02008391 NetrwKeepj call s:NetrwOptionsRestore("s:")
Bram Moolenaar97d62492012-11-15 21:28:22 +01008392 let @@= ykeep
Luca Saccarolac363ca12024-12-19 20:16:18 +01008393 " call Dret("NetrwPreview")
Bram Moolenaar446cb832008-06-24 21:56:24 +00008394endfun
8395
8396" ---------------------------------------------------------------------
8397" s:NetrwRefresh: {{{2
8398fun! s:NetrwRefresh(islocal,dirname)
Luca Saccarolac363ca12024-12-19 20:16:18 +01008399 " 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 +00008400 " at the current time (Mar 19, 2007) all calls to NetrwRefresh() call NetrwBrowseChgDir() first.
Bram Moolenaarff034192013-04-24 18:51:19 +02008401 setl ma noro
Luca Saccarolac363ca12024-12-19 20:16:18 +01008402 " call Decho("setl ma noro",'~'.expand("<slnum>"))
8403 " call Decho("clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
Bram Moolenaar97d62492012-11-15 21:28:22 +01008404 let ykeep = @@
Bram Moolenaar85850f32019-07-19 22:05:51 +02008405 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
Luca Saccarolac363ca12024-12-19 20:16:18 +01008406 if !exists("w:netrw_treetop")
8407 if exists("b:netrw_curdir")
8408 let w:netrw_treetop= b:netrw_curdir
8409 else
8410 let w:netrw_treetop= getcwd()
8411 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +02008412 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01008413 NetrwKeepj call s:NetrwRefreshTreeDict(w:netrw_treetop)
Bram Moolenaar85850f32019-07-19 22:05:51 +02008414 endif
Bram Moolenaar13600302014-05-22 18:26:40 +02008415
8416 " save the cursor position before refresh.
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008417 let screenposn = winsaveview()
Luca Saccarolac363ca12024-12-19 20:16:18 +01008418 " call Decho("saving posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
Bram Moolenaara0f849e2015-10-30 14:37:44 +01008419
Luca Saccarolac363ca12024-12-19 20:16:18 +01008420 " call Decho("win#".winnr().": ".winheight(0)."x".winwidth(0)." curfile<".expand("%").">",'~'.expand("<slnum>"))
8421 " call Decho("clearing buffer prior to refresh",'~'.expand("<slnum>"))
Bram Moolenaara0f849e2015-10-30 14:37:44 +01008422 sil! NetrwKeepj %d _
Bram Moolenaar446cb832008-06-24 21:56:24 +00008423 if a:islocal
Luca Saccarolac363ca12024-12-19 20:16:18 +01008424 NetrwKeepj call netrw#LocalBrowseCheck(a:dirname)
Bram Moolenaar446cb832008-06-24 21:56:24 +00008425 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01008426 NetrwKeepj call s:NetrwBrowse(a:islocal,a:dirname)
Bram Moolenaar446cb832008-06-24 21:56:24 +00008427 endif
Bram Moolenaar13600302014-05-22 18:26:40 +02008428
8429 " restore position
Luca Saccarolac363ca12024-12-19 20:16:18 +01008430 " call Decho("restoring posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008431 NetrwKeepj call winrestview(screenposn)
Bram Moolenaar446cb832008-06-24 21:56:24 +00008432
8433 " restore file marks
Bram Moolenaar85850f32019-07-19 22:05:51 +02008434 if has("syntax") && exists("g:syntax_on") && g:syntax_on
Luca Saccarolac363ca12024-12-19 20:16:18 +01008435 if exists("s:netrwmarkfilemtch_{bufnr('%')}") && s:netrwmarkfilemtch_{bufnr("%")} != ""
8436 " " call Decho("exe 2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/",'~'.expand("<slnum>"))
8437 exe "2match netrwMarkFile /".s:netrwmarkfilemtch_{bufnr("%")}."/"
8438 else
8439 " " call Decho("2match none (bufnr(%)=".bufnr("%")."<".bufname("%").">)",'~'.expand("<slnum>"))
8440 2match none
8441 endif
8442 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008443
Luca Saccarolac363ca12024-12-19 20:16:18 +01008444 " restore
Bram Moolenaar97d62492012-11-15 21:28:22 +01008445 let @@= ykeep
Luca Saccarolac363ca12024-12-19 20:16:18 +01008446 " call Dret("s:NetrwRefresh")
Bram Moolenaar446cb832008-06-24 21:56:24 +00008447endfun
8448
8449" ---------------------------------------------------------------------
8450" s:NetrwRefreshDir: refreshes a directory by name {{{2
8451" Called by NetrwMarkFileCopy()
Bram Moolenaara6878372014-03-22 21:02:50 +01008452" Interfaces to s:NetrwRefresh() and s:LocalBrowseRefresh()
Bram Moolenaar446cb832008-06-24 21:56:24 +00008453fun! s:NetrwRefreshDir(islocal,dirname)
Bram Moolenaar446cb832008-06-24 21:56:24 +00008454 if g:netrw_fastbrowse == 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01008455 " slowest mode (keep buffers refreshed, local or remote)
8456 let tgtwin= bufwinnr(a:dirname)
Bram Moolenaar446cb832008-06-24 21:56:24 +00008457
Luca Saccarolac363ca12024-12-19 20:16:18 +01008458 if tgtwin > 0
8459 " tgtwin is being displayed, so refresh it
8460 let curwin= winnr()
8461 exe tgtwin."wincmd w"
8462 NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
8463 exe curwin."wincmd w"
Bram Moolenaar446cb832008-06-24 21:56:24 +00008464
Luca Saccarolac363ca12024-12-19 20:16:18 +01008465 elseif bufnr(a:dirname) > 0
8466 let bn= bufnr(a:dirname)
8467 exe "sil keepj bd ".bn
8468 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008469
8470 elseif g:netrw_fastbrowse <= 1
Luca Saccarolac363ca12024-12-19 20:16:18 +01008471 NetrwKeepj call s:LocalBrowseRefresh()
Bram Moolenaar446cb832008-06-24 21:56:24 +00008472 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008473endfun
8474
8475" ---------------------------------------------------------------------
Bram Moolenaar13600302014-05-22 18:26:40 +02008476" s:NetrwSetChgwin: set g:netrw_chgwin; a <cr> will use the specified
8477" window number to do its editing in.
8478" Supports [count]C where the count, if present, is used to specify
8479" a window to use for editing via the <cr> mapping.
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01008480fun! s:NetrwSetChgwin(...)
Luca Saccarolac363ca12024-12-19 20:16:18 +01008481 " call Dfunc("s:NetrwSetChgwin() v:count=".v:count)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01008482 if a:0 > 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01008483 " call Decho("a:1<".a:1.">",'~'.expand("<slnum>"))
8484 if a:1 == "" " :NetrwC win#
8485 let g:netrw_chgwin= winnr()
8486 else " :NetrwC
8487 let g:netrw_chgwin= a:1
8488 endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01008489 elseif v:count > 0 " [count]C
Luca Saccarolac363ca12024-12-19 20:16:18 +01008490 let g:netrw_chgwin= v:count
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01008491 else " C
Luca Saccarolac363ca12024-12-19 20:16:18 +01008492 let g:netrw_chgwin= winnr()
Bram Moolenaar13600302014-05-22 18:26:40 +02008493 endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +01008494 echo "editing window now set to window#".g:netrw_chgwin
Luca Saccarolac363ca12024-12-19 20:16:18 +01008495 " call Dret("s:NetrwSetChgwin : g:netrw_chgwin=".g:netrw_chgwin)
Bram Moolenaar13600302014-05-22 18:26:40 +02008496endfun
8497
8498" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +00008499" s:NetrwSetSort: sets up the sort based on the g:netrw_sort_sequence {{{2
8500" What this function does is to compute a priority for the patterns
8501" in the g:netrw_sort_sequence. It applies a substitute to any
8502" "files" that satisfy each pattern, putting the priority / in
8503" front. An "*" pattern handles the default priority.
8504fun! s:NetrwSetSort()
Luca Saccarolac363ca12024-12-19 20:16:18 +01008505 " call Dfunc("SetSort() bannercnt=".w:netrw_bannercnt)
Bram Moolenaar97d62492012-11-15 21:28:22 +01008506 let ykeep= @@
Bram Moolenaar446cb832008-06-24 21:56:24 +00008507 if w:netrw_liststyle == s:LONGLIST
Luca Saccarolac363ca12024-12-19 20:16:18 +01008508 let seqlist = substitute(g:netrw_sort_sequence,'\$','\\%(\t\\|\$\\)','ge')
Bram Moolenaar446cb832008-06-24 21:56:24 +00008509 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01008510 let seqlist = g:netrw_sort_sequence
Bram Moolenaar446cb832008-06-24 21:56:24 +00008511 endif
8512 " sanity check -- insure that * appears somewhere
8513 if seqlist == ""
Luca Saccarolac363ca12024-12-19 20:16:18 +01008514 let seqlist= '*'
Bram Moolenaar446cb832008-06-24 21:56:24 +00008515 elseif seqlist !~ '\*'
Luca Saccarolac363ca12024-12-19 20:16:18 +01008516 let seqlist= seqlist.',*'
Bram Moolenaar446cb832008-06-24 21:56:24 +00008517 endif
8518 let priority = 1
8519 while seqlist != ""
Luca Saccarolac363ca12024-12-19 20:16:18 +01008520 if seqlist =~ ','
8521 let seq = substitute(seqlist,',.*$','','e')
8522 let seqlist = substitute(seqlist,'^.\{-},\(.*\)$','\1','e')
8523 else
8524 let seq = seqlist
8525 let seqlist = ""
8526 endif
8527 if priority < 10
8528 let spriority= "00".priority.g:netrw_sepchr
8529 elseif priority < 100
8530 let spriority= "0".priority.g:netrw_sepchr
8531 else
8532 let spriority= priority.g:netrw_sepchr
8533 endif
8534 " call Decho("priority=".priority." spriority<".spriority."> seq<".seq."> seqlist<".seqlist.">",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00008535
Luca Saccarolac363ca12024-12-19 20:16:18 +01008536 " sanity check
8537 if w:netrw_bannercnt > line("$")
8538 " apparently no files were left after a Hiding pattern was used
8539 " call Dret("SetSort : no files left after hiding")
8540 return
8541 endif
8542 if seq == '*'
8543 let starpriority= spriority
8544 else
8545 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/'.seq.'/s/^/'.spriority.'/'
8546 call histdel("/",-1)
8547 " sometimes multiple sorting patterns will match the same file or directory.
8548 " The following substitute is intended to remove the excess matches.
8549 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/^\d\{3}'.g:netrw_sepchr.'\d\{3}\//s/^\d\{3}'.g:netrw_sepchr.'\(\d\{3}\/\).\@=/\1/e'
8550 NetrwKeepj call histdel("/",-1)
8551 endif
8552 let priority = priority + 1
Bram Moolenaar446cb832008-06-24 21:56:24 +00008553 endwhile
8554 if exists("starpriority")
Luca Saccarolac363ca12024-12-19 20:16:18 +01008555 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$v/^\d\{3}'.g:netrw_sepchr.'/s/^/'.starpriority.'/e'
8556 NetrwKeepj call histdel("/",-1)
Bram Moolenaar446cb832008-06-24 21:56:24 +00008557 endif
8558
8559 " Following line associated with priority -- items that satisfy a priority
8560 " pattern get prefixed by ###/ which permits easy sorting by priority.
8561 " Sometimes files can satisfy multiple priority patterns -- only the latest
8562 " priority pattern needs to be retained. So, at this point, these excess
8563 " priority prefixes need to be removed, but not directories that happen to
8564 " be just digits themselves.
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01008565 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\d\{3}'.g:netrw_sepchr.'\)\%(\d\{3}'.g:netrw_sepchr.'\)\+\ze./\1/e'
8566 NetrwKeepj call histdel("/",-1)
Bram Moolenaar97d62492012-11-15 21:28:22 +01008567 let @@= ykeep
Bram Moolenaar446cb832008-06-24 21:56:24 +00008568
Luca Saccarolac363ca12024-12-19 20:16:18 +01008569 " call Dret("SetSort")
Bram Moolenaar446cb832008-06-24 21:56:24 +00008570endfun
8571
Bram Moolenaarff034192013-04-24 18:51:19 +02008572" ---------------------------------------------------------------------
8573" s:NetrwSetTgt: sets the target to the specified choice index {{{2
8574" Implements [count]Tb (bookhist<b>)
8575" [count]Th (bookhist<h>)
8576" See :help netrw-qb for how to make the choice.
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008577fun! s:NetrwSetTgt(islocal,bookhist,choice)
Luca Saccarolac363ca12024-12-19 20:16:18 +01008578 " call Dfunc("s:NetrwSetTgt(islocal=".a:islocal." bookhist<".a:bookhist."> choice#".a:choice.")")
Bram Moolenaarff034192013-04-24 18:51:19 +02008579
8580 if a:bookhist == 'b'
Luca Saccarolac363ca12024-12-19 20:16:18 +01008581 " supports choosing a bookmark as a target using a qb-generated list
8582 let choice= a:choice - 1
8583 if exists("g:netrw_bookmarklist[".choice."]")
8584 call netrw#MakeTgt(g:netrw_bookmarklist[choice])
8585 else
8586 echomsg "Sorry, bookmark#".a:choice." doesn't exist!"
8587 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02008588
8589 elseif a:bookhist == 'h'
Luca Saccarolac363ca12024-12-19 20:16:18 +01008590 " supports choosing a history stack entry as a target using a qb-generated list
8591 let choice= (a:choice % g:netrw_dirhistmax) + 1
8592 if exists("g:netrw_dirhist_".choice)
8593 let histentry = g:netrw_dirhist_{choice}
8594 call netrw#MakeTgt(histentry)
8595 else
8596 echomsg "Sorry, history#".a:choice." not available!"
8597 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02008598 endif
8599
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008600 " refresh the display
8601 if !exists("b:netrw_curdir")
Luca Saccarolac363ca12024-12-19 20:16:18 +01008602 let b:netrw_curdir= getcwd()
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008603 endif
8604 call s:NetrwRefresh(a:islocal,b:netrw_curdir)
8605
Luca Saccarolac363ca12024-12-19 20:16:18 +01008606 " call Dret("s:NetrwSetTgt")
Bram Moolenaarff034192013-04-24 18:51:19 +02008607endfun
8608
Bram Moolenaar446cb832008-06-24 21:56:24 +00008609" =====================================================================
Bram Moolenaar85850f32019-07-19 22:05:51 +02008610" s:NetrwSortStyle: change sorting style (name - time - size - exten) and refresh display {{{2
Bram Moolenaar446cb832008-06-24 21:56:24 +00008611fun! s:NetrwSortStyle(islocal)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01008612 NetrwKeepj call s:NetrwSaveWordPosn()
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008613 let svpos= winsaveview()
Bram Moolenaar446cb832008-06-24 21:56:24 +00008614
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +02008615 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 +01008616 NetrwKeepj norm! 0
Tom Benham64a536d2024-11-07 21:15:03 +01008617 NetrwKeepj call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008618 NetrwKeepj call winrestview(svpos)
Bram Moolenaar446cb832008-06-24 21:56:24 +00008619endfun
8620
8621" ---------------------------------------------------------------------
8622" s:NetrwSplit: mode {{{2
8623" =0 : net and o
8624" =1 : net and t
8625" =2 : net and v
8626" =3 : local and o
8627" =4 : local and t
8628" =5 : local and v
8629fun! s:NetrwSplit(mode)
Bram Moolenaar446cb832008-06-24 21:56:24 +00008630
Bram Moolenaar97d62492012-11-15 21:28:22 +01008631 let ykeep= @@
Bram Moolenaar446cb832008-06-24 21:56:24 +00008632 call s:SaveWinVars()
8633
8634 if a:mode == 0
Luca Saccarolac363ca12024-12-19 20:16:18 +01008635 " remote and o
8636 let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
8637 if winsz == 0|let winsz= ""|endif
8638 exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
8639 let s:didsplit= 1
8640 NetrwKeepj call s:RestoreWinVars()
8641 NetrwKeepj call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord(),1))
8642 unlet s:didsplit
Bram Moolenaar446cb832008-06-24 21:56:24 +00008643
8644 elseif a:mode == 1
Luca Saccarolac363ca12024-12-19 20:16:18 +01008645 " remote and t
8646 let newdir = s:NetrwBrowseChgDir(0,s:NetrwGetWord(),1)
8647 tabnew
8648 let s:didsplit= 1
8649 NetrwKeepj call s:RestoreWinVars()
8650 NetrwKeepj call s:NetrwBrowse(0,newdir)
8651 unlet s:didsplit
Bram Moolenaar446cb832008-06-24 21:56:24 +00008652
8653 elseif a:mode == 2
Luca Saccarolac363ca12024-12-19 20:16:18 +01008654 " remote and v
8655 let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
8656 if winsz == 0|let winsz= ""|endif
8657 exe (g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v"
8658 let s:didsplit= 1
8659 NetrwKeepj call s:RestoreWinVars()
8660 NetrwKeepj call s:NetrwBrowse(0,s:NetrwBrowseChgDir(0,s:NetrwGetWord(),1))
8661 unlet s:didsplit
Bram Moolenaar446cb832008-06-24 21:56:24 +00008662
8663 elseif a:mode == 3
Luca Saccarolac363ca12024-12-19 20:16:18 +01008664 " local and o
8665 let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winheight(0))/100 : -g:netrw_winsize
8666 if winsz == 0|let winsz= ""|endif
8667 exe (g:netrw_alto? "bel " : "abo ").winsz."wincmd s"
8668 let s:didsplit= 1
8669 NetrwKeepj call s:RestoreWinVars()
8670 NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord(),1))
8671 unlet s:didsplit
Bram Moolenaar446cb832008-06-24 21:56:24 +00008672
8673 elseif a:mode == 4
Luca Saccarolac363ca12024-12-19 20:16:18 +01008674 " local and t
8675 let cursorword = s:NetrwGetWord()
8676 let eikeep = &ei
8677 let netrw_winnr = winnr()
8678 let netrw_line = line(".")
8679 let netrw_col = virtcol(".")
8680 NetrwKeepj norm! H0
8681 let netrw_hline = line(".")
Bram Moolenaara6878372014-03-22 21:02:50 +01008682 setl ei=all
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01008683 exe "NetrwKeepj norm! ".netrw_hline."G0z\<CR>"
8684 exe "NetrwKeepj norm! ".netrw_line."G0".netrw_col."\<bar>"
Luca Saccarolac363ca12024-12-19 20:16:18 +01008685 let &ei = eikeep
8686 let netrw_curdir = s:NetrwTreeDir(0)
8687 tabnew
8688 let b:netrw_curdir = netrw_curdir
8689 let s:didsplit = 1
8690 NetrwKeepj call s:RestoreWinVars()
8691 NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,cursorword,0))
8692 if &ft == "netrw"
8693 setl ei=all
8694 exe "NetrwKeepj norm! ".netrw_hline."G0z\<CR>"
8695 exe "NetrwKeepj norm! ".netrw_line."G0".netrw_col."\<bar>"
8696 let &ei= eikeep
8697 endif
8698 unlet s:didsplit
Bram Moolenaar446cb832008-06-24 21:56:24 +00008699
8700 elseif a:mode == 5
Luca Saccarolac363ca12024-12-19 20:16:18 +01008701 " local and v
8702 let winsz= (g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize
8703 if winsz == 0|let winsz= ""|endif
8704 exe (g:netrw_altv? "rightb " : "lefta ").winsz."wincmd v"
8705 let s:didsplit= 1
8706 NetrwKeepj call s:RestoreWinVars()
8707 NetrwKeepj call netrw#LocalBrowseCheck(s:NetrwBrowseChgDir(1,s:NetrwGetWord(),1))
8708 unlet s:didsplit
Bram Moolenaar446cb832008-06-24 21:56:24 +00008709
8710 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01008711 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"(NetrwSplit) unsupported mode=".a:mode,45)
Bram Moolenaar446cb832008-06-24 21:56:24 +00008712 endif
8713
Bram Moolenaar97d62492012-11-15 21:28:22 +01008714 let @@= ykeep
Bram Moolenaar446cb832008-06-24 21:56:24 +00008715endfun
8716
8717" ---------------------------------------------------------------------
Bram Moolenaarff034192013-04-24 18:51:19 +02008718" s:NetrwTgtMenu: {{{2
8719fun! s:NetrwTgtMenu()
8720 if !exists("s:netrw_menucnt")
Luca Saccarolac363ca12024-12-19 20:16:18 +01008721 return
Bram Moolenaar446cb832008-06-24 21:56:24 +00008722 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01008723 " call Dfunc("s:NetrwTgtMenu()")
Bram Moolenaarff034192013-04-24 18:51:19 +02008724
8725 " the following test assures that gvim is running, has menus available, and has menus enabled.
8726 if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
Luca Saccarolac363ca12024-12-19 20:16:18 +01008727 if exists("g:NetrwTopLvlMenu")
8728 " call Decho("removing ".g:NetrwTopLvlMenu."Bookmarks menu item(s)",'~'.expand("<slnum>"))
8729 exe 'sil! unmenu '.g:NetrwTopLvlMenu.'Targets'
8730 endif
8731 if !exists("s:netrw_initbookhist")
8732 call s:NetrwBookHistRead()
8733 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02008734
Luca Saccarolac363ca12024-12-19 20:16:18 +01008735 " try to cull duplicate entries
8736 let tgtdict={}
Bram Moolenaara0f849e2015-10-30 14:37:44 +01008737
Luca Saccarolac363ca12024-12-19 20:16:18 +01008738 " target bookmarked places
8739 if exists("g:netrw_bookmarklist") && g:netrw_bookmarklist != [] && g:netrw_dirhistmax > 0
8740 " call Decho("installing bookmarks as easy targets",'~'.expand("<slnum>"))
8741 let cnt= 1
8742 for bmd in g:netrw_bookmarklist
8743 if has_key(tgtdict,bmd)
8744 let cnt= cnt + 1
8745 continue
8746 endif
8747 let tgtdict[bmd]= cnt
8748 let ebmd= escape(bmd,g:netrw_menu_escape)
8749 " show bookmarks for goto menu
8750 " call Decho("menu: Targets: ".bmd,'~'.expand("<slnum>"))
8751 exe 'sil! menu <silent> '.g:NetrwMenuPriority.".19.1.".cnt." ".g:NetrwTopLvlMenu.'Targets.'.ebmd." :call netrw#MakeTgt('".bmd."')\<cr>"
8752 let cnt= cnt + 1
8753 endfor
8754 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02008755
Luca Saccarolac363ca12024-12-19 20:16:18 +01008756 " target directory browsing history
8757 if exists("g:netrw_dirhistmax") && g:netrw_dirhistmax > 0
8758 " call Decho("installing history as easy targets (histmax=".g:netrw_dirhistmax.")",'~'.expand("<slnum>"))
8759 let histcnt = 1
8760 while histcnt <= g:netrw_dirhistmax
8761 let priority = g:netrw_dirhistcnt + histcnt
8762 if exists("g:netrw_dirhist_{histcnt}")
8763 let histentry = g:netrw_dirhist_{histcnt}
8764 if has_key(tgtdict,histentry)
8765 let histcnt = histcnt + 1
8766 continue
8767 endif
8768 let tgtdict[histentry] = histcnt
8769 let ehistentry = escape(histentry,g:netrw_menu_escape)
8770 " call Decho("menu: Targets: ".histentry,'~'.expand("<slnum>"))
8771 exe 'sil! menu <silent> '.g:NetrwMenuPriority.".19.2.".priority." ".g:NetrwTopLvlMenu.'Targets.'.ehistentry." :call netrw#MakeTgt('".histentry."')\<cr>"
8772 endif
8773 let histcnt = histcnt + 1
8774 endwhile
8775 endif
Bram Moolenaarff034192013-04-24 18:51:19 +02008776 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01008777 " call Dret("s:NetrwTgtMenu")
Bram Moolenaar446cb832008-06-24 21:56:24 +00008778endfun
8779
8780" ---------------------------------------------------------------------
8781" s:NetrwTreeDir: determine tree directory given current cursor position {{{2
8782" (full path directory with trailing slash returned)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01008783fun! s:NetrwTreeDir(islocal)
Bram Moolenaar446cb832008-06-24 21:56:24 +00008784
Bram Moolenaar89a9c152021-08-29 21:55:35 +02008785 if exists("s:treedir") && exists("s:prevwinopen")
Luca Saccarolac363ca12024-12-19 20:16:18 +01008786 " s:NetrwPrevWinOpen opens a "previous" window -- and thus needs to and does call s:NetrwTreeDir early
8787 let treedir= s:treedir
8788 unlet s:treedir
8789 unlet s:prevwinopen
8790 return treedir
Bram Moolenaar8d043172014-01-23 14:24:41 +01008791 endif
Bram Moolenaar89a9c152021-08-29 21:55:35 +02008792 if exists("s:prevwinopen")
Luca Saccarolac363ca12024-12-19 20:16:18 +01008793 unlet s:prevwinopen
Bram Moolenaar89a9c152021-08-29 21:55:35 +02008794 endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +01008795
Bram Moolenaar8d043172014-01-23 14:24:41 +01008796 if !exists("b:netrw_curdir") || b:netrw_curdir == ""
Luca Saccarolac363ca12024-12-19 20:16:18 +01008797 let b:netrw_curdir= getcwd()
Bram Moolenaar8d043172014-01-23 14:24:41 +01008798 endif
8799 let treedir = b:netrw_curdir
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008800 let s:treecurpos= winsaveview()
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008801
8802 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
Bram Moolenaar5c736222010-01-06 20:54:52 +01008803
Luca Saccarolac363ca12024-12-19 20:16:18 +01008804 " extract tree directory if on a line specifying a subdirectory (ie. ends with "/")
8805 let curline= substitute(getline('.'),"\t -->.*$",'','')
8806 if curline =~ '/$'
8807 let treedir= substitute(getline('.'),'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e')
8808 elseif curline =~ '@$'
8809 let potentialdir= resolve(s:NetrwTreePath(w:netrw_treetop))
8810 else
8811 let treedir= ""
8812 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008813
Luca Saccarolac363ca12024-12-19 20:16:18 +01008814 " detect user attempting to close treeroot
8815 if curline !~ '^'.s:treedepthstring && getline('.') != '..'
8816 " now force a refresh
8817 sil! NetrwKeepj %d _
8818 return b:netrw_curdir
8819 endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01008820
Luca Saccarolac363ca12024-12-19 20:16:18 +01008821 " COMBAK: a symbolic link may point anywhere -- so it will be used to start a new treetop
8822 " if a:islocal && curline =~ '@$' && isdirectory(s:NetrwFile(potentialdir))
8823 " let newdir = w:netrw_treetop.'/'.potentialdir
Christian Brabandt56b7da32024-02-29 17:48:14 +01008824 if a:islocal && curline =~ '@$'
8825 if isdirectory(s:NetrwFile(potentialdir))
Tom Benham64a536d2024-11-07 21:15:03 +01008826 let treedir = potentialdir
Christian Brabandt56b7da32024-02-29 17:48:14 +01008827 let w:netrw_treetop = treedir
8828 endif
8829 else
8830 let potentialdir= s:NetrwFile(substitute(curline,'^'.s:treedepthstring.'\+ \(.*\)@$','\1',''))
8831 let treedir = s:NetrwTreePath(w:netrw_treetop)
8832 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008833 endif
Bram Moolenaar8d043172014-01-23 14:24:41 +01008834
8835 " sanity maintenance: keep those //s away...
Bram Moolenaar446cb832008-06-24 21:56:24 +00008836 let treedir= substitute(treedir,'//$','/','')
Bram Moolenaar446cb832008-06-24 21:56:24 +00008837 return treedir
8838endfun
8839
8840" ---------------------------------------------------------------------
8841" s:NetrwTreeDisplay: recursive tree display {{{2
8842fun! s:NetrwTreeDisplay(dir,depth)
Tom Benham64a536d2024-11-07 21:15:03 +01008843 " ensure that there are no folds
Bram Moolenaarff034192013-04-24 18:51:19 +02008844 setl nofen
Bram Moolenaar446cb832008-06-24 21:56:24 +00008845
8846 " install ../ and shortdir
8847 if a:depth == ""
Luca Saccarolac363ca12024-12-19 20:16:18 +01008848 call setline(line("$")+1,'../')
Bram Moolenaar446cb832008-06-24 21:56:24 +00008849 endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +01008850 if a:dir =~ '^\a\{3,}://'
Luca Saccarolac363ca12024-12-19 20:16:18 +01008851 if a:dir == w:netrw_treetop
8852 let shortdir= a:dir
8853 else
8854 let shortdir= substitute(a:dir,'^.*/\([^/]\+\)/$','\1/','e')
8855 endif
8856 call setline(line("$")+1,a:depth.shortdir)
Bram Moolenaar446cb832008-06-24 21:56:24 +00008857 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01008858 let shortdir= substitute(a:dir,'^.*/','','e')
8859 call setline(line("$")+1,a:depth.shortdir.'/')
Bram Moolenaar446cb832008-06-24 21:56:24 +00008860 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008861 " append a / to dir if its missing one
8862 let dir= a:dir
Bram Moolenaar446cb832008-06-24 21:56:24 +00008863
8864 " display subtrees (if any)
Bram Moolenaar8d043172014-01-23 14:24:41 +01008865 let depth= s:treedepthstring.a:depth
Bram Moolenaar446cb832008-06-24 21:56:24 +00008866
Bram Moolenaar85850f32019-07-19 22:05:51 +02008867 " implement g:netrw_hide for tree listings (uses g:netrw_list_hide)
8868 if g:netrw_hide == 1
Luca Saccarolac363ca12024-12-19 20:16:18 +01008869 " hide given patterns
8870 let listhide= split(g:netrw_list_hide,',')
8871 for pat in listhide
8872 call filter(w:netrw_treedict[dir],'v:val !~ "'.escape(pat,'\\').'"')
8873 endfor
Bram Moolenaar85850f32019-07-19 22:05:51 +02008874
8875 elseif g:netrw_hide == 2
Luca Saccarolac363ca12024-12-19 20:16:18 +01008876 " show given patterns (only)
8877 let listhide= split(g:netrw_list_hide,',')
8878 let entries=[]
8879 for entry in w:netrw_treedict[dir]
8880 for pat in listhide
8881 if entry =~ pat
8882 call add(entries,entry)
8883 break
8884 endif
8885 endfor
Bram Moolenaar85850f32019-07-19 22:05:51 +02008886 endfor
Luca Saccarolac363ca12024-12-19 20:16:18 +01008887 let w:netrw_treedict[dir]= entries
Bram Moolenaar85850f32019-07-19 22:05:51 +02008888 endif
8889 if depth != ""
Luca Saccarolac363ca12024-12-19 20:16:18 +01008890 " always remove "." and ".." entries when there's depth
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 !~ "\\.$"')
8894 call filter(w:netrw_treedict[dir],'v:val !~ "\\./$"')
Bram Moolenaar85850f32019-07-19 22:05:51 +02008895 endif
8896
Bram Moolenaara0f849e2015-10-30 14:37:44 +01008897 for entry in w:netrw_treedict[dir]
Luca Saccarolac363ca12024-12-19 20:16:18 +01008898 if dir =~ '/$'
8899 let direntry= substitute(dir.entry,'[@/]$','','e')
8900 else
8901 let direntry= substitute(dir.'/'.entry,'[@/]$','','e')
8902 endif
8903 if entry =~ '/$' && has_key(w:netrw_treedict,direntry)
8904 NetrwKeepj call s:NetrwTreeDisplay(direntry,depth)
8905 elseif entry =~ '/$' && has_key(w:netrw_treedict,direntry.'/')
8906 NetrwKeepj call s:NetrwTreeDisplay(direntry.'/',depth)
8907 elseif entry =~ '@$' && has_key(w:netrw_treedict,direntry.'@')
8908 NetrwKeepj call s:NetrwTreeDisplay(direntry.'@',depth)
8909 else
8910 sil! NetrwKeepj call setline(line("$")+1,depth.entry)
8911 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008912 endfor
Bram Moolenaar446cb832008-06-24 21:56:24 +00008913endfun
8914
8915" ---------------------------------------------------------------------
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008916" s:NetrwRefreshTreeDict: updates the contents information for a tree (w:netrw_treedict) {{{2
8917fun! s:NetrwRefreshTreeDict(dir)
Bram Moolenaar85850f32019-07-19 22:05:51 +02008918 if !exists("w:netrw_treedict")
Luca Saccarolac363ca12024-12-19 20:16:18 +01008919 return
Bram Moolenaar85850f32019-07-19 22:05:51 +02008920 endif
8921
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008922 for entry in w:netrw_treedict[a:dir]
Luca Saccarolac363ca12024-12-19 20:16:18 +01008923 let direntry= substitute(a:dir.'/'.entry,'[@/]$','','e')
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008924
Luca Saccarolac363ca12024-12-19 20:16:18 +01008925 if entry =~ '/$' && has_key(w:netrw_treedict,direntry)
8926 NetrwKeepj call s:NetrwRefreshTreeDict(direntry)
8927 let filelist = s:NetrwLocalListingList(direntry,0)
8928 let w:netrw_treedict[direntry] = sort(filelist)
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008929
Luca Saccarolac363ca12024-12-19 20:16:18 +01008930 elseif entry =~ '/$' && has_key(w:netrw_treedict,direntry.'/')
8931 NetrwKeepj call s:NetrwRefreshTreeDict(direntry.'/')
8932 let filelist = s:NetrwLocalListingList(direntry.'/',0)
8933 let w:netrw_treedict[direntry] = sort(filelist)
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008934
Luca Saccarolac363ca12024-12-19 20:16:18 +01008935 elseif entry =~ '@$' && has_key(w:netrw_treedict,direntry.'@')
8936 NetrwKeepj call s:NetrwRefreshTreeDict(direntry.'/')
8937 let liststar = s:NetrwGlob(direntry.'/','*',1)
8938 let listdotstar= s:NetrwGlob(direntry.'/','.*',1)
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008939
Luca Saccarolac363ca12024-12-19 20:16:18 +01008940 else
8941 endif
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008942 endfor
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008943endfun
8944
8945" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +00008946" s:NetrwTreeListing: displays tree listing from treetop on down, using NetrwTreeDisplay() {{{2
Bram Moolenaara0f849e2015-10-30 14:37:44 +01008947" Called by s:PerformListing()
Bram Moolenaar446cb832008-06-24 21:56:24 +00008948fun! s:NetrwTreeListing(dirname)
Bram Moolenaare0fa3742016-02-20 15:47:01 +01008949 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
Bram Moolenaar446cb832008-06-24 21:56:24 +00008950
Luca Saccarolac363ca12024-12-19 20:16:18 +01008951 " update the treetop
8952 if !exists("w:netrw_treetop")
8953 let w:netrw_treetop= a:dirname
8954 let s:netrw_treetop= w:netrw_treetop
shane.xb.qianc673b802024-12-20 19:36:40 +01008955 " use \V in case the directory contains specials chars like '$' or '~'
Luca Saccarolac363ca12024-12-19 20:16:18 +01008956 elseif (w:netrw_treetop =~ ('^'.'\V'.a:dirname) && s:Strlen(a:dirname) < s:Strlen(w:netrw_treetop))
8957 \ || a:dirname !~ ('^'.'\V'.w:netrw_treetop)
8958 let w:netrw_treetop= a:dirname
8959 let s:netrw_treetop= w:netrw_treetop
8960 endif
8961 if exists("w:netrw_treetop")
8962 let s:netrw_treetop= w:netrw_treetop
8963 else
8964 let w:netrw_treetop= getcwd()
8965 let s:netrw_treetop= w:netrw_treetop
8966 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008967
Luca Saccarolac363ca12024-12-19 20:16:18 +01008968 if !exists("w:netrw_treedict")
8969 " insure that we have a treedict, albeit empty
8970 let w:netrw_treedict= {}
8971 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008972
Luca Saccarolac363ca12024-12-19 20:16:18 +01008973 " update the dictionary for the current directory
8974 exe "sil! NetrwKeepj keepp ".w:netrw_bannercnt.',$g@^\.\.\=/$@d _'
8975 let w:netrw_treedict[a:dirname]= getline(w:netrw_bannercnt,line("$"))
8976 exe "sil! NetrwKeepj ".w:netrw_bannercnt.",$d _"
Bram Moolenaar446cb832008-06-24 21:56:24 +00008977
Luca Saccarolac363ca12024-12-19 20:16:18 +01008978 " if past banner, record word
8979 if exists("w:netrw_bannercnt") && line(".") > w:netrw_bannercnt
8980 let fname= expand("<cword>")
8981 else
8982 let fname= ""
8983 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00008984
Luca Saccarolac363ca12024-12-19 20:16:18 +01008985 " display from treetop on down
8986 NetrwKeepj call s:NetrwTreeDisplay(w:netrw_treetop,"")
Bram Moolenaar8d043172014-01-23 14:24:41 +01008987
Luca Saccarolac363ca12024-12-19 20:16:18 +01008988 " remove any blank line remaining as line#1 (happens in treelisting mode with banner suppressed)
8989 while getline(1) =~ '^\s*$' && byte2line(1) > 0
8990 1d
8991 endwhile
Bram Moolenaar8d043172014-01-23 14:24:41 +01008992
Luca Saccarolac363ca12024-12-19 20:16:18 +01008993 exe "setl ".g:netrw_bufsettings
Bram Moolenaar446cb832008-06-24 21:56:24 +00008994
Luca Saccarolac363ca12024-12-19 20:16:18 +01008995 return
Bram Moolenaar446cb832008-06-24 21:56:24 +00008996 endif
8997endfun
8998
8999" ---------------------------------------------------------------------
Bram Moolenaar85850f32019-07-19 22:05:51 +02009000" s:NetrwTreePath: returns path to current file/directory in tree listing {{{2
Bram Moolenaara6878372014-03-22 21:02:50 +01009001" Normally, treetop is w:netrw_treetop, but a
9002" user of the function ( netrw#SetTreetop() )
9003" wipes that out prior to calling this function
9004fun! s:NetrwTreePath(treetop)
Luca Saccarolac363ca12024-12-19 20:16:18 +01009005 " call Dfunc("s:NetrwTreePath(treetop<".a:treetop.">) line#".line(".")."<".getline(".").">")
Bram Moolenaar85850f32019-07-19 22:05:51 +02009006 if line(".") < w:netrw_bannercnt + 2
Luca Saccarolac363ca12024-12-19 20:16:18 +01009007 let treedir= a:treetop
9008 if treedir !~ '/$'
9009 let treedir= treedir.'/'
9010 endif
9011 " call Dret("s:NetrwTreePath ".treedir." : line#".line(".")." ≤ ".(w:netrw_bannercnt+2))
9012 return treedir
Bram Moolenaar85850f32019-07-19 22:05:51 +02009013 endif
9014
Bram Moolenaare0fa3742016-02-20 15:47:01 +01009015 let svpos = winsaveview()
Luca Saccarolac363ca12024-12-19 20:16:18 +01009016 " call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +01009017 let depth = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e')
Luca Saccarolac363ca12024-12-19 20:16:18 +01009018 " call Decho("depth<".depth."> 1st subst",'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +01009019 let depth = substitute(depth,'^'.s:treedepthstring,'','')
Luca Saccarolac363ca12024-12-19 20:16:18 +01009020 " call Decho("depth<".depth."> 2nd subst (first depth removed)",'~'.expand("<slnum>"))
Bram Moolenaara0f849e2015-10-30 14:37:44 +01009021 let curline= getline('.')
Luca Saccarolac363ca12024-12-19 20:16:18 +01009022 " call Decho("curline<".curline.'>','~'.expand("<slnum>"))
Bram Moolenaara0f849e2015-10-30 14:37:44 +01009023 if curline =~ '/$'
Luca Saccarolac363ca12024-12-19 20:16:18 +01009024 " call Decho("extract tree directory from current line",'~'.expand("<slnum>"))
9025 let treedir= substitute(curline,'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e')
shane.xb.qianc673b802024-12-20 19:36:40 +01009026 " call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
Bram Moolenaara0f849e2015-10-30 14:37:44 +01009027 elseif curline =~ '@\s\+-->'
Luca Saccarolac363ca12024-12-19 20:16:18 +01009028 " call Decho("extract tree directory using symbolic link",'~'.expand("<slnum>"))
9029 let treedir= substitute(curline,'^\%('.s:treedepthstring.'\)*\([^'.s:treedepthstring.'].\{-}\)$','\1','e')
9030 let treedir= substitute(treedir,'@\s\+-->.*$','','e')
shane.xb.qianc673b802024-12-20 19:36:40 +01009031 " call Decho("treedir<".treedir.">",'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +01009032 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01009033 " call Decho("do not extract tree directory from current line and set treedir to empty",'~'.expand("<slnum>"))
9034 let treedir= ""
Bram Moolenaara6878372014-03-22 21:02:50 +01009035 endif
9036 " construct treedir by searching backwards at correct depth
Luca Saccarolac363ca12024-12-19 20:16:18 +01009037 " call Decho("construct treedir by searching backwards for correct depth",'~'.expand("<slnum>"))
9038 " call Decho("initial treedir<".treedir."> depth<".depth.">",'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +01009039 while depth != "" && search('^'.depth.'[^'.s:treedepthstring.'].\{-}/$','bW')
Luca Saccarolac363ca12024-12-19 20:16:18 +01009040 let dirname= substitute(getline('.'),'^\('.s:treedepthstring.'\)*','','e')
9041 let treedir= dirname.treedir
9042 let depth = substitute(depth,'^'.s:treedepthstring,'','')
9043 " call Decho("constructing treedir<".treedir.">: dirname<".dirname."> while depth<".depth.">",'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +01009044 endwhile
Luca Saccarolac363ca12024-12-19 20:16:18 +01009045 " call Decho("treedir#1<".treedir.">",'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +01009046 if a:treetop =~ '/$'
Luca Saccarolac363ca12024-12-19 20:16:18 +01009047 let treedir= a:treetop.treedir
Bram Moolenaara6878372014-03-22 21:02:50 +01009048 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01009049 let treedir= a:treetop.'/'.treedir
Bram Moolenaara6878372014-03-22 21:02:50 +01009050 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01009051 " call Decho("treedir#2<".treedir.">",'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +01009052 let treedir= substitute(treedir,'//$','/','')
Luca Saccarolac363ca12024-12-19 20:16:18 +01009053 " call Decho("treedir#3<".treedir.">",'~'.expand("<slnum>"))
9054 " call Decho("restoring posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))"
Bram Moolenaare0fa3742016-02-20 15:47:01 +01009055 call winrestview(svpos)
Luca Saccarolac363ca12024-12-19 20:16:18 +01009056 " call Dret("s:NetrwTreePath <".treedir.">")
Bram Moolenaara6878372014-03-22 21:02:50 +01009057 return treedir
9058endfun
9059
9060" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +00009061" s:NetrwWideListing: {{{2
9062fun! s:NetrwWideListing()
9063
9064 if w:netrw_liststyle == s:WIDELIST
Luca Saccarolac363ca12024-12-19 20:16:18 +01009065 " call Dfunc("NetrwWideListing() w:netrw_liststyle=".w:netrw_liststyle.' fo='.&fo.' l:fo='.&l:fo)
9066 " look for longest filename (cpf=characters per filename)
9067 " cpf: characters per filename
9068 " fpl: filenames per line
9069 " fpc: filenames per column
9070 setl ma noro
9071 let dict={}
9072 " save the unnamed register and register 0-9 and a
9073 let dict.a=[getreg('a'), getregtype('a')]
9074 for i in range(0, 9)
9075 let dict[i] = [getreg(i), getregtype(i)]
9076 endfor
9077 let dict.unnamed = [getreg(''), getregtype('')]
9078 " call Decho("setl ma noro",'~'.expand("<slnum>"))
9079 let b:netrw_cpf= 0
9080 if line("$") >= w:netrw_bannercnt
9081 " determine the maximum filename size; use that to set cpf
9082 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g/^./if virtcol("$") > b:netrw_cpf|let b:netrw_cpf= virtcol("$")|endif'
shane.xb.qianc673b802024-12-20 19:36:40 +01009083 NetrwKeepj call histdel("/",-1)
Bram Moolenaar446cb832008-06-24 21:56:24 +00009084 else
shane.xb.qianc673b802024-12-20 19:36:40 +01009085 " restore stored registers
9086 call s:RestoreRegister(dict)
9087 " call Dret("NetrwWideListing")
9088 return
Bram Moolenaar446cb832008-06-24 21:56:24 +00009089 endif
shane.xb.qianc673b802024-12-20 19:36:40 +01009090 " allow for two spaces to separate columns
9091 let b:netrw_cpf= b:netrw_cpf + 2
9092 " call Decho("b:netrw_cpf=max_filename_length+2=".b:netrw_cpf,'~'.expand("<slnum>"))
9093
9094 " determine qty files per line (fpl)
9095 let w:netrw_fpl= winwidth(0)/b:netrw_cpf
9096 if w:netrw_fpl <= 0
9097 let w:netrw_fpl= 1
9098 endif
9099 " call Decho("fpl= [winwidth=".winwidth(0)."]/[b:netrw_cpf=".b:netrw_cpf.']='.w:netrw_fpl,'~'.expand("<slnum>"))
9100
9101 " make wide display
9102 " fpc: files per column of wide listing
9103 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/^.*$/\=escape(printf("%-'.b:netrw_cpf.'S",submatch(0)),"\\")/'
9104 NetrwKeepj call histdel("/",-1)
9105 let fpc = (line("$") - w:netrw_bannercnt + w:netrw_fpl)/w:netrw_fpl
9106 let newcolstart = w:netrw_bannercnt + fpc
9107 let newcolend = newcolstart + fpc - 1
9108 " call Decho("bannercnt=".w:netrw_bannercnt." fpl=".w:netrw_fpl." fpc=".fpc." newcol[".newcolstart.",".newcolend."]",'~'.expand("<slnum>"))
9109 if has("clipboard") && g:netrw_clipboard
9110 " call Decho("(s:NetrwWideListing) save @* and @+",'~'.expand("<slnum>"))
9111 sil! let keepregstar = @*
9112 sil! let keepregplus = @+
9113 endif
9114 while line("$") >= newcolstart
9115 if newcolend > line("$") | let newcolend= line("$") | endif
9116 let newcolqty= newcolend - newcolstart
9117 exe newcolstart
9118 " COMBAK: both of the visual-mode using lines below are problematic vis-a-vis @*
9119 if newcolqty == 0
9120 exe "sil! NetrwKeepj norm! 0\<c-v>$h\"ax".w:netrw_bannercnt."G$\"ap"
9121 else
9122 exe "sil! NetrwKeepj norm! 0\<c-v>".newcolqty.'j$h"ax'.w:netrw_bannercnt.'G$"ap'
9123 endif
9124 exe "sil! NetrwKeepj ".newcolstart.','.newcolend.'d _'
9125 exe 'sil! NetrwKeepj '.w:netrw_bannercnt
9126 endwhile
9127 if has("clipboard")
9128 " call Decho("(s:NetrwWideListing) restore @* and @+",'~'.expand("<slnum>"))
9129 if @* != keepregstar | sil! let @* = keepregstar | endif
9130 if @+ != keepregplus | sil! let @+ = keepregplus | endif
9131 endif
9132 exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$s/\s\+$//e'
9133 NetrwKeepj call histdel("/",-1)
9134 exe 'nno <buffer> <silent> w :call search(''^.\\|\s\s\zs\S'',''W'')'."\<cr>"
9135 exe 'nno <buffer> <silent> b :call search(''^.\\|\s\s\zs\S'',''bW'')'."\<cr>"
9136 " call Decho("NetrwWideListing) setl noma nomod ro",'~'.expand("<slnum>"))
9137 exe "setl ".g:netrw_bufsettings
9138 call s:RestoreRegister(dict)
9139 " call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
9140 " call Dret("NetrwWideListing")
9141 return
9142 else
9143 if hasmapto("w","n")
9144 sil! nunmap <buffer> w
9145 endif
9146 if hasmapto("b","n")
9147 sil! nunmap <buffer> b
9148 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009149 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009150endfun
9151
9152" ---------------------------------------------------------------------
9153" s:PerformListing: {{{2
9154fun! s:PerformListing(islocal)
Luca Saccarolac363ca12024-12-19 20:16:18 +01009155 " call Dfunc("s:PerformListing(islocal=".a:islocal.")")
9156 " call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9157 " 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 +02009158 sil! NetrwKeepj %d _
Luca Saccarolac363ca12024-12-19 20:16:18 +01009159 " call DechoBuf(bufnr("%"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00009160
Bram Moolenaar15146672011-10-20 22:22:38 +02009161 " set up syntax highlighting {{{3
Luca Saccarolac363ca12024-12-19 20:16:18 +01009162 " call Decho("--set up syntax highlighting (ie. setl ft=netrw)",'~'.expand("<slnum>"))
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01009163 sil! setl ft=netrw
Bram Moolenaar15146672011-10-20 22:22:38 +02009164
Bram Moolenaar85850f32019-07-19 22:05:51 +02009165 NetrwKeepj call s:NetrwOptionsSafe(a:islocal)
Bram Moolenaara6878372014-03-22 21:02:50 +01009166 setl noro ma
Luca Saccarolac363ca12024-12-19 20:16:18 +01009167 " call Decho("setl noro ma bh=".&bh,'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00009168
Luca Saccarolac363ca12024-12-19 20:16:18 +01009169 " if exists("g:netrw_silent") && g:netrw_silent == 0 && &ch >= 1 " Decho
9170 " call Decho("Processing your browsing request...",'~'.expand("<slnum>"))
9171 " endif " Decho
Bram Moolenaar446cb832008-06-24 21:56:24 +00009172
Luca Saccarolac363ca12024-12-19 20:16:18 +01009173 " call Decho('w:netrw_liststyle='.(exists("w:netrw_liststyle")? w:netrw_liststyle : 'n/a'),'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00009174 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treedict")
Luca Saccarolac363ca12024-12-19 20:16:18 +01009175 " force a refresh for tree listings
9176 " call Decho("force refresh for treelisting: clear buffer<".expand("%")."> with :%d",'~'.expand("<slnum>"))
9177 sil! NetrwKeepj %d _
Bram Moolenaar446cb832008-06-24 21:56:24 +00009178 endif
9179
9180 " save current directory on directory history list
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01009181 NetrwKeepj call s:NetrwBookHistHandler(3,b:netrw_curdir)
Bram Moolenaar446cb832008-06-24 21:56:24 +00009182
9183 " Set up the banner {{{3
Bram Moolenaar5c736222010-01-06 20:54:52 +01009184 if g:netrw_banner
Luca Saccarolac363ca12024-12-19 20:16:18 +01009185 " call Decho("--set up banner",'~'.expand("<slnum>"))
9186 NetrwKeepj call setline(1,'" ============================================================================')
9187 if exists("g:netrw_pchk")
9188 " this undocumented option allows pchk to run with different versions of netrw without causing spurious
9189 " failure detections.
9190 NetrwKeepj call setline(2,'" Netrw Directory Listing')
9191 else
9192 NetrwKeepj call setline(2,'" Netrw Directory Listing (netrw '.g:loaded_netrw.')')
9193 endif
9194 if exists("g:netrw_pchk")
9195 let curdir= substitute(b:netrw_curdir,expand("$HOME"),'~','')
9196 else
9197 let curdir= b:netrw_curdir
9198 endif
9199 if exists("g:netrw_bannerbackslash") && g:netrw_bannerbackslash
9200 NetrwKeepj call setline(3,'" '.substitute(curdir,'/','\\','g'))
9201 else
9202 NetrwKeepj call setline(3,'" '.curdir)
9203 endif
9204 let w:netrw_bannercnt= 3
9205 NetrwKeepj exe "sil! NetrwKeepj ".w:netrw_bannercnt
Bram Moolenaar5c736222010-01-06 20:54:52 +01009206 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01009207 " call Decho("--no banner",'~'.expand("<slnum>"))
9208 NetrwKeepj 1
9209 let w:netrw_bannercnt= 1
Bram Moolenaar5c736222010-01-06 20:54:52 +01009210 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01009211 " call Decho("w:netrw_bannercnt=".w:netrw_bannercnt." win#".winnr(),'~'.expand("<slnum>"))
9212 " 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 +00009213
Bram Moolenaar85850f32019-07-19 22:05:51 +02009214 " construct sortby string: [name|time|size|exten] [reversed]
Bram Moolenaar446cb832008-06-24 21:56:24 +00009215 let sortby= g:netrw_sort_by
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +02009216 if g:netrw_sort_direction =~# "^r"
Luca Saccarolac363ca12024-12-19 20:16:18 +01009217 let sortby= sortby." reversed"
Bram Moolenaar446cb832008-06-24 21:56:24 +00009218 endif
9219
9220 " Sorted by... {{{3
Bram Moolenaar5c736222010-01-06 20:54:52 +01009221 if g:netrw_banner
Luca Saccarolac363ca12024-12-19 20:16:18 +01009222 " call Decho("--handle specified sorting: g:netrw_sort_by<".g:netrw_sort_by.">",'~'.expand("<slnum>"))
9223 if g:netrw_sort_by =~# "^n"
9224 " call Decho("directories will be sorted by name",'~'.expand("<slnum>"))
9225 " sorted by name (also includes the sorting sequence in the banner)
9226 NetrwKeepj put ='\" Sorted by '.sortby
9227 NetrwKeepj put ='\" Sort sequence: '.g:netrw_sort_sequence
9228 let w:netrw_bannercnt= w:netrw_bannercnt + 2
9229 else
9230 " call Decho("directories will be sorted by size or time",'~'.expand("<slnum>"))
9231 " sorted by time, size, exten
9232 NetrwKeepj put ='\" Sorted by '.sortby
9233 let w:netrw_bannercnt= w:netrw_bannercnt + 1
9234 endif
9235 exe "sil! NetrwKeepj ".w:netrw_bannercnt
9236 " else " Decho
9237 " 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 +00009238 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009239
Bram Moolenaar85850f32019-07-19 22:05:51 +02009240 " show copy/move target, if any {{{3
Bram Moolenaar5c736222010-01-06 20:54:52 +01009241 if g:netrw_banner
Luca Saccarolac363ca12024-12-19 20:16:18 +01009242 if exists("s:netrwmftgt") && exists("s:netrwmftgt_islocal")
9243 " call Decho("--show copy/move target<".s:netrwmftgt.">",'~'.expand("<slnum>"))
9244 NetrwKeepj put =''
9245 if s:netrwmftgt_islocal
9246 sil! NetrwKeepj call setline(line("."),'" Copy/Move Tgt: '.s:netrwmftgt.' (local)')
9247 else
9248 sil! NetrwKeepj call setline(line("."),'" Copy/Move Tgt: '.s:netrwmftgt.' (remote)')
9249 endif
9250 let w:netrw_bannercnt= w:netrw_bannercnt + 1
Bram Moolenaar5c736222010-01-06 20:54:52 +01009251 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01009252 " call Decho("s:netrwmftgt does not exist, don't make Copy/Move Tgt",'~'.expand("<slnum>"))
Bram Moolenaar5c736222010-01-06 20:54:52 +01009253 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01009254 exe "sil! NetrwKeepj ".w:netrw_bannercnt
Bram Moolenaar446cb832008-06-24 21:56:24 +00009255 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009256
9257 " Hiding... -or- Showing... {{{3
Bram Moolenaar5c736222010-01-06 20:54:52 +01009258 if g:netrw_banner
Luca Saccarolac363ca12024-12-19 20:16:18 +01009259 " call Decho("--handle hiding/showing in banner (g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">)",'~'.expand("<slnum>"))
9260 if g:netrw_list_hide != "" && g:netrw_hide
9261 if g:netrw_hide == 1
9262 NetrwKeepj put ='\" Hiding: '.g:netrw_list_hide
9263 else
9264 NetrwKeepj put ='\" Showing: '.g:netrw_list_hide
9265 endif
9266 let w:netrw_bannercnt= w:netrw_bannercnt + 1
Bram Moolenaar5c736222010-01-06 20:54:52 +01009267 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01009268 exe "NetrwKeepj ".w:netrw_bannercnt
Bram Moolenaara6878372014-03-22 21:02:50 +01009269
Luca Saccarolac363ca12024-12-19 20:16:18 +01009270 " call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
9271 let quickhelp = g:netrw_quickhelp%len(s:QuickHelp)
9272 " call Decho("quickhelp =".quickhelp,'~'.expand("<slnum>"))
9273 NetrwKeepj put ='\" Quick Help: <F1>:help '.s:QuickHelp[quickhelp]
9274 " call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
9275 NetrwKeepj put ='\" =============================================================================='
9276 let w:netrw_bannercnt= w:netrw_bannercnt + 2
9277 " else " Decho
9278 " 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 +00009279 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009280
9281 " bannercnt should index the line just after the banner
Bram Moolenaar5c736222010-01-06 20:54:52 +01009282 if g:netrw_banner
Luca Saccarolac363ca12024-12-19 20:16:18 +01009283 let w:netrw_bannercnt= w:netrw_bannercnt + 1
9284 exe "sil! NetrwKeepj ".w:netrw_bannercnt
9285 " call Decho("--w:netrw_bannercnt=".w:netrw_bannercnt." (should index line just after banner) line($)=".line("$"),'~'.expand("<slnum>"))
9286 " else " Decho
9287 " 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 +01009288 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009289
Bram Moolenaar446cb832008-06-24 21:56:24 +00009290 " get list of files
Luca Saccarolac363ca12024-12-19 20:16:18 +01009291 " call Decho("--Get list of files - islocal=".a:islocal,'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00009292 if a:islocal
Luca Saccarolac363ca12024-12-19 20:16:18 +01009293 NetrwKeepj call s:LocalListing()
Bram Moolenaar446cb832008-06-24 21:56:24 +00009294 else " remote
Luca Saccarolac363ca12024-12-19 20:16:18 +01009295 NetrwKeepj let badresult= s:NetrwRemoteListing()
9296 if badresult
9297 " call Decho("w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a')." win#".winnr()." buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
9298 " call Dret("s:PerformListing : error detected by NetrwRemoteListing")
9299 return
9300 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009301 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009302
9303 " manipulate the directory listing (hide, sort) {{{3
Bram Moolenaar5b435d62012-04-05 17:33:26 +02009304 if !exists("w:netrw_bannercnt")
Luca Saccarolac363ca12024-12-19 20:16:18 +01009305 let w:netrw_bannercnt= 0
Bram Moolenaar5b435d62012-04-05 17:33:26 +02009306 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01009307 " call Decho("--manipulate directory listing (hide, sort)",'~'.expand("<slnum>"))
9308 " call Decho("g:netrw_banner=".g:netrw_banner." w:netrw_bannercnt=".w:netrw_bannercnt." (banner complete)",'~'.expand("<slnum>"))
9309 " 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 +01009310
Bram Moolenaar5c736222010-01-06 20:54:52 +01009311 if !g:netrw_banner || line("$") >= w:netrw_bannercnt
Luca Saccarolac363ca12024-12-19 20:16:18 +01009312 " call Decho("manipulate directory listing (support hide)",'~'.expand("<slnum>"))
9313 " call Decho("g:netrw_hide=".g:netrw_hide." g:netrw_list_hide<".g:netrw_list_hide.">",'~'.expand("<slnum>"))
9314 if g:netrw_hide && g:netrw_list_hide != ""
9315 NetrwKeepj call s:NetrwListHide()
Bram Moolenaar446cb832008-06-24 21:56:24 +00009316 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01009317 if !g:netrw_banner || line("$") >= w:netrw_bannercnt
9318 " call Decho("manipulate directory listing (sort) : g:netrw_sort_by<".g:netrw_sort_by.">",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00009319
Luca Saccarolac363ca12024-12-19 20:16:18 +01009320 if g:netrw_sort_by =~# "^n"
9321 " sort by name
9322 " call Decho("sort by name",'~'.expand("<slnum>"))
9323 NetrwKeepj call s:NetrwSetSort()
9324
9325 if !g:netrw_banner || w:netrw_bannercnt < line("$")
9326 " call Decho("g:netrw_sort_direction=".g:netrw_sort_direction." (bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
9327 if g:netrw_sort_direction =~# 'n'
9328 " name: sort by name of file
9329 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
9330 else
9331 " reverse direction sorting
9332 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
9333 endif
9334 endif
9335
9336 " remove priority pattern prefix
9337 " call Decho("remove priority pattern prefix",'~'.expand("<slnum>"))
9338 exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\d\{3}'.g:netrw_sepchr.'//e'
9339 NetrwKeepj call histdel("/",-1)
9340
9341 elseif g:netrw_sort_by =~# "^ext"
9342 " exten: sort by extension
9343 " The histdel(...,-1) calls remove the last search from the search history
9344 " call Decho("sort by extension",'~'.expand("<slnum>"))
9345 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$g+/+s/^/001'.g:netrw_sepchr.'/'
9346 NetrwKeepj call histdel("/",-1)
9347 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$v+[./]+s/^/002'.g:netrw_sepchr.'/'
9348 NetrwKeepj call histdel("/",-1)
9349 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$v+['.g:netrw_sepchr.'/]+s/^\(.*\.\)\(.\{-\}\)$/\2'.g:netrw_sepchr.'&/e'
9350 NetrwKeepj call histdel("/",-1)
9351 if !g:netrw_banner || w:netrw_bannercnt < line("$")
9352 " call Decho("g:netrw_sort_direction=".g:netrw_sort_direction." (bannercnt=".w:netrw_bannercnt.")",'~'.expand("<slnum>"))
9353 if g:netrw_sort_direction =~# 'n'
9354 " normal direction sorting
9355 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
9356 else
9357 " reverse direction sorting
9358 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
9359 endif
9360 endif
9361 exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^.\{-}'.g:netrw_sepchr.'//e'
9362 NetrwKeepj call histdel("/",-1)
9363
9364 elseif a:islocal
9365 if !g:netrw_banner || w:netrw_bannercnt < line("$")
9366 " call Decho("g:netrw_sort_direction=".g:netrw_sort_direction,'~'.expand("<slnum>"))
9367 if g:netrw_sort_direction =~# 'n'
9368 " call Decho('exe sil NetrwKeepj '.w:netrw_bannercnt.',$sort','~'.expand("<slnum>"))
9369 exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$sort'.' '.g:netrw_sort_options
9370 else
9371 " call Decho('exe sil NetrwKeepj '.w:netrw_bannercnt.',$sort!','~'.expand("<slnum>"))
9372 exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$sort!'.' '.g:netrw_sort_options
9373 endif
9374 " call Decho("remove leading digits/ (sorting) information from listing",'~'.expand("<slnum>"))
9375 exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\d\{-}\///e'
9376 NetrwKeepj call histdel("/",-1)
9377 endif
9378 endif
9379
9380 elseif g:netrw_sort_direction =~# 'r'
9381 " call Decho('(s:PerformListing) reverse the sorted listing','~'.expand("<slnum>"))
9382 if !g:netrw_banner || w:netrw_bannercnt < line('$')
9383 exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$g/^/m '.w:netrw_bannercnt
9384 call histdel("/",-1)
9385 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +01009386 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009387 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01009388 " 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 +00009389
9390 " convert to wide/tree listing {{{3
Luca Saccarolac363ca12024-12-19 20:16:18 +01009391 " call Decho("--modify display if wide/tree listing style",'~'.expand("<slnum>"))
9392 " 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 +01009393 NetrwKeepj call s:NetrwWideListing()
Luca Saccarolac363ca12024-12-19 20:16:18 +01009394 " 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 +01009395 NetrwKeepj call s:NetrwTreeListing(b:netrw_curdir)
Luca Saccarolac363ca12024-12-19 20:16:18 +01009396 " 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 +00009397
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01009398 " resolve symbolic links if local and (thin or tree)
Bram Moolenaare0fa3742016-02-20 15:47:01 +01009399 if a:islocal && (w:netrw_liststyle == s:THINLIST || (exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST))
Luca Saccarolac363ca12024-12-19 20:16:18 +01009400 " call Decho("--resolve symbolic links if local and thin|tree",'~'.expand("<slnum>"))
9401 sil! keepp g/@$/call s:ShowLink()
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01009402 endif
9403
Bram Moolenaara0f849e2015-10-30 14:37:44 +01009404 if exists("w:netrw_bannercnt") && (line("$") >= w:netrw_bannercnt || !g:netrw_banner)
Luca Saccarolac363ca12024-12-19 20:16:18 +01009405 " place cursor on the top-left corner of the file listing
9406 " call Decho("--place cursor on top-left corner of file listing",'~'.expand("<slnum>"))
9407 exe 'sil! '.w:netrw_bannercnt
9408 sil! NetrwKeepj norm! 0
shane.xb.qianc673b802024-12-20 19:36:40 +01009409 " 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 +01009410 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01009411 " call Decho("--did NOT place cursor on top-left corner",'~'.expand("<slnum>"))
9412 " call Decho(" w:netrw_bannercnt=".(exists("w:netrw_bannercnt")? w:netrw_bannercnt : 'n/a'),'~'.expand("<slnum>"))
9413 " call Decho(" line($)=".line("$"),'~'.expand("<slnum>"))
9414 " call Decho(" g:netrw_banner=".(exists("g:netrw_banner")? g:netrw_banner : 'n/a'),'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00009415 endif
9416
9417 " record previous current directory
9418 let w:netrw_prvdir= b:netrw_curdir
Luca Saccarolac363ca12024-12-19 20:16:18 +01009419 " call Decho("--record netrw_prvdir<".w:netrw_prvdir.">",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00009420
9421 " save certain window-oriented variables into buffer-oriented variables {{{3
Luca Saccarolac363ca12024-12-19 20:16:18 +01009422 " call Decho("--save some window-oriented variables into buffer oriented variables",'~'.expand("<slnum>"))
9423 " 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 +01009424 NetrwKeepj call s:SetBufWinVars()
Luca Saccarolac363ca12024-12-19 20:16:18 +01009425 " 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 +02009426 NetrwKeepj call s:NetrwOptionsRestore("w:")
Luca Saccarolac363ca12024-12-19 20:16:18 +01009427 " 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 +00009428
9429 " set display to netrw display settings
Luca Saccarolac363ca12024-12-19 20:16:18 +01009430 " call Decho("--set display to netrw display settings (".g:netrw_bufsettings.")",'~'.expand("<slnum>"))
Bram Moolenaar5ac3b1a2010-07-27 22:50:36 +02009431 exe "setl ".g:netrw_bufsettings
Luca Saccarolac363ca12024-12-19 20:16:18 +01009432 " 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 +01009433 if g:netrw_liststyle == s:LONGLIST
Luca Saccarolac363ca12024-12-19 20:16:18 +01009434 " call Decho("exe setl ts=".(g:netrw_maxfilenamelen+1),'~'.expand("<slnum>"))
9435 exe "setl ts=".(g:netrw_maxfilenamelen+1)
Bram Moolenaar97d62492012-11-15 21:28:22 +01009436 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01009437 " call Decho("PerformListing buffer:",'~'.expand("<slnum>"))
9438 " call DechoBuf(bufnr("%"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00009439
Bram Moolenaar8d043172014-01-23 14:24:41 +01009440 if exists("s:treecurpos")
Luca Saccarolac363ca12024-12-19 20:16:18 +01009441 " call Decho("s:treecurpos exists; restore posn",'~'.expand("<slnum>"))
9442 " 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>"))
9443 " call Decho("restoring posn to s:treecurpos<".string(s:treecurpos).">",'~'.expand("<slnum>"))
9444 NetrwKeepj call winrestview(s:treecurpos)
9445 unlet s:treecurpos
Bram Moolenaar446cb832008-06-24 21:56:24 +00009446 endif
9447
Luca Saccarolac363ca12024-12-19 20:16:18 +01009448 " 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>"))
9449 " call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol()." line($)=".line("$"),'~'.expand("<slnum>"))
9450 " call Dret("s:PerformListing : curpos<".string(getpos(".")).">")
Bram Moolenaar446cb832008-06-24 21:56:24 +00009451endfun
9452
9453" ---------------------------------------------------------------------
9454" s:SetupNetrwStatusLine: {{{2
Bram Moolenaar9964e462007-05-05 17:54:07 +00009455fun! s:SetupNetrwStatusLine(statline)
Luca Saccarolac363ca12024-12-19 20:16:18 +01009456 " call Dfunc("SetupNetrwStatusLine(statline<".a:statline.">)")
Bram Moolenaar9964e462007-05-05 17:54:07 +00009457
9458 if !exists("s:netrw_setup_statline")
Luca Saccarolac363ca12024-12-19 20:16:18 +01009459 let s:netrw_setup_statline= 1
9460 " call Decho("do first-time status line setup",'~'.expand("<slnum>"))
Bram Moolenaar9964e462007-05-05 17:54:07 +00009461
Luca Saccarolac363ca12024-12-19 20:16:18 +01009462 if !exists("s:netrw_users_stl")
9463 let s:netrw_users_stl= &stl
Bram Moolenaar9964e462007-05-05 17:54:07 +00009464 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01009465 if !exists("s:netrw_users_ls")
9466 let s:netrw_users_ls= &laststatus
9467 endif
9468
9469 " set up User9 highlighting as needed
9470 let dict={}
9471 let dict.a=[getreg('a'), getregtype('a')]
9472 redir @a
9473 try
9474 hi User9
9475 catch /^Vim\%((\a\{3,})\)\=:E411/
9476 if &bg == "dark"
9477 hi User9 ctermfg=yellow ctermbg=blue guifg=yellow guibg=blue
9478 else
9479 hi User9 ctermbg=yellow ctermfg=blue guibg=yellow guifg=blue
9480 endif
9481 endtry
9482 redir END
9483 call s:RestoreRegister(dict)
Bram Moolenaar9964e462007-05-05 17:54:07 +00009484 endif
9485
9486 " set up status line (may use User9 highlighting)
9487 " insure that windows have a statusline
9488 " make sure statusline is displayed
K.Takataa262d3f2024-01-25 04:10:19 +09009489 let &l:stl=a:statline
Bram Moolenaarff034192013-04-24 18:51:19 +02009490 setl laststatus=2
Luca Saccarolac363ca12024-12-19 20:16:18 +01009491 " call Decho("stl=".&stl,'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00009492 redraw
Bram Moolenaar9964e462007-05-05 17:54:07 +00009493
Luca Saccarolac363ca12024-12-19 20:16:18 +01009494 " call Dret("SetupNetrwStatusLine : stl=".&stl)
Bram Moolenaar9964e462007-05-05 17:54:07 +00009495endfun
9496
Bram Moolenaar85850f32019-07-19 22:05:51 +02009497" =========================================
9498" Remote Directory Browsing Support: {{{1
9499" =========================================
Bram Moolenaar9964e462007-05-05 17:54:07 +00009500
9501" ---------------------------------------------------------------------
Bram Moolenaara6878372014-03-22 21:02:50 +01009502" s:NetrwRemoteFtpCmd: unfortunately, not all ftp servers honor options for ls {{{2
9503" This function assumes that a long listing will be received. Size, time,
9504" and reverse sorts will be requested of the server but not otherwise
9505" enforced here.
9506fun! s:NetrwRemoteFtpCmd(path,listcmd)
Luca Saccarolac363ca12024-12-19 20:16:18 +01009507 " 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 : "???")))
9508 " call Decho("line($)=".line("$")." win#".winnr()." w:netrw_bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +01009509 " sanity check: {{{3
9510 if !exists("w:netrw_method")
Luca Saccarolac363ca12024-12-19 20:16:18 +01009511 if exists("b:netrw_method")
9512 let w:netrw_method= b:netrw_method
9513 else
9514 call netrw#ErrorMsg(2,"(s:NetrwRemoteFtpCmd) internal netrw error",93)
9515 " call Dret("NetrwRemoteFtpCmd")
9516 return
9517 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01009518 endif
9519
Luca Saccarolac363ca12024-12-19 20:16:18 +01009520 " WinXX ftp uses unix style input, so set ff to unix " {{{3
Bram Moolenaara6878372014-03-22 21:02:50 +01009521 let ffkeep= &ff
9522 setl ma ff=unix noro
Luca Saccarolac363ca12024-12-19 20:16:18 +01009523 " call Decho("setl ma ff=unix noro",'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +01009524
Luca Saccarolac363ca12024-12-19 20:16:18 +01009525 " clear off any older non-banner lines " {{{3
Bram Moolenaara6878372014-03-22 21:02:50 +01009526 " note that w:netrw_bannercnt indexes the line after the banner
Luca Saccarolac363ca12024-12-19 20:16:18 +01009527 " call Decho('exe sil! NetrwKeepj '.w:netrw_bannercnt.",$d _ (clear off old non-banner lines)",'~'.expand("<slnum>"))
Bram Moolenaare0fa3742016-02-20 15:47:01 +01009528 exe "sil! NetrwKeepj ".w:netrw_bannercnt.",$d _"
Bram Moolenaara6878372014-03-22 21:02:50 +01009529
9530 ".........................................
Luca Saccarolac363ca12024-12-19 20:16:18 +01009531 if w:netrw_method == 2 || w:netrw_method == 5 " {{{3
9532 " ftp + <.netrc>: Method #2
9533 if a:path != ""
9534 NetrwKeepj put ='cd \"'.a:path.'\"'
9535 endif
9536 if exists("g:netrw_ftpextracmd")
9537 NetrwKeepj put =g:netrw_ftpextracmd
9538 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
9539 endif
9540 NetrwKeepj call setline(line("$")+1,a:listcmd)
9541 " exe "NetrwKeepj ".w:netrw_bannercnt.',$g/^./call Decho("ftp#".line(".").": ".getline("."),''~''.expand("<slnum>"))'
9542 if exists("g:netrw_port") && g:netrw_port != ""
9543 " 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>"))
9544 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)
9545 else
9546 " call Decho("exe ".s:netrw_silentxfer.w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1),'~'.expand("<slnum>"))
9547 exe s:netrw_silentxfer." NetrwKeepj ".w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." -i ".s:ShellEscape(g:netrw_machine,1)
9548 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01009549
Luca Saccarolac363ca12024-12-19 20:16:18 +01009550 ".........................................
9551 elseif w:netrw_method == 3 " {{{3
9552 " ftp + machine,id,passwd,filename: Method #3
Bram Moolenaara6878372014-03-22 21:02:50 +01009553 setl ff=unix
9554 if exists("g:netrw_port") && g:netrw_port != ""
Luca Saccarolac363ca12024-12-19 20:16:18 +01009555 NetrwKeepj put ='open '.g:netrw_machine.' '.g:netrw_port
Bram Moolenaara6878372014-03-22 21:02:50 +01009556 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01009557 NetrwKeepj put ='open '.g:netrw_machine
Bram Moolenaara6878372014-03-22 21:02:50 +01009558 endif
9559
9560 " handle userid and password
9561 let host= substitute(g:netrw_machine,'\..*$','','')
Luca Saccarolac363ca12024-12-19 20:16:18 +01009562 " call Decho("host<".host.">",'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +01009563 if exists("s:netrw_hup") && exists("s:netrw_hup[host]")
Luca Saccarolac363ca12024-12-19 20:16:18 +01009564 call NetUserPass("ftp:".host)
Bram Moolenaara6878372014-03-22 21:02:50 +01009565 endif
9566 if exists("g:netrw_uid") && g:netrw_uid != ""
Luca Saccarolac363ca12024-12-19 20:16:18 +01009567 if exists("g:netrw_ftp") && g:netrw_ftp == 1
9568 NetrwKeepj put =g:netrw_uid
9569 if exists("s:netrw_passwd") && s:netrw_passwd != ""
9570 NetrwKeepj put ='\"'.s:netrw_passwd.'\"'
9571 endif
9572 elseif exists("s:netrw_passwd")
9573 NetrwKeepj put ='user \"'.g:netrw_uid.'\" \"'.s:netrw_passwd.'\"'
Bram Moolenaara6878372014-03-22 21:02:50 +01009574 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01009575 endif
9576
Luca Saccarolac363ca12024-12-19 20:16:18 +01009577 if a:path != ""
9578 NetrwKeepj put ='cd \"'.a:path.'\"'
9579 endif
9580 if exists("g:netrw_ftpextracmd")
9581 NetrwKeepj put =g:netrw_ftpextracmd
9582 " call Decho("filter input: ".getline('.'),'~'.expand("<slnum>"))
9583 endif
9584 NetrwKeepj call setline(line("$")+1,a:listcmd)
Bram Moolenaara6878372014-03-22 21:02:50 +01009585
Luca Saccarolac363ca12024-12-19 20:16:18 +01009586 " perform ftp:
9587 " -i : turns off interactive prompting from ftp
9588 " -n unix : DON'T use <.netrc>, even though it exists
9589 " -n win32: quit being obnoxious about password
9590 if exists("w:netrw_bannercnt")
9591 " exe w:netrw_bannercnt.',$g/^./call Decho("ftp#".line(".").": ".getline("."),''~''.expand("<slnum>"))'
9592 call s:NetrwExe(s:netrw_silentxfer.w:netrw_bannercnt.",$!".s:netrw_ftp_cmd." ".g:netrw_ftp_options)
9593 " else " Decho
9594 " call Decho("WARNING: w:netrw_bannercnt doesn't exist!",'~'.expand("<slnum>"))
9595 " g/^./call Decho("SKIPPING ftp#".line(".").": ".getline("."),'~'.expand("<slnum>"))
9596 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01009597
Luca Saccarolac363ca12024-12-19 20:16:18 +01009598 ".........................................
9599 elseif w:netrw_method == 9 " {{{3
9600 " sftp username@machine: Method #9
9601 " s:netrw_sftp_cmd
9602 setl ff=unix
Bram Moolenaara6878372014-03-22 21:02:50 +01009603
Luca Saccarolac363ca12024-12-19 20:16:18 +01009604 " restore settings
9605 let &l:ff= ffkeep
9606 " call Dret("NetrwRemoteFtpCmd")
9607 return
Bram Moolenaara6878372014-03-22 21:02:50 +01009608
Luca Saccarolac363ca12024-12-19 20:16:18 +01009609 ".........................................
9610 else " {{{3
9611 NetrwKeepj call netrw#ErrorMsg(s:WARNING,"unable to comply with your request<" . bufname("%") . ">",23)
Bram Moolenaara6878372014-03-22 21:02:50 +01009612 endif
9613
9614 " cleanup for Windows " {{{3
Nir Lichtman1e34b952024-05-08 19:19:34 +02009615 if has("win32")
Luca Saccarolac363ca12024-12-19 20:16:18 +01009616 sil! NetrwKeepj %s/\r$//e
9617 NetrwKeepj call histdel("/",-1)
Bram Moolenaara6878372014-03-22 21:02:50 +01009618 endif
9619 if a:listcmd == "dir"
Luca Saccarolac363ca12024-12-19 20:16:18 +01009620 " infer directory/link based on the file permission string
9621 sil! NetrwKeepj g/d\%([-r][-w][-x]\)\{3}/NetrwKeepj s@$@/@e
9622 sil! NetrwKeepj g/l\%([-r][-w][-x]\)\{3}/NetrwKeepj s/$/@/e
Bram Moolenaar8feef4f2015-01-07 16:57:10 +01009623 NetrwKeepj call histdel("/",-1)
Luca Saccarolac363ca12024-12-19 20:16:18 +01009624 NetrwKeepj call histdel("/",-1)
9625 if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || (exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST)
9626 exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$s/^\%(\S\+\s\+\)\{8}//e'
9627 NetrwKeepj call histdel("/",-1)
9628 endif
Bram Moolenaara6878372014-03-22 21:02:50 +01009629 endif
9630
9631 " ftp's listing doesn't seem to include ./ or ../ " {{{3
9632 if !search('^\.\/$\|\s\.\/$','wn')
Luca Saccarolac363ca12024-12-19 20:16:18 +01009633 exe 'NetrwKeepj '.w:netrw_bannercnt
9634 NetrwKeepj put ='./'
Bram Moolenaara6878372014-03-22 21:02:50 +01009635 endif
9636 if !search('^\.\.\/$\|\s\.\.\/$','wn')
Luca Saccarolac363ca12024-12-19 20:16:18 +01009637 exe 'NetrwKeepj '.w:netrw_bannercnt
9638 NetrwKeepj put ='../'
Bram Moolenaara6878372014-03-22 21:02:50 +01009639 endif
9640
9641 " restore settings " {{{3
K.Takataa262d3f2024-01-25 04:10:19 +09009642 let &l:ff= ffkeep
Luca Saccarolac363ca12024-12-19 20:16:18 +01009643 " call Dret("NetrwRemoteFtpCmd")
Bram Moolenaara6878372014-03-22 21:02:50 +01009644endfun
9645
9646" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +00009647" s:NetrwRemoteListing: {{{2
9648fun! s:NetrwRemoteListing()
Luca Saccarolac363ca12024-12-19 20:16:18 +01009649 " call Dfunc("s:NetrwRemoteListing() b:netrw_curdir<".b:netrw_curdir.">) win#".winnr())
Bram Moolenaar69a7cb42004-06-20 12:51:53 +00009650
Bram Moolenaara6878372014-03-22 21:02:50 +01009651 if !exists("w:netrw_bannercnt") && exists("s:bannercnt")
Luca Saccarolac363ca12024-12-19 20:16:18 +01009652 let w:netrw_bannercnt= s:bannercnt
Bram Moolenaara6878372014-03-22 21:02:50 +01009653 endif
9654 if !exists("w:netrw_bannercnt") && exists("b:bannercnt")
Luca Saccarolac363ca12024-12-19 20:16:18 +01009655 let w:netrw_bannercnt= b:bannercnt
Bram Moolenaara6878372014-03-22 21:02:50 +01009656 endif
9657
Bram Moolenaar446cb832008-06-24 21:56:24 +00009658 call s:RemotePathAnalysis(b:netrw_curdir)
Bram Moolenaarcfbc5ee2004-07-02 15:38:35 +00009659
Bram Moolenaar446cb832008-06-24 21:56:24 +00009660 " sanity check:
9661 if exists("b:netrw_method") && b:netrw_method =~ '[235]'
Luca Saccarolac363ca12024-12-19 20:16:18 +01009662 " call Decho("b:netrw_method=".b:netrw_method,'~'.expand("<slnum>"))
9663 if !executable("ftp")
9664 " call Decho("ftp is not executable",'~'.expand("<slnum>"))
9665 if !exists("g:netrw_quiet")
9666 call netrw#ErrorMsg(s:ERROR,"this system doesn't support remote directory listing via ftp",18)
9667 endif
9668 call s:NetrwOptionsRestore("w:")
9669 " call Dret("s:NetrwRemoteListing -1")
9670 return -1
Bram Moolenaar446cb832008-06-24 21:56:24 +00009671 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009672
Bram Moolenaar8d043172014-01-23 14:24:41 +01009673 elseif !exists("g:netrw_list_cmd") || g:netrw_list_cmd == ''
Luca Saccarolac363ca12024-12-19 20:16:18 +01009674 " call Decho("g:netrw_list_cmd<",(exists("g:netrw_list_cmd")? 'n/a' : "-empty-").">",'~'.expand("<slnum>"))
9675 if !exists("g:netrw_quiet")
9676 if g:netrw_list_cmd == ""
9677 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)
9678 else
9679 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"this system doesn't support remote directory listing via ".g:netrw_list_cmd,19)
9680 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009681 endif
Bram Moolenaarcfbc5ee2004-07-02 15:38:35 +00009682
Luca Saccarolac363ca12024-12-19 20:16:18 +01009683 NetrwKeepj call s:NetrwOptionsRestore("w:")
9684 " call Dret("s:NetrwRemoteListing -1")
9685 return -1
Bram Moolenaar446cb832008-06-24 21:56:24 +00009686 endif " (remote handling sanity check)
Luca Saccarolac363ca12024-12-19 20:16:18 +01009687 " call Decho("passed remote listing sanity checks",'~'.expand("<slnum>"))
Bram Moolenaarcfbc5ee2004-07-02 15:38:35 +00009688
Bram Moolenaar446cb832008-06-24 21:56:24 +00009689 if exists("b:netrw_method")
Luca Saccarolac363ca12024-12-19 20:16:18 +01009690 " call Decho("setting w:netrw_method to b:netrw_method<".b:netrw_method.">",'~'.expand("<slnum>"))
9691 let w:netrw_method= b:netrw_method
Bram Moolenaar446cb832008-06-24 21:56:24 +00009692 endif
9693
Bram Moolenaar13600302014-05-22 18:26:40 +02009694 if s:method == "ftp"
Luca Saccarolac363ca12024-12-19 20:16:18 +01009695 " use ftp to get remote file listing {{{3
9696 " call Decho("use ftp to get remote file listing",'~'.expand("<slnum>"))
9697 let s:method = "ftp"
9698 let listcmd = g:netrw_ftp_list_cmd
9699 if g:netrw_sort_by =~# '^t'
9700 let listcmd= g:netrw_ftp_timelist_cmd
9701 elseif g:netrw_sort_by =~# '^s'
9702 let listcmd= g:netrw_ftp_sizelist_cmd
Bram Moolenaara6878372014-03-22 21:02:50 +01009703 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01009704 " call Decho("listcmd<".listcmd."> (using g:netrw_ftp_list_cmd)",'~'.expand("<slnum>"))
9705 call s:NetrwRemoteFtpCmd(s:path,listcmd)
9706 " exe "sil! keepalt NetrwKeepj ".w:netrw_bannercnt.',$g/^./call Decho("raw listing: ".getline("."),''~''.expand("<slnum>"))'
Bram Moolenaara6878372014-03-22 21:02:50 +01009707
Luca Saccarolac363ca12024-12-19 20:16:18 +01009708 " report on missing file or directory messages
9709 if search('[Nn]o such file or directory\|Failed to change directory')
9710 let mesg= getline(".")
9711 if exists("w:netrw_bannercnt")
9712 setl ma
9713 exe w:netrw_bannercnt.",$d _"
9714 setl noma
9715 endif
9716 NetrwKeepj call s:NetrwOptionsRestore("w:")
9717 call netrw#ErrorMsg(s:WARNING,mesg,96)
9718 " call Dret("s:NetrwRemoteListing : -1")
9719 return -1
9720 endif
9721
9722 if w:netrw_liststyle == s:THINLIST || w:netrw_liststyle == s:WIDELIST || (exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST)
9723 " shorten the listing
9724 " call Decho("generate short listing",'~'.expand("<slnum>"))
9725 exe "sil! keepalt NetrwKeepj ".w:netrw_bannercnt
9726
9727 " cleanup
9728 if g:netrw_ftp_browse_reject != ""
9729 exe "sil! keepalt NetrwKeepj g/".g:netrw_ftp_browse_reject."/NetrwKeepj d"
9730 NetrwKeepj call histdel("/",-1)
9731 endif
9732 sil! NetrwKeepj %s/\r$//e
9733 NetrwKeepj call histdel("/",-1)
9734
9735 " if there's no ../ listed, then put ../ in
9736 let line1= line(".")
9737 exe "sil! NetrwKeepj ".w:netrw_bannercnt
9738 let line2= search('\.\.\/\%(\s\|$\)','cnW')
9739 " call Decho("search(".'\.\.\/\%(\s\|$\)'."','cnW')=".line2." w:netrw_bannercnt=".w:netrw_bannercnt,'~'.expand("<slnum>"))
9740 if line2 == 0
9741 " call Decho("netrw is putting ../ into listing",'~'.expand("<slnum>"))
9742 sil! NetrwKeepj put='../'
9743 endif
9744 exe "sil! NetrwKeepj ".line1
9745 sil! NetrwKeepj norm! 0
9746
9747 " call Decho("line1=".line1." line2=".line2." line(.)=".line("."),'~'.expand("<slnum>"))
9748 if search('^\d\{2}-\d\{2}-\d\{2}\s','n') " M$ ftp site cleanup
9749 " call Decho("M$ ftp cleanup",'~'.expand("<slnum>"))
9750 exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\d\{2}-\d\{2}-\d\{2}\s\+\d\+:\d\+[AaPp][Mm]\s\+\%(<DIR>\|\d\+\)\s\+//'
9751 NetrwKeepj call histdel("/",-1)
9752 else " normal ftp cleanup
9753 " call Decho("normal ftp cleanup",'~'.expand("<slnum>"))
9754 exe 'sil! NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\%(\S\+\s\+\)\{7}\S\+\)\s\+\(\S.*\)$/\2/e'
9755 exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g/ -> /s# -> .*/$#/#e'
9756 exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g/ -> /s# -> .*$#/#e'
9757 NetrwKeepj call histdel("/",-1)
9758 NetrwKeepj call histdel("/",-1)
9759 NetrwKeepj call histdel("/",-1)
9760 endif
9761 endif
9762
9763 else
9764 " use ssh to get remote file listing {{{3
9765 " call Decho("use ssh to get remote file listing: s:path<".s:path.">",'~'.expand("<slnum>"))
9766 let listcmd= s:MakeSshCmd(g:netrw_list_cmd)
9767 " call Decho("listcmd<".listcmd."> (using g:netrw_list_cmd)",'~'.expand("<slnum>"))
9768 if g:netrw_scp_cmd =~ '^pscp'
9769 " call Decho("1: exe r! ".s:ShellEscape(listcmd.s:path, 1),'~'.expand("<slnum>"))
9770 exe "NetrwKeepj r! ".listcmd.s:ShellEscape(s:path, 1)
9771 " remove rubbish and adjust listing format of 'pscp' to 'ssh ls -FLa' like
9772 sil! NetrwKeepj g/^Listing directory/NetrwKeepj d
9773 sil! NetrwKeepj g/^d[-rwx][-rwx][-rwx]/NetrwKeepj s+$+/+e
9774 sil! NetrwKeepj g/^l[-rwx][-rwx][-rwx]/NetrwKeepj s+$+@+e
9775 NetrwKeepj call histdel("/",-1)
9776 NetrwKeepj call histdel("/",-1)
9777 NetrwKeepj call histdel("/",-1)
9778 if g:netrw_liststyle != s:LONGLIST
9779 sil! NetrwKeepj g/^[dlsp-][-rwx][-rwx][-rwx]/NetrwKeepj s/^.*\s\(\S\+\)$/\1/e
9780 NetrwKeepj call histdel("/",-1)
9781 endif
9782 else
9783 if s:path == ""
9784 " call Decho("2: exe r! ".listcmd,'~'.expand("<slnum>"))
9785 exe "NetrwKeepj keepalt r! ".listcmd
9786 else
9787 " call Decho("3: exe r! ".listcmd.' '.s:ShellEscape(fnameescape(s:path),1),'~'.expand("<slnum>"))
9788 exe "NetrwKeepj keepalt r! ".listcmd.' '.s:ShellEscape(fnameescape(s:path),1)
9789 " call Decho("listcmd<".listcmd."> path<".s:path.">",'~'.expand("<slnum>"))
9790 endif
9791 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009792
9793 " cleanup
Luca Saccarolac363ca12024-12-19 20:16:18 +01009794 if g:netrw_ssh_browse_reject != ""
9795 " call Decho("cleanup: exe sil! g/".g:netrw_ssh_browse_reject."/NetrwKeepj d",'~'.expand("<slnum>"))
9796 exe "sil! g/".g:netrw_ssh_browse_reject."/NetrwKeepj d"
9797 NetrwKeepj call histdel("/",-1)
Bram Moolenaar446cb832008-06-24 21:56:24 +00009798 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009799 endif
9800
9801 if w:netrw_liststyle == s:LONGLIST
Luca Saccarolac363ca12024-12-19 20:16:18 +01009802 " do a long listing; these substitutions need to be done prior to sorting {{{3
9803 " call Decho("fix long listing:",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00009804
Luca Saccarolac363ca12024-12-19 20:16:18 +01009805 if s:method == "ftp"
9806 " cleanup
9807 exe "sil! NetrwKeepj ".w:netrw_bannercnt
9808 while getline('.') =~# g:netrw_ftp_browse_reject
9809 sil! NetrwKeepj d
9810 endwhile
9811 " if there's no ../ listed, then put ../ in
9812 let line1= line(".")
9813 sil! NetrwKeepj 1
9814 sil! NetrwKeepj call search('^\.\.\/\%(\s\|$\)','W')
9815 let line2= line(".")
9816 if line2 == 0
9817 if b:netrw_curdir != '/'
9818 exe 'sil! NetrwKeepj '.w:netrw_bannercnt."put='../'"
9819 endif
9820 endif
9821 exe "sil! NetrwKeepj ".line1
9822 sil! NetrwKeepj norm! 0
Bram Moolenaar446cb832008-06-24 21:56:24 +00009823 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009824
Luca Saccarolac363ca12024-12-19 20:16:18 +01009825 if search('^\d\{2}-\d\{2}-\d\{2}\s','n') " M$ ftp site cleanup
9826 " call Decho("M$ ftp site listing cleanup",'~'.expand("<slnum>"))
9827 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/'
9828 elseif exists("w:netrw_bannercnt") && w:netrw_bannercnt <= line("$")
9829 " call Decho("normal ftp site listing cleanup: bannercnt=".w:netrw_bannercnt." line($)=".line("$"),'~'.expand("<slnum>"))
9830 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/ -> .*$//e'
9831 exe 'sil NetrwKeepj '.w:netrw_bannercnt.',$s/^\(\%(\S\+\s\+\)\{7}\S\+\)\s\+\(\S.*\)$/\2 \t\1/e'
9832 exe 'sil NetrwKeepj '.w:netrw_bannercnt
9833 NetrwKeepj call histdel("/",-1)
9834 NetrwKeepj call histdel("/",-1)
9835 NetrwKeepj call histdel("/",-1)
9836 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009837 endif
9838
Luca Saccarolac363ca12024-12-19 20:16:18 +01009839 " if exists("w:netrw_bannercnt") && w:netrw_bannercnt <= line("$") " Decho
9840 " exe "NetrwKeepj ".w:netrw_bannercnt.',$g/^./call Decho("listing: ".getline("."),''~''.expand("<slnum>"))'
9841 " endif " Decho
Bram Moolenaara6878372014-03-22 21:02:50 +01009842
Luca Saccarolac363ca12024-12-19 20:16:18 +01009843 " call Dret("s:NetrwRemoteListing 0")
Bram Moolenaara6878372014-03-22 21:02:50 +01009844 return 0
Bram Moolenaarcfbc5ee2004-07-02 15:38:35 +00009845endfun
9846
Bram Moolenaar446cb832008-06-24 21:56:24 +00009847" ---------------------------------------------------------------------
9848" s:NetrwRemoteRm: remove/delete a remote file or directory {{{2
9849fun! s:NetrwRemoteRm(usrhost,path) range
Bram Moolenaare0fa3742016-02-20 15:47:01 +01009850 let svpos= winsaveview()
Bram Moolenaar446cb832008-06-24 21:56:24 +00009851
9852 let all= 0
9853 if exists("s:netrwmarkfilelist_{bufnr('%')}")
Luca Saccarolac363ca12024-12-19 20:16:18 +01009854 " remove all marked files
9855 for fname in s:netrwmarkfilelist_{bufnr("%")}
9856 let ok= s:NetrwRemoteRmFile(a:path,fname,all)
9857 if ok =~# 'q\%[uit]'
9858 break
9859 elseif ok =~# 'a\%[ll]'
9860 let all= 1
9861 endif
9862 endfor
9863 call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
Bram Moolenaar446cb832008-06-24 21:56:24 +00009864
9865 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01009866 " remove files specified by range
Bram Moolenaar446cb832008-06-24 21:56:24 +00009867
Luca Saccarolac363ca12024-12-19 20:16:18 +01009868 " preparation for removing multiple files/directories
9869 let keepsol = &l:sol
9870 setl nosol
9871 let ctr = a:firstline
Bram Moolenaar446cb832008-06-24 21:56:24 +00009872
Luca Saccarolac363ca12024-12-19 20:16:18 +01009873 " remove multiple files and directories
9874 while ctr <= a:lastline
9875 exe "NetrwKeepj ".ctr
9876 let ok= s:NetrwRemoteRmFile(a:path,s:NetrwGetWord(),all)
9877 if ok =~# 'q\%[uit]'
9878 break
9879 elseif ok =~# 'a\%[ll]'
9880 let all= 1
9881 endif
9882 let ctr= ctr + 1
9883 endwhile
9884 let &l:sol = keepsol
Bram Moolenaar446cb832008-06-24 21:56:24 +00009885 endif
9886
9887 " refresh the (remote) directory listing
Tom Benham64a536d2024-11-07 21:15:03 +01009888 NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./',0))
Bram Moolenaare0fa3742016-02-20 15:47:01 +01009889 NetrwKeepj call winrestview(svpos)
Bram Moolenaar446cb832008-06-24 21:56:24 +00009890endfun
9891
9892" ---------------------------------------------------------------------
9893" s:NetrwRemoteRmFile: {{{2
9894fun! s:NetrwRemoteRmFile(path,rmfile,all)
Luca Saccarolac363ca12024-12-19 20:16:18 +01009895 " call Dfunc("s:NetrwRemoteRmFile(path<".a:path."> rmfile<".a:rmfile.">) all=".a:all)
Bram Moolenaar446cb832008-06-24 21:56:24 +00009896
9897 let all= a:all
9898 let ok = ""
9899
9900 if a:rmfile !~ '^"' && (a:rmfile =~ '@$' || a:rmfile !~ '[\/]$')
Luca Saccarolac363ca12024-12-19 20:16:18 +01009901 " attempt to remove file
9902 " call Decho("attempt to remove file (all=".all.")",'~'.expand("<slnum>"))
9903 if !all
9904 echohl Statement
9905 " call Decho("case all=0:",'~'.expand("<slnum>"))
9906 call inputsave()
9907 let ok= input("Confirm deletion of file<".a:rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
9908 call inputrestore()
9909 echohl NONE
9910 if ok == ""
9911 let ok="no"
9912 endif
9913 let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
9914 if ok =~# 'a\%[ll]'
9915 let all= 1
9916 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009917 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009918
Luca Saccarolac363ca12024-12-19 20:16:18 +01009919 if all || ok =~# 'y\%[es]' || ok == ""
9920 " call Decho("case all=".all." or ok<".ok.">".(exists("w:netrw_method")? ': netrw_method='.w:netrw_method : ""),'~'.expand("<slnum>"))
9921 if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
9922 " call Decho("case ftp:",'~'.expand("<slnum>"))
9923 let path= a:path
9924 if path =~ '^\a\{3,}://'
9925 let path= substitute(path,'^\a\{3,}://[^/]\+/','','')
9926 endif
9927 sil! NetrwKeepj .,$d _
9928 call s:NetrwRemoteFtpCmd(path,"delete ".'"'.a:rmfile.'"')
Bram Moolenaar446cb832008-06-24 21:56:24 +00009929 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01009930 " call Decho("case ssh: g:netrw_rm_cmd<".g:netrw_rm_cmd.">",'~'.expand("<slnum>"))
9931 let netrw_rm_cmd= s:MakeSshCmd(g:netrw_rm_cmd)
9932 " call Decho("netrw_rm_cmd<".netrw_rm_cmd.">",'~'.expand("<slnum>"))
9933 if !exists("b:netrw_curdir")
9934 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"for some reason b:netrw_curdir doesn't exist!",53)
9935 let ok="q"
9936 else
9937 let remotedir= substitute(b:netrw_curdir,'^.\{-}//[^/]\+/\(.*\)$','\1','')
9938 " call Decho("netrw_rm_cmd<".netrw_rm_cmd.">",'~'.expand("<slnum>"))
9939 " call Decho("remotedir<".remotedir.">",'~'.expand("<slnum>"))
9940 " call Decho("rmfile<".a:rmfile.">",'~'.expand("<slnum>"))
9941 if remotedir != ""
9942 let netrw_rm_cmd= netrw_rm_cmd." ".s:ShellEscape(fnameescape(remotedir.a:rmfile))
9943 else
9944 let netrw_rm_cmd= netrw_rm_cmd." ".s:ShellEscape(fnameescape(a:rmfile))
9945 endif
9946 " call Decho("call system(".netrw_rm_cmd.")",'~'.expand("<slnum>"))
9947 let ret= system(netrw_rm_cmd)
9948 if v:shell_error != 0
9949 if exists("b:netrw_curdir") && b:netrw_curdir != getcwd() && !g:netrw_keepdir
9950 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)
9951 else
9952 call netrw#ErrorMsg(s:WARNING,"cmd<".netrw_rm_cmd."> failed",60)
9953 endif
9954 elseif ret != 0
9955 call netrw#ErrorMsg(s:WARNING,"cmd<".netrw_rm_cmd."> failed",60)
9956 endif
9957 " call Decho("returned=".ret." errcode=".v:shell_error,'~'.expand("<slnum>"))
9958 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009959 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01009960 elseif ok =~# 'q\%[uit]'
9961 " call Decho("ok==".ok,'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +00009962 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009963
9964 else
Luca Saccarolac363ca12024-12-19 20:16:18 +01009965 " attempt to remove directory
9966 " call Decho("attempt to remove directory",'~'.expand("<slnum>"))
9967 if !all
9968 call inputsave()
9969 let ok= input("Confirm deletion of directory<".a:rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
9970 call inputrestore()
9971 if ok == ""
9972 let ok="no"
Bram Moolenaar446cb832008-06-24 21:56:24 +00009973 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +01009974 let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
9975 if ok =~# 'a\%[ll]'
9976 let all= 1
9977 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +00009978 endif
9979
Luca Saccarolac363ca12024-12-19 20:16:18 +01009980 if all || ok =~# 'y\%[es]' || ok == ""
9981 if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
9982 NetrwKeepj call s:NetrwRemoteFtpCmd(a:path,"rmdir ".a:rmfile)
9983 else
9984 let rmfile = substitute(a:path.a:rmfile,'/$','','')
9985 let netrw_rmdir_cmd = s:MakeSshCmd(netrw#WinPath(g:netrw_rmdir_cmd)).' '.s:ShellEscape(netrw#WinPath(rmfile))
9986 " call Decho("attempt to remove dir: system(".netrw_rmdir_cmd.")",'~'.expand("<slnum>"))
9987 let ret= system(netrw_rmdir_cmd)
9988 " call Decho("returned=".ret." errcode=".v:shell_error,'~'.expand("<slnum>"))
9989
9990 if v:shell_error != 0
9991 " call Decho("v:shell_error not 0",'~'.expand("<slnum>"))
9992 let netrw_rmf_cmd= s:MakeSshCmd(netrw#WinPath(g:netrw_rmf_cmd)).' '.s:ShellEscape(netrw#WinPath(substitute(rmfile,'[\/]$','','e')))
9993 " call Decho("2nd attempt to remove dir: system(".netrw_rmf_cmd.")",'~'.expand("<slnum>"))
9994 let ret= system(netrw_rmf_cmd)
9995 " call Decho("returned=".ret." errcode=".v:shell_error,'~'.expand("<slnum>"))
9996
9997 if v:shell_error != 0 && !exists("g:netrw_quiet")
9998 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"unable to remove directory<".rmfile."> -- is it empty?",22)
9999 endif
10000 endif
10001 endif
10002
10003 elseif ok =~# 'q\%[uit]'
10004 " call Decho("ok==".ok,'~'.expand("<slnum>"))
10005 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +000010006 endif
10007
Luca Saccarolac363ca12024-12-19 20:16:18 +010010008 " call Dret("s:NetrwRemoteRmFile ".ok)
Bram Moolenaar446cb832008-06-24 21:56:24 +000010009 return ok
10010endfun
10011
10012" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +000010013" s:NetrwRemoteRename: rename a remote file or directory {{{2
10014fun! s:NetrwRemoteRename(usrhost,path) range
Bram Moolenaar446cb832008-06-24 21:56:24 +000010015
10016 " preparation for removing multiple files/directories
Bram Moolenaare0fa3742016-02-20 15:47:01 +010010017 let svpos = winsaveview()
Luca Saccarolac363ca12024-12-19 20:16:18 +010010018 " call Decho("saving posn to svpos<".string(svpos).">",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +000010019 let ctr = a:firstline
10020 let rename_cmd = s:MakeSshCmd(g:netrw_rename_cmd)
10021
10022 " rename files given by the markfilelist
10023 if exists("s:netrwmarkfilelist_{bufnr('%')}")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010024 for oldname in s:netrwmarkfilelist_{bufnr("%")}
10025 if exists("subfrom")
10026 let newname= substitute(oldname,subfrom,subto,'')
10027 else
10028 call inputsave()
10029 let newname= input("Moving ".oldname." to : ",oldname)
10030 call inputrestore()
10031 if newname =~ '^s/'
10032 let subfrom = substitute(newname,'^s/\([^/]*\)/.*/$','\1','')
10033 let subto = substitute(newname,'^s/[^/]*/\(.*\)/$','\1','')
10034 let newname = substitute(oldname,subfrom,subto,'')
10035 endif
10036 endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010037
Luca Saccarolac363ca12024-12-19 20:16:18 +010010038 if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
10039 NetrwKeepj call s:NetrwRemoteFtpCmd(a:path,"rename ".oldname." ".newname)
10040 else
10041 let oldname= s:ShellEscape(a:path.oldname)
10042 let newname= s:ShellEscape(a:path.newname)
10043 let ret = system(netrw#WinPath(rename_cmd).' '.oldname.' '.newname)
10044 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +000010045
Luca Saccarolac363ca12024-12-19 20:16:18 +010010046 endfor
10047 call s:NetrwUnMarkFile(1)
Bram Moolenaar446cb832008-06-24 21:56:24 +000010048
10049 else
10050
Luca Saccarolac363ca12024-12-19 20:16:18 +010010051 " attempt to rename files/directories
10052 let keepsol= &l:sol
10053 setl nosol
10054 while ctr <= a:lastline
10055 exe "NetrwKeepj ".ctr
Bram Moolenaar446cb832008-06-24 21:56:24 +000010056
Luca Saccarolac363ca12024-12-19 20:16:18 +010010057 let oldname= s:NetrwGetWord()
Bram Moolenaar446cb832008-06-24 21:56:24 +000010058
Luca Saccarolac363ca12024-12-19 20:16:18 +010010059 call inputsave()
10060 let newname= input("Moving ".oldname." to : ",oldname)
10061 call inputrestore()
Bram Moolenaar446cb832008-06-24 21:56:24 +000010062
Luca Saccarolac363ca12024-12-19 20:16:18 +010010063 if exists("w:netrw_method") && (w:netrw_method == 2 || w:netrw_method == 3)
10064 call s:NetrwRemoteFtpCmd(a:path,"rename ".oldname." ".newname)
10065 else
10066 let oldname= s:ShellEscape(a:path.oldname)
10067 let newname= s:ShellEscape(a:path.newname)
10068 let ret = system(netrw#WinPath(rename_cmd).' '.oldname.' '.newname)
10069 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +000010070
Luca Saccarolac363ca12024-12-19 20:16:18 +010010071 let ctr= ctr + 1
10072 endwhile
10073 let &l:sol= keepsol
Bram Moolenaar446cb832008-06-24 21:56:24 +000010074 endif
10075
10076 " refresh the directory
Tom Benham64a536d2024-11-07 21:15:03 +010010077 NetrwKeepj call s:NetrwRefresh(0,s:NetrwBrowseChgDir(0,'./',0))
Bram Moolenaare0fa3742016-02-20 15:47:01 +010010078 NetrwKeepj call winrestview(svpos)
Bram Moolenaar446cb832008-06-24 21:56:24 +000010079endfun
10080
Bram Moolenaar85850f32019-07-19 22:05:51 +020010081" ==========================================
Bram Moolenaar446cb832008-06-24 21:56:24 +000010082" Local Directory Browsing Support: {{{1
10083" ==========================================
10084
10085" ---------------------------------------------------------------------
Bram Moolenaar85850f32019-07-19 22:05:51 +020010086" netrw#FileUrlEdit: handles editing file://* files {{{2
Bram Moolenaar97d62492012-11-15 21:28:22 +010010087" Should accept: file://localhost/etc/fstab
10088" file:///etc/fstab
10089" file:///c:/WINDOWS/clock.avi
10090" file:///c|/WINDOWS/clock.avi
10091" file://localhost/c:/WINDOWS/clock.avi
10092" file://localhost/c|/WINDOWS/clock.avi
10093" file://c:/foo.txt
10094" file:///c:/foo.txt
10095" 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 +020010096fun! netrw#FileUrlEdit(fname)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010097 " call Dfunc("netrw#FileUrlEdit(fname<".a:fname.">)")
Bram Moolenaar97d62492012-11-15 21:28:22 +010010098 let fname = a:fname
10099 if fname =~ '^file://localhost/'
Luca Saccarolac363ca12024-12-19 20:16:18 +010010100 " call Decho('converting file://localhost/ -to- file:///','~'.expand("<slnum>"))
10101 let fname= substitute(fname,'^file://localhost/','file:///','')
10102 " call Decho("fname<".fname.">",'~'.expand("<slnum>"))
Bram Moolenaar97d62492012-11-15 21:28:22 +010010103 endif
Nir Lichtman1e34b952024-05-08 19:19:34 +020010104 if has("win32")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010105 if fname =~ '^file:///\=\a[|:]/'
10106 " call Decho('converting file:///\a|/ -to- file://\a:/','~'.expand("<slnum>"))
10107 let fname = substitute(fname,'^file:///\=\(\a\)[|:]/','file://\1:/','')
10108 " call Decho("fname<".fname.">",'~'.expand("<slnum>"))
10109 endif
Bram Moolenaar97d62492012-11-15 21:28:22 +010010110 endif
10111 let fname2396 = netrw#RFC2396(fname)
10112 let fname2396e= fnameescape(fname2396)
10113 let plainfname= substitute(fname2396,'file://\(.*\)','\1',"")
Nir Lichtman1e34b952024-05-08 19:19:34 +020010114 if has("win32")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010115 " call Decho("windows exception for plainfname",'~'.expand("<slnum>"))
10116 if plainfname =~ '^/\+\a:'
10117 " call Decho('removing leading "/"s','~'.expand("<slnum>"))
10118 let plainfname= substitute(plainfname,'^/\+\(\a:\)','\1','')
10119 endif
Bram Moolenaar97d62492012-11-15 21:28:22 +010010120 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +020010121
Luca Saccarolac363ca12024-12-19 20:16:18 +010010122 " call Decho("fname2396<".fname2396.">",'~'.expand("<slnum>"))
10123 " call Decho("plainfname<".plainfname.">",'~'.expand("<slnum>"))
Bram Moolenaar97d62492012-11-15 21:28:22 +010010124 exe "sil doau BufReadPre ".fname2396e
Bram Moolenaar85850f32019-07-19 22:05:51 +020010125 exe 'NetrwKeepj keepalt edit '.plainfname
10126 exe 'sil! NetrwKeepj keepalt bdelete '.fnameescape(a:fname)
10127
Luca Saccarolac363ca12024-12-19 20:16:18 +010010128 " call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
10129 " call Dret("netrw#FileUrlEdit")
Bram Moolenaar97d62492012-11-15 21:28:22 +010010130 exe "sil doau BufReadPost ".fname2396e
10131endfun
10132
10133" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +000010134" netrw#LocalBrowseCheck: {{{2
10135fun! netrw#LocalBrowseCheck(dirname)
Bram Moolenaar89a9c152021-08-29 21:55:35 +020010136 " This function is called by netrwPlugin.vim's s:LocalBrowseCheck(), s:NetrwRexplore(),
Bram Moolenaar85850f32019-07-19 22:05:51 +020010137 " and by <cr> when atop a listed file/directory (via a buffer-local map)
10138 "
10139 " unfortunate interaction -- split window debugging can't be used here, must use
10140 " D-echoRemOn or D-echoTabOn as the BufEnter event triggers
10141 " another call to LocalBrowseCheck() when attempts to write
10142 " to the DBG buffer are made.
10143 "
Bram Moolenaar446cb832008-06-24 21:56:24 +000010144 " The &ft == "netrw" test was installed because the BufEnter event
10145 " would hit when re-entering netrw windows, creating unexpected
10146 " refreshes (and would do so in the middle of NetrwSaveOptions(), too)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010147 " call Dfunc("netrw#LocalBrowseCheck(dirname<".a:dirname.">)")
10148 " call Decho("isdir<".a:dirname."> =".isdirectory(s:NetrwFile(a:dirname)).((exists("s:treeforceredraw")? " treeforceredraw" : "")).'~'.expand("<slnum>"))
10149 " 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 +010010150 " getting E930: Cannot use :redir inside execute
Luca Saccarolac363ca12024-12-19 20:16:18 +010010151 "" call Dredir("ls!","netrw#LocalBrowseCheck")
10152 " call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10153 " call Decho("current buffer#".bufnr("%")."<".bufname("%")."> ft=".&ft,'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +010010154
Bram Moolenaar97d62492012-11-15 21:28:22 +010010155 let ykeep= @@
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010156 if isdirectory(s:NetrwFile(a:dirname))
Luca Saccarolac363ca12024-12-19 20:16:18 +010010157 " 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 +010010158
Luca Saccarolac363ca12024-12-19 20:16:18 +010010159 if &ft != "netrw" || (exists("b:netrw_curdir") && b:netrw_curdir != a:dirname) || g:netrw_fastbrowse <= 1
10160 " call Decho("case 1 : ft=".&ft,'~'.expand("<slnum>"))
10161 " call Decho("s:rexposn_".bufnr("%")."<".bufname("%")."> ".(exists("s:rexposn_".bufnr("%"))? "exists" : "does not exist"),'~'.expand("<slnum>"))
10162 sil! NetrwKeepj keepalt call s:NetrwBrowse(1,a:dirname)
Bram Moolenaar8d043172014-01-23 14:24:41 +010010163
Luca Saccarolac363ca12024-12-19 20:16:18 +010010164 elseif &ft == "netrw" && line("$") == 1
10165 " call Decho("case 2 (ft≡netrw && line($)≡1)",'~'.expand("<slnum>"))
10166 sil! NetrwKeepj keepalt call s:NetrwBrowse(1,a:dirname)
Bram Moolenaar8d043172014-01-23 14:24:41 +010010167
Luca Saccarolac363ca12024-12-19 20:16:18 +010010168 elseif exists("s:treeforceredraw")
10169 " call Decho("case 3 (treeforceredraw)",'~'.expand("<slnum>"))
10170 unlet s:treeforceredraw
10171 sil! NetrwKeepj keepalt call s:NetrwBrowse(1,a:dirname)
10172 endif
10173 " call Decho("tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> line#".line(".")." col#".col(".")." winline#".winline()." wincol#".wincol(),'~'.expand("<slnum>"))
10174 " call Dret("netrw#LocalBrowseCheck")
10175 return
Bram Moolenaar446cb832008-06-24 21:56:24 +000010176 endif
Bram Moolenaar8d043172014-01-23 14:24:41 +010010177
Bram Moolenaar85850f32019-07-19 22:05:51 +020010178 " The following code wipes out currently unused netrw buffers
Bram Moolenaar97d62492012-11-15 21:28:22 +010010179 " IF g:netrw_fastbrowse is zero (ie. slow browsing selected)
10180 " AND IF the listing style is not a tree listing
10181 if exists("g:netrw_fastbrowse") && g:netrw_fastbrowse == 0 && g:netrw_liststyle != s:TREELIST
Luca Saccarolac363ca12024-12-19 20:16:18 +010010182 " call Decho("wiping out currently unused netrw buffers",'~'.expand("<slnum>"))
10183 let ibuf = 1
10184 let buflast = bufnr("$")
10185 while ibuf <= buflast
10186 if bufwinnr(ibuf) == -1 && isdirectory(s:NetrwFile(bufname(ibuf)))
10187 exe "sil! keepj keepalt ".ibuf."bw!"
10188 endif
10189 let ibuf= ibuf + 1
10190 endwhile
Bram Moolenaar97d62492012-11-15 21:28:22 +010010191 endif
10192 let @@= ykeep
Luca Saccarolac363ca12024-12-19 20:16:18 +010010193 " 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>"))
10194 " 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 +000010195 " not a directory, ignore it
Luca Saccarolac363ca12024-12-19 20:16:18 +010010196 " call Dret("netrw#LocalBrowseCheck : not a directory, ignoring it; dirname<".a:dirname.">")
Bram Moolenaar446cb832008-06-24 21:56:24 +000010197endfun
10198
10199" ---------------------------------------------------------------------
Bram Moolenaara6878372014-03-22 21:02:50 +010010200" s:LocalBrowseRefresh: this function is called after a user has {{{2
Bram Moolenaar446cb832008-06-24 21:56:24 +000010201" performed any shell command. The idea is to cause all local-browsing
10202" buffers to be refreshed after a user has executed some shell command,
10203" on the chance that s/he removed/created a file/directory with it.
Bram Moolenaara6878372014-03-22 21:02:50 +010010204fun! s:LocalBrowseRefresh()
Bram Moolenaar446cb832008-06-24 21:56:24 +000010205 " determine which buffers currently reside in a tab
10206 if !exists("s:netrw_browselist")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010207 return
Bram Moolenaar446cb832008-06-24 21:56:24 +000010208 endif
10209 if !exists("w:netrw_bannercnt")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010210 return
Bram Moolenaar446cb832008-06-24 21:56:24 +000010211 endif
Christian Brabandtfbd72d22023-12-19 20:22:18 +010010212 if !empty(getcmdwintype())
10213 " cannot move away from cmdline window, see :h E11
10214 return
10215 endif
Bram Moolenaara6878372014-03-22 21:02:50 +010010216 if exists("s:netrw_events") && s:netrw_events == 1
Luca Saccarolac363ca12024-12-19 20:16:18 +010010217 " s:LocalFastBrowser gets called (indirectly) from a
10218 let s:netrw_events= 2
10219 return
Bram Moolenaar5c736222010-01-06 20:54:52 +010010220 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +000010221 let itab = 1
10222 let buftablist = []
Bram Moolenaar97d62492012-11-15 21:28:22 +010010223 let ykeep = @@
Bram Moolenaar446cb832008-06-24 21:56:24 +000010224 while itab <= tabpagenr("$")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010225 let buftablist = buftablist + tabpagebuflist()
10226 let itab = itab + 1
10227 sil! tabn
Bram Moolenaar446cb832008-06-24 21:56:24 +000010228 endwhile
Bram Moolenaar446cb832008-06-24 21:56:24 +000010229 " GO through all buffers on netrw_browselist (ie. just local-netrw buffers):
10230 " | refresh any netrw window
10231 " | wipe out any non-displaying netrw buffer
Bram Moolenaar85850f32019-07-19 22:05:51 +020010232 let curwinid = win_getid(winnr())
Bram Moolenaar446cb832008-06-24 21:56:24 +000010233 let ibl = 0
10234 for ibuf in s:netrw_browselist
Luca Saccarolac363ca12024-12-19 20:16:18 +010010235 if bufwinnr(ibuf) == -1 && index(buftablist,ibuf) == -1
10236 " wipe out any non-displaying netrw buffer
10237 " (ibuf not shown in a current window AND
10238 " ibuf not in any tab)
10239 exe "sil! keepj bd ".fnameescape(ibuf)
10240 call remove(s:netrw_browselist,ibl)
10241 continue
10242 elseif index(tabpagebuflist(),ibuf) != -1
10243 " refresh any netrw buffer
10244 exe bufwinnr(ibuf)."wincmd w"
10245 if getline(".") =~# 'Quick Help'
10246 " decrement g:netrw_quickhelp to prevent refresh from changing g:netrw_quickhelp
10247 " (counteracts s:NetrwBrowseChgDir()'s incrementing)
10248 let g:netrw_quickhelp= g:netrw_quickhelp - 1
10249 endif
10250 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
10251 NetrwKeepj call s:NetrwRefreshTreeDict(w:netrw_treetop)
10252 endif
10253 NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./',0))
Bram Moolenaara6878372014-03-22 21:02:50 +010010254 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010010255 let ibl= ibl + 1
Bram Moolenaar446cb832008-06-24 21:56:24 +000010256 endfor
Bram Moolenaar85850f32019-07-19 22:05:51 +020010257 call win_gotoid(curwinid)
Bram Moolenaar97d62492012-11-15 21:28:22 +010010258 let @@= ykeep
Bram Moolenaar446cb832008-06-24 21:56:24 +000010259endfun
10260
10261" ---------------------------------------------------------------------
Bram Moolenaar97d62492012-11-15 21:28:22 +010010262" s:LocalFastBrowser: handles setting up/taking down fast browsing for the local browser {{{2
10263"
10264" g:netrw_ Directory Is
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010265" fastbrowse Local Remote
Bram Moolenaar97d62492012-11-15 21:28:22 +010010266" slow 0 D D D=Deleting a buffer implies it will not be re-used (slow)
10267" med 1 D H H=Hiding a buffer implies it may be re-used (fast)
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010268" fast 2 H H
Bram Moolenaar97d62492012-11-15 21:28:22 +010010269"
10270" Deleting a buffer means that it will be re-loaded when examined, hence "slow".
10271" Hiding a buffer means that it will be re-used when examined, hence "fast".
Bram Moolenaara6878372014-03-22 21:02:50 +010010272" (re-using a buffer may not be as accurate)
10273"
Bram Moolenaar89a9c152021-08-29 21:55:35 +020010274" s:netrw_events : doesn't exist, s:LocalFastBrowser() will install autocmds with medium-speed or fast browsing
Bram Moolenaara6878372014-03-22 21:02:50 +010010275" =1: autocmds installed, but ignore next FocusGained event to avoid initial double-refresh of listing.
10276" BufEnter may be first event, then a FocusGained event. Ignore the first FocusGained event.
10277" If :Explore used: it sets s:netrw_events to 2, so no FocusGained events are ignored.
10278" =2: autocmds installed (doesn't ignore any FocusGained events)
Bram Moolenaar97d62492012-11-15 21:28:22 +010010279fun! s:LocalFastBrowser()
Bram Moolenaar97d62492012-11-15 21:28:22 +010010280
10281 " initialize browselist, a list of buffer numbers that the local browser has used
10282 if !exists("s:netrw_browselist")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010283 let s:netrw_browselist= []
Bram Moolenaar97d62492012-11-15 21:28:22 +010010284 endif
10285
10286 " append current buffer to fastbrowse list
10287 if empty(s:netrw_browselist) || bufnr("%") > s:netrw_browselist[-1]
Luca Saccarolac363ca12024-12-19 20:16:18 +010010288 call add(s:netrw_browselist,bufnr("%"))
Bram Moolenaar97d62492012-11-15 21:28:22 +010010289 endif
10290
10291 " enable autocmd events to handle refreshing/removing local browser buffers
10292 " If local browse buffer is currently showing: refresh it
10293 " If local browse buffer is currently hidden : wipe it
10294 " g:netrw_fastbrowse=0 : slow speed, never re-use directory listing
10295 " =1 : medium speed, re-use directory listing for remote only
10296 " =2 : fast speed, always re-use directory listing when possible
Bram Moolenaara6878372014-03-22 21:02:50 +010010297 if g:netrw_fastbrowse <= 1 && !exists("#ShellCmdPost") && !exists("s:netrw_events")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010298 let s:netrw_events= 1
10299 augroup AuNetrwEvent
10300 au!
10301 if has("win32")
10302 au ShellCmdPost * call s:LocalBrowseRefresh()
10303 else
10304 au ShellCmdPost,FocusGained * call s:LocalBrowseRefresh()
10305 endif
10306 augroup END
Bram Moolenaar97d62492012-11-15 21:28:22 +010010307
shane.xb.qianc673b802024-12-20 19:36:40 +010010308 " user must have changed fastbrowse to its fast setting, so remove
10309 " the associated autocmd events
Bram Moolenaara6878372014-03-22 21:02:50 +010010310 elseif g:netrw_fastbrowse > 1 && exists("#ShellCmdPost") && exists("s:netrw_events")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010311 unlet s:netrw_events
10312 augroup AuNetrwEvent
10313 au!
10314 augroup END
10315 augroup! AuNetrwEvent
Bram Moolenaar97d62492012-11-15 21:28:22 +010010316 endif
Bram Moolenaar97d62492012-11-15 21:28:22 +010010317endfun
10318
Tom Benham64a536d2024-11-07 21:15:03 +010010319fun! s:NetrwLocalListingList(dirname,setmaxfilenamelen)
Bram Moolenaara6878372014-03-22 21:02:50 +010010320 " get the list of files contained in the current directory
Tom Benham64a536d2024-11-07 21:15:03 +010010321 let dirname = a:dirname
10322 let dirnamelen = strlen(dirname)
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +020010323 let filelist = s:NetrwGlob(dirname,"*",0)
10324 let filelist = filelist + s:NetrwGlob(dirname,".*",0)
Bram Moolenaara6878372014-03-22 21:02:50 +010010325
Nir Lichtman1e34b952024-05-08 19:19:34 +020010326 if g:netrw_cygwin == 0 && has("win32")
Tom Benham64a536d2024-11-07 21:15:03 +010010327 elseif index(filelist,'..') == -1 && dirname !~ '/'
Bram Moolenaara6878372014-03-22 21:02:50 +010010328 " include ../ in the glob() entry if its missing
Luca Saccarolac363ca12024-12-19 20:16:18 +010010329 let filelist= filelist+[s:ComposePath(dirname,"../")]
Bram Moolenaara6878372014-03-22 21:02:50 +010010330 endif
10331
Tom Benham64a536d2024-11-07 21:15:03 +010010332 if a:setmaxfilenamelen && get(g:, 'netrw_dynamic_maxfilenamelen', 0)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010333 let filelistcopy = map(deepcopy(filelist),'fnamemodify(v:val, ":t")')
10334 let g:netrw_maxfilenamelen = max(map(filelistcopy,'len(v:val)')) + 1
Bram Moolenaara6878372014-03-22 21:02:50 +010010335 endif
Bram Moolenaara6878372014-03-22 21:02:50 +010010336
Tom Benham64a536d2024-11-07 21:15:03 +010010337 let resultfilelist = []
Bram Moolenaara6878372014-03-22 21:02:50 +010010338 for filename in filelist
Bram Moolenaara6878372014-03-22 21:02:50 +010010339
Luca Saccarolac363ca12024-12-19 20:16:18 +010010340 if getftype(filename) == "link"
10341 " indicate a symbolic link
10342 let pfile= filename."@"
Bram Moolenaara6878372014-03-22 21:02:50 +010010343
Luca Saccarolac363ca12024-12-19 20:16:18 +010010344 elseif getftype(filename) == "socket"
10345 " indicate a socket
10346 let pfile= filename."="
Bram Moolenaara6878372014-03-22 21:02:50 +010010347
Luca Saccarolac363ca12024-12-19 20:16:18 +010010348 elseif getftype(filename) == "fifo"
10349 " indicate a fifo
10350 let pfile= filename."|"
Bram Moolenaara6878372014-03-22 21:02:50 +010010351
Luca Saccarolac363ca12024-12-19 20:16:18 +010010352 elseif isdirectory(s:NetrwFile(filename))
10353 " indicate a directory
10354 let pfile= filename."/"
Bram Moolenaara6878372014-03-22 21:02:50 +010010355
Luca Saccarolac363ca12024-12-19 20:16:18 +010010356 elseif exists("b:netrw_curdir") && b:netrw_curdir !~ '^.*://' && !isdirectory(s:NetrwFile(filename))
10357 if has("win32")
10358 if filename =~ '\.[eE][xX][eE]$' || filename =~ '\.[cC][oO][mM]$' || filename =~ '\.[bB][aA][tT]$'
10359 " indicate an executable
10360 let pfile= filename."*"
10361 else
10362 " normal file
10363 let pfile= filename
10364 endif
10365 elseif executable(filename)
10366 " indicate an executable
10367 let pfile= filename."*"
10368 else
10369 " normal file
10370 let pfile= filename
10371 endif
10372
10373 else
Bram Moolenaara6878372014-03-22 21:02:50 +010010374 " normal file
10375 let pfile= filename
Luca Saccarolac363ca12024-12-19 20:16:18 +010010376 endif
10377
10378 if pfile =~ '//$'
10379 let pfile= substitute(pfile,'//$','/','e')
10380 endif
10381 let pfile= strpart(pfile,dirnamelen)
10382 let pfile= substitute(pfile,'^[/\\]','','e')
10383
10384 if w:netrw_liststyle == s:LONGLIST
10385 let longfile = printf("%-".g:netrw_maxfilenamelen."S",pfile)
10386 let sz = getfsize(filename)
10387 let szlen = 15 - (strdisplaywidth(longfile) - g:netrw_maxfilenamelen)
10388 let szlen = (szlen > 0) ? szlen : 0
10389
10390 if g:netrw_sizestyle =~# "[hH]"
10391 let sz= s:NetrwHumanReadable(sz)
10392 endif
10393 let fsz = printf("%".szlen."S",sz)
10394 let pfile= longfile." ".fsz." ".strftime(g:netrw_timefmt,getftime(filename))
10395 endif
10396
10397 if g:netrw_sort_by =~# "^t"
10398 " sort by time (handles time up to 1 quintillion seconds, US)
10399 " Decorate listing by prepending a timestamp/ . Sorting will then be done based on time.
10400 let t = getftime(filename)
10401 let ft = printf("%018d",t)
10402 let ftpfile= ft.'/'.pfile
10403 let resultfilelist += [ftpfile]
10404
10405 elseif g:netrw_sort_by =~ "^s"
10406 " sort by size (handles file sizes up to 1 quintillion bytes, US)
10407 let sz = getfsize(filename)
10408 let fsz = printf("%018d",sz)
10409 let fszpfile= fsz.'/'.pfile
10410 let resultfilelist += [fszpfile]
10411
Bram Moolenaara6878372014-03-22 21:02:50 +010010412 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010010413 " sort by name
10414 let resultfilelist += [pfile]
Bram Moolenaara6878372014-03-22 21:02:50 +010010415 endif
Tom Benham64a536d2024-11-07 21:15:03 +010010416 endfor
10417
10418 return resultfilelist
10419endfun
10420
10421" ---------------------------------------------------------------------
10422" s:LocalListing: does the job of "ls" for local directories {{{2
10423fun! s:LocalListing()
10424
10425 let filelist = s:NetrwLocalListingList(b:netrw_curdir, 1)
10426 for filename in filelist
10427 sil! NetrwKeepj put =filename
Bram Moolenaara6878372014-03-22 21:02:50 +010010428 endfor
10429
10430 " cleanup any windows mess at end-of-line
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010010431 sil! NetrwKeepj g/^$/d
10432 sil! NetrwKeepj %s/\r$//e
Bram Moolenaara6878372014-03-22 21:02:50 +010010433 call histdel("/",-1)
Bram Moolenaara6878372014-03-22 21:02:50 +010010434 exe "setl ts=".(g:netrw_maxfilenamelen+1)
Bram Moolenaara6878372014-03-22 21:02:50 +010010435endfun
10436
10437" ---------------------------------------------------------------------
Bram Moolenaar97d62492012-11-15 21:28:22 +010010438" s:NetrwLocalExecute: uses system() to execute command under cursor ("X" command support) {{{2
10439fun! s:NetrwLocalExecute(cmd)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010440 " call Dfunc("s:NetrwLocalExecute(cmd<".a:cmd.">)")
Bram Moolenaar97d62492012-11-15 21:28:22 +010010441 let ykeep= @@
10442 " sanity check
10443 if !executable(a:cmd)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010444 call netrw#ErrorMsg(s:ERROR,"the file<".a:cmd."> is not executable!",89)
10445 let @@= ykeep
10446 " call Dret("s:NetrwLocalExecute")
10447 return
Bram Moolenaar97d62492012-11-15 21:28:22 +010010448 endif
10449
10450 let optargs= input(":!".a:cmd,"","file")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010451 " call Decho("optargs<".optargs.">",'~'.expand("<slnum>"))
Bram Moolenaar97d62492012-11-15 21:28:22 +010010452 let result= system(a:cmd.optargs)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010453 " call Decho("result,'~'.expand("<slnum>"))
Bram Moolenaar97d62492012-11-15 21:28:22 +010010454
10455 " strip any ansi escape sequences off
10456 let result = substitute(result,"\e\\[[0-9;]*m","","g")
10457
10458 " show user the result(s)
10459 echomsg result
10460 let @@= ykeep
10461
Luca Saccarolac363ca12024-12-19 20:16:18 +010010462 " call Dret("s:NetrwLocalExecute")
Bram Moolenaar97d62492012-11-15 21:28:22 +010010463endfun
10464
10465" ---------------------------------------------------------------------
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010010466" s:NetrwLocalRename: rename a local file or directory {{{2
Bram Moolenaar97d62492012-11-15 21:28:22 +010010467fun! s:NetrwLocalRename(path) range
Bram Moolenaar97d62492012-11-15 21:28:22 +010010468
KSR-Yasudab52e7ac2023-12-12 01:11:43 +090010469 if !exists("w:netrw_bannercnt")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010470 let w:netrw_bannercnt= b:netrw_bannercnt
KSR-Yasudab52e7ac2023-12-12 01:11:43 +090010471 endif
10472
Bram Moolenaar97d62492012-11-15 21:28:22 +010010473 " preparation for removing multiple files/directories
Bram Moolenaar29634562020-01-09 21:46:04 +010010474 let ykeep = @@
10475 let ctr = a:firstline
10476 let svpos = winsaveview()
10477 let all = 0
Bram Moolenaar97d62492012-11-15 21:28:22 +010010478
10479 " rename files given by the markfilelist
10480 if exists("s:netrwmarkfilelist_{bufnr('%')}")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010481 for oldname in s:netrwmarkfilelist_{bufnr("%")}
10482 if exists("subfrom")
10483 let newname= substitute(oldname,subfrom,subto,'')
10484 else
10485 call inputsave()
10486 let newname= input("Moving ".oldname." to : ",oldname,"file")
10487 call inputrestore()
10488 if newname =~ ''
10489 " two ctrl-x's : ignore all of string preceding the ctrl-x's
10490 let newname = substitute(newname,'^.*','','')
10491 elseif newname =~ ''
10492 " one ctrl-x : ignore portion of string preceding ctrl-x but after last /
10493 let newname = substitute(newname,'[^/]*','','')
10494 endif
10495 if newname =~ '^s/'
10496 let subfrom = substitute(newname,'^s/\([^/]*\)/.*/$','\1','')
10497 let subto = substitute(newname,'^s/[^/]*/\(.*\)/$','\1','')
10498 let newname = substitute(oldname,subfrom,subto,'')
10499 endif
10500 endif
10501 if !all && filereadable(newname)
10502 call inputsave()
10503 let response= input("File<".newname."> already exists; do you want to overwrite it? (y/all/n) ")
10504 call inputrestore()
10505 if response == "all"
10506 let all= 1
10507 elseif response != "y" && response != "yes"
10508 " refresh the directory
10509 NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./',0))
10510 NetrwKeepj call winrestview(svpos)
10511 let @@= ykeep
10512 return
10513 endif
10514 endif
10515 call rename(oldname,newname)
10516 endfor
10517 call s:NetrwUnmarkList(bufnr("%"),b:netrw_curdir)
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010518
Bram Moolenaar97d62492012-11-15 21:28:22 +010010519 else
10520
Luca Saccarolac363ca12024-12-19 20:16:18 +010010521 " attempt to rename files/directories
10522 while ctr <= a:lastline
10523 exe "NetrwKeepj ".ctr
Bram Moolenaar97d62492012-11-15 21:28:22 +010010524
Luca Saccarolac363ca12024-12-19 20:16:18 +010010525 " sanity checks
10526 if line(".") < w:netrw_bannercnt
10527 let ctr= ctr + 1
10528 continue
10529 endif
10530 let curword= s:NetrwGetWord()
10531 if curword == "./" || curword == "../"
10532 let ctr= ctr + 1
10533 continue
10534 endif
Bram Moolenaar97d62492012-11-15 21:28:22 +010010535
Luca Saccarolac363ca12024-12-19 20:16:18 +010010536 NetrwKeepj norm! 0
10537 let oldname= s:ComposePath(a:path,curword)
Bram Moolenaar97d62492012-11-15 21:28:22 +010010538
Luca Saccarolac363ca12024-12-19 20:16:18 +010010539 call inputsave()
10540 let newname= input("Moving ".oldname." to : ",substitute(oldname,'/*$','','e'))
10541 call inputrestore()
Bram Moolenaar97d62492012-11-15 21:28:22 +010010542
Luca Saccarolac363ca12024-12-19 20:16:18 +010010543 call rename(oldname,newname)
10544 let ctr= ctr + 1
10545 endwhile
Bram Moolenaar97d62492012-11-15 21:28:22 +010010546 endif
10547
10548 " refresh the directory
Tom Benham64a536d2024-11-07 21:15:03 +010010549 NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./',0))
Bram Moolenaare0fa3742016-02-20 15:47:01 +010010550 NetrwKeepj call winrestview(svpos)
Bram Moolenaar97d62492012-11-15 21:28:22 +010010551 let @@= ykeep
Bram Moolenaar97d62492012-11-15 21:28:22 +010010552endfun
10553
10554" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +000010555" s:NetrwLocalRm: {{{2
10556fun! s:NetrwLocalRm(path) range
KSR-Yasudab52e7ac2023-12-12 01:11:43 +090010557 if !exists("w:netrw_bannercnt")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010558 let w:netrw_bannercnt= b:netrw_bannercnt
KSR-Yasudab52e7ac2023-12-12 01:11:43 +090010559 endif
10560
Bram Moolenaar446cb832008-06-24 21:56:24 +000010561 " preparation for removing multiple files/directories
Bram Moolenaar97d62492012-11-15 21:28:22 +010010562 let ykeep = @@
Bram Moolenaar446cb832008-06-24 21:56:24 +000010563 let ret = 0
10564 let all = 0
Bram Moolenaare0fa3742016-02-20 15:47:01 +010010565 let svpos = winsaveview()
Bram Moolenaar446cb832008-06-24 21:56:24 +000010566
10567 if exists("s:netrwmarkfilelist_{bufnr('%')}")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010568 " remove all marked files
10569 for fname in s:netrwmarkfilelist_{bufnr("%")}
10570 let ok= s:NetrwLocalRmFile(a:path,fname,all)
10571 if ok =~# 'q\%[uit]' || ok == "no"
10572 break
10573 elseif ok =~# '^a\%[ll]$'
10574 let all= 1
10575 endif
10576 endfor
10577 call s:NetrwUnMarkFile(1)
Bram Moolenaar446cb832008-06-24 21:56:24 +000010578
10579 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010010580 " remove (multiple) files and directories
Bram Moolenaar446cb832008-06-24 21:56:24 +000010581
Luca Saccarolac363ca12024-12-19 20:16:18 +010010582 let keepsol= &l:sol
10583 setl nosol
10584 let ctr = a:firstline
10585 while ctr <= a:lastline
10586 exe "NetrwKeepj ".ctr
Bram Moolenaar446cb832008-06-24 21:56:24 +000010587
Luca Saccarolac363ca12024-12-19 20:16:18 +010010588 " sanity checks
10589 if line(".") < w:netrw_bannercnt
10590 let ctr= ctr + 1
10591 continue
10592 endif
10593 let curword= s:NetrwGetWord()
10594 if curword == "./" || curword == "../"
10595 let ctr= ctr + 1
10596 continue
10597 endif
10598 let ok= s:NetrwLocalRmFile(a:path,curword,all)
10599 if ok =~# 'q\%[uit]' || ok == "no"
10600 break
10601 elseif ok =~# '^a\%[ll]$'
10602 let all= 1
10603 endif
10604 let ctr= ctr + 1
10605 endwhile
10606 let &l:sol= keepsol
Bram Moolenaar446cb832008-06-24 21:56:24 +000010607 endif
10608
10609 " refresh the directory
Bram Moolenaar446cb832008-06-24 21:56:24 +000010610 if bufname("%") != "NetrwMessage"
Luca Saccarolac363ca12024-12-19 20:16:18 +010010611 NetrwKeepj call s:NetrwRefresh(1,s:NetrwBrowseChgDir(1,'./',0))
10612 NetrwKeepj call winrestview(svpos)
Bram Moolenaar446cb832008-06-24 21:56:24 +000010613 endif
Bram Moolenaar97d62492012-11-15 21:28:22 +010010614 let @@= ykeep
Bram Moolenaar446cb832008-06-24 21:56:24 +000010615endfun
10616
10617" ---------------------------------------------------------------------
10618" s:NetrwLocalRmFile: remove file fname given the path {{{2
10619" Give confirmation prompt unless all==1
10620fun! s:NetrwLocalRmFile(path,fname,all)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010621 " call Dfunc("s:NetrwLocalRmFile(path<".a:path."> fname<".a:fname."> all=".a:all)
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010622
Bram Moolenaar446cb832008-06-24 21:56:24 +000010623 let all= a:all
10624 let ok = ""
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010010625 NetrwKeepj norm! 0
Christian Brabandt581d4a72024-07-23 21:14:06 +020010626 let rmfile= s:NetrwFile(s:ComposePath(a:path,escape(a:fname, '\\')))
Luca Saccarolac363ca12024-12-19 20:16:18 +010010627 " call Decho("rmfile<".rmfile.">",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +000010628
10629 if rmfile !~ '^"' && (rmfile =~ '@$' || rmfile !~ '[\/]$')
Luca Saccarolac363ca12024-12-19 20:16:18 +010010630 " attempt to remove file
10631 " call Decho("attempt to remove file<".rmfile.">",'~'.expand("<slnum>"))
10632 if !all
10633 echohl Statement
10634 call inputsave()
10635 let ok= input("Confirm deletion of file <".rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
10636 call inputrestore()
10637 echohl NONE
10638 if ok == ""
10639 let ok="no"
10640 endif
10641 " call Decho("response: ok<".ok.">",'~'.expand("<slnum>"))
10642 let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
10643 " call Decho("response: ok<".ok."> (after sub)",'~'.expand("<slnum>"))
10644 if ok =~# '^a\%[ll]$'
10645 let all= 1
10646 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +000010647 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +000010648
Luca Saccarolac363ca12024-12-19 20:16:18 +010010649 if all || ok =~# '^y\%[es]$' || ok == ""
10650 let ret= s:NetrwDelete(rmfile)
10651 " call Decho("errcode=".v:shell_error." ret=".ret,'~'.expand("<slnum>"))
10652 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +000010653
10654 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010010655 " attempt to remove directory
10656 if !all
10657 echohl Statement
10658 call inputsave()
10659 let ok= input("Confirm *recursive* deletion of directory <".rmfile."> ","[{y(es)},n(o),a(ll),q(uit)] ")
10660 call inputrestore()
10661 let ok= substitute(ok,'\[{y(es)},n(o),a(ll),q(uit)]\s*','','e')
10662 if ok == ""
10663 let ok="no"
10664 endif
10665 if ok =~# '^a\%[ll]$'
10666 let all= 1
10667 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +000010668 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010010669 let rmfile= substitute(rmfile,'[\/]$','','e')
Bram Moolenaar446cb832008-06-24 21:56:24 +000010670
Luca Saccarolac363ca12024-12-19 20:16:18 +010010671 if all || ok =~# '^y\%[es]$' || ok == ""
10672 if delete(rmfile,"rf")
10673 call netrw#ErrorMsg(s:ERROR,"unable to delete directory <".rmfile.">!",103)
10674 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +000010675 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +000010676 endif
10677
Luca Saccarolac363ca12024-12-19 20:16:18 +010010678 " call Dret("s:NetrwLocalRmFile ".ok)
Bram Moolenaar446cb832008-06-24 21:56:24 +000010679 return ok
10680endfun
10681
Bram Moolenaar85850f32019-07-19 22:05:51 +020010682" =====================================================================
Bram Moolenaar9964e462007-05-05 17:54:07 +000010683" Support Functions: {{{1
10684
Bram Moolenaar488c6512005-08-11 20:09:58 +000010685" ---------------------------------------------------------------------
Bram Moolenaara6878372014-03-22 21:02:50 +010010686" netrw#Access: intended to provide access to variable values for netrw's test suite {{{2
10687" 0: marked file list of current buffer
10688" 1: marked file target
10689fun! netrw#Access(ilist)
10690 if a:ilist == 0
Luca Saccarolac363ca12024-12-19 20:16:18 +010010691 if exists("s:netrwmarkfilelist_".bufnr('%'))
10692 return s:netrwmarkfilelist_{bufnr('%')}
10693 else
10694 return "no-list-buf#".bufnr('%')
10695 endif
Bram Moolenaara6878372014-03-22 21:02:50 +010010696 elseif a:ilist == 1
Luca Saccarolac363ca12024-12-19 20:16:18 +010010697 return s:netrwmftgt
Bram Moolenaar85850f32019-07-19 22:05:51 +020010698 endif
Bram Moolenaara6878372014-03-22 21:02:50 +010010699endfun
10700
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010701" ---------------------------------------------------------------------
10702" netrw#Call: allows user-specified mappings to call internal netrw functions {{{2
10703fun! netrw#Call(funcname,...)
Bram Moolenaar85850f32019-07-19 22:05:51 +020010704 return call("s:".a:funcname,a:000)
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010705endfun
10706
Bram Moolenaara6878372014-03-22 21:02:50 +010010707" ---------------------------------------------------------------------
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010708" netrw#Expose: allows UserMaps and pchk to look at otherwise script-local variables {{{2
10709" I expect this function to be used in
10710" :PChkAssert netrw#Expose("netrwmarkfilelist")
10711" for example.
10712fun! netrw#Expose(varname)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010713 " call Dfunc("netrw#Expose(varname<".a:varname.">)")
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +020010714 if exists("s:".a:varname)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010715 exe "let retval= s:".a:varname
10716 " call Decho("retval=".retval,'~'.expand("<slnum>"))
10717 if exists("g:netrw_pchk")
10718 " call Decho("type(g:netrw_pchk=".g:netrw_pchk.")=".type(retval),'~'.expand("<slnum>"))
10719 if type(retval) == 3
10720 let retval = copy(retval)
10721 let i = 0
10722 while i < len(retval)
10723 let retval[i]= substitute(retval[i],expand("$HOME"),'~','')
10724 let i = i + 1
10725 endwhile
10726 endif
10727 " call Dret("netrw#Expose ".string(retval)),'~'.expand("<slnum>"))
10728 return string(retval)
10729 else
10730 " call Decho("g:netrw_pchk doesn't exist",'~'.expand("<slnum>"))
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +020010731 endif
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +020010732 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010010733 " call Decho("s:".a:varname." doesn't exist",'~'.expand("<slnum>"))
10734 let retval= "n/a"
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010735 endif
10736
Luca Saccarolac363ca12024-12-19 20:16:18 +010010737 " call Dret("netrw#Expose ".string(retval))
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010738 return retval
10739endfun
10740
10741" ---------------------------------------------------------------------
10742" netrw#Modify: allows UserMaps to set (modify) script-local variables {{{2
10743fun! netrw#Modify(varname,newvalue)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010744 " call Dfunc("netrw#Modify(varname<".a:varname.">,newvalue<".string(a:newvalue).">)")
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010745 exe "let s:".a:varname."= ".string(a:newvalue)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010746 " call Dret("netrw#Modify")
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010747endfun
10748
10749" ---------------------------------------------------------------------
Bram Moolenaara6878372014-03-22 21:02:50 +010010750" netrw#RFC2396: converts %xx into characters {{{2
10751fun! netrw#RFC2396(fname)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010752 " call Dfunc("netrw#RFC2396(fname<".a:fname.">)")
K.Takata23577652024-01-13 01:30:01 +090010753 let fname = escape(substitute(a:fname,'%\(\x\x\)','\=printf("%c","0x".submatch(1))','ge')," \t")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010754 " call Dret("netrw#RFC2396 ".fname)
Bram Moolenaara6878372014-03-22 21:02:50 +010010755 return fname
10756endfun
10757
10758" ---------------------------------------------------------------------
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010759" netrw#UserMaps: supports user-specified maps {{{2
10760" see :help function()
10761"
10762" g:Netrw_UserMaps is a List with members such as:
10763" [[keymap sequence, function reference],...]
10764"
10765" The referenced function may return a string,
Luca Saccarolac363ca12024-12-19 20:16:18 +010010766" refresh : refresh the display
10767" -other- : this string will be executed
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010768" or it may return a List of strings.
10769"
10770" Each keymap-sequence will be set up with a nnoremap
Bram Moolenaar85850f32019-07-19 22:05:51 +020010771" to invoke netrw#UserMaps(a:islocal).
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010772" Related functions:
10773" netrw#Expose(varname) -- see s:varname variables
10774" netrw#Modify(varname,newvalue) -- modify value of s:varname variable
10775" netrw#Call(funcname,...) -- call internal netrw function with optional arguments
10776fun! netrw#UserMaps(islocal)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010777 " call Dfunc("netrw#UserMaps(islocal=".a:islocal.")")
10778 " call Decho("g:Netrw_UserMaps ".(exists("g:Netrw_UserMaps")? "exists" : "does NOT exist"),'~'.expand("<slnum>"))
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010779
Luca Saccarolac363ca12024-12-19 20:16:18 +010010780 " set up usermaplist
10781 if exists("g:Netrw_UserMaps") && type(g:Netrw_UserMaps) == 3
10782 " call Decho("g:Netrw_UserMaps has type 3<List>",'~'.expand("<slnum>"))
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010783 for umap in g:Netrw_UserMaps
Luca Saccarolac363ca12024-12-19 20:16:18 +010010784 " call Decho("type(umap[0]<".string(umap[0]).">)=".type(umap[0])." (should be 1=string)",'~'.expand("<slnum>"))
10785 " call Decho("type(umap[1])=".type(umap[1])." (should be 1=string)",'~'.expand("<slnum>"))
10786 " if umap[0] is a string and umap[1] is a string holding a function name
10787 if type(umap[0]) == 1 && type(umap[1]) == 1
10788 " call Decho("nno <buffer> <silent> ".umap[0]." :call s:UserMaps(".a:islocal.",".string(umap[1]).")<cr>",'~'.expand("<slnum>"))
10789 exe "nno <buffer> <silent> ".umap[0]." :call <SID>UserMaps(".a:islocal.",'".umap[1]."')<cr>"
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010790 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010010791 call netrw#ErrorMsg(s:WARNING,"ignoring usermap <".string(umap[0])."> -- not a [string,funcref] entry",99)
10792 endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010793 endfor
Luca Saccarolac363ca12024-12-19 20:16:18 +010010794 endif
10795 " call Dret("netrw#UserMaps")
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010796endfun
10797
10798" ---------------------------------------------------------------------
Bram Moolenaare6ae6222013-05-21 21:01:10 +020010799" netrw#WinPath: tries to insure that the path is windows-acceptable, whether cygwin is used or not {{{2
10800fun! netrw#WinPath(path)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010801 " call Dfunc("netrw#WinPath(path<".a:path.">)")
Nir Lichtman1e34b952024-05-08 19:19:34 +020010802 if (!g:netrw_cygwin || &shell !~ '\%(\<bash\>\|\<zsh\>\)\%(\.exe\)\=$') && has("win32")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010803 " remove cygdrive prefix, if present
10804 let path = substitute(a:path,g:netrw_cygdrive.'/\(.\)','\1:','')
10805 " remove trailing slash (Win95)
10806 let path = substitute(path, '\(\\\|/\)$', '', 'g')
10807 " remove escaped spaces
10808 let path = substitute(path, '\ ', ' ', 'g')
10809 " convert slashes to backslashes
10810 let path = substitute(path, '/', '\', 'g')
Bram Moolenaare6ae6222013-05-21 21:01:10 +020010811 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010010812 let path= a:path
Bram Moolenaare6ae6222013-05-21 21:01:10 +020010813 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010010814 " call Dret("netrw#WinPath <".path.">")
Bram Moolenaare6ae6222013-05-21 21:01:10 +020010815 return path
10816endfun
10817
10818" ---------------------------------------------------------------------
Travis Sheltone34d0e32024-07-30 21:08:56 +020010819" s:StripTrailingSlash: removes trailing slashes from a path {{{2
10820fun! s:StripTrailingSlash(path)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010821 " remove trailing slash
10822 return substitute(a:path, '[/\\]$', '', 'g')
Travis Sheltone34d0e32024-07-30 21:08:56 +020010823endfun
10824
Travis Sheltone34d0e32024-07-30 21:08:56 +020010825" ---------------------------------------------------------------------
Bram Moolenaar85850f32019-07-19 22:05:51 +020010826" s:NetrwBadd: adds marked files to buffer list or vice versa {{{2
10827" cb : bl2mf=0 add marked files to buffer list
10828" cB : bl2mf=1 use bufferlist to mark files
10829" (mnemonic: cb = copy (marked files) to buffer list)
10830fun! s:NetrwBadd(islocal,bl2mf)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010831 " " call Dfunc("s:NetrwBadd(islocal=".a:islocal." mf2bl=".mf2bl.")")
Bram Moolenaar85850f32019-07-19 22:05:51 +020010832 if a:bl2mf
Luca Saccarolac363ca12024-12-19 20:16:18 +010010833 " cB: add buffer list to marked files
10834 redir => bufl
Bram Moolenaar85850f32019-07-19 22:05:51 +020010835 ls
Luca Saccarolac363ca12024-12-19 20:16:18 +010010836 redir END
10837 let bufl = map(split(bufl,"\n"),'substitute(v:val,''^.\{-}"\(.*\)".\{-}$'',''\1'','''')')
10838 for fname in bufl
10839 call s:NetrwMarkFile(a:islocal,fname)
10840 endfor
Bram Moolenaar85850f32019-07-19 22:05:51 +020010841 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010010842 " cb: add marked files to buffer list
10843 for fname in s:netrwmarkfilelist_{bufnr("%")}
10844 " " call Decho("badd ".fname,'~'.expand("<slnum>"))
10845 exe "badd ".fnameescape(fname)
10846 endfor
10847 let curbufnr = bufnr("%")
10848 let curdir = s:NetrwGetCurdir(a:islocal)
10849 call s:NetrwUnmarkList(curbufnr,curdir) " remove markings from local buffer
Bram Moolenaar85850f32019-07-19 22:05:51 +020010850 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010010851 " call Dret("s:NetrwBadd")
Bram Moolenaar85850f32019-07-19 22:05:51 +020010852endfun
10853
10854" ---------------------------------------------------------------------
Bram Moolenaarc236c162008-07-13 17:41:49 +000010855" s:ComposePath: Appends a new part to a path taking different systems into consideration {{{2
10856fun! s:ComposePath(base,subdir)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010857 " call Dfunc("s:ComposePath(base<".a:base."> subdir<".a:subdir.">)")
Bram Moolenaarc236c162008-07-13 17:41:49 +000010858
Bram Moolenaar5b435d62012-04-05 17:33:26 +020010859 if has("amiga")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010860 " call Decho("amiga",'~'.expand("<slnum>"))
10861 let ec = a:base[s:Strlen(a:base)-1]
10862 if ec != '/' && ec != ':'
10863 let ret = a:base."/" . a:subdir
10864 else
10865 let ret = a:base.a:subdir
10866 endif
Bram Moolenaarc236c162008-07-13 17:41:49 +000010867
shane.xb.qianc673b802024-12-20 19:36:40 +010010868 " COMBAK: test on windows with changing to root directory: :e C:/
Nir Lichtman1e34b952024-05-08 19:19:34 +020010869 elseif a:subdir =~ '^\a:[/\\]\([^/\\]\|$\)' && has("win32")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010870 " call Decho("windows",'~'.expand("<slnum>"))
10871 let ret= a:subdir
Bram Moolenaarc236c162008-07-13 17:41:49 +000010872
Nir Lichtman1e34b952024-05-08 19:19:34 +020010873 elseif a:base =~ '^\a:[/\\]\([^/\\]\|$\)' && has("win32")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010874 " call Decho("windows",'~'.expand("<slnum>"))
10875 if a:base =~ '[/\\]$'
10876 let ret= a:base.a:subdir
10877 else
10878 let ret= a:base.'/'.a:subdir
10879 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +010010880
Bram Moolenaara0f849e2015-10-30 14:37:44 +010010881 elseif a:base =~ '^\a\{3,}://'
Luca Saccarolac363ca12024-12-19 20:16:18 +010010882 " call Decho("remote linux/macos",'~'.expand("<slnum>"))
10883 let urlbase = substitute(a:base,'^\(\a\+://.\{-}/\)\(.*\)$','\1','')
10884 let curpath = substitute(a:base,'^\(\a\+://.\{-}/\)\(.*\)$','\2','')
10885 if a:subdir == '../'
10886 if curpath =~ '[^/]/[^/]\+/$'
10887 let curpath= substitute(curpath,'[^/]\+/$','','')
10888 else
10889 let curpath=""
10890 endif
10891 let ret= urlbase.curpath
Bram Moolenaarc236c162008-07-13 17:41:49 +000010892 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010010893 let ret= urlbase.curpath.a:subdir
Bram Moolenaarc236c162008-07-13 17:41:49 +000010894 endif
shane.xb.qianc673b802024-12-20 19:36:40 +010010895 " call Decho("urlbase<".urlbase.">",'~'.expand("<slnum>"))
10896 " call Decho("curpath<".curpath.">",'~'.expand("<slnum>"))
10897 " call Decho("ret<".ret.">",'~'.expand("<slnum>"))
Bram Moolenaarc236c162008-07-13 17:41:49 +000010898
10899 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010010900 " call Decho("local linux/macos",'~'.expand("<slnum>"))
10901 let ret = substitute(a:base."/".a:subdir,"//","/","g")
10902 if a:base =~ '^//'
10903 " keeping initial '//' for the benefit of network share listing support
10904 let ret= '/'.ret
10905 endif
10906 let ret= simplify(ret)
Bram Moolenaarc236c162008-07-13 17:41:49 +000010907 endif
10908
Luca Saccarolac363ca12024-12-19 20:16:18 +010010909 " call Dret("s:ComposePath ".ret)
Bram Moolenaarc236c162008-07-13 17:41:49 +000010910 return ret
10911endfun
10912
10913" ---------------------------------------------------------------------
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010010914" s:DeleteBookmark: deletes a file/directory from Netrw's bookmark system {{{2
10915" Related Functions: s:MakeBookmark() s:NetrwBookHistHandler() s:NetrwBookmark()
10916fun! s:DeleteBookmark(fname)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010917 " call Dfunc("s:DeleteBookmark(fname<".a:fname.">)")
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010010918 call s:MergeBookmarks()
10919
10920 if exists("g:netrw_bookmarklist")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010921 let indx= index(g:netrw_bookmarklist,a:fname)
10922 if indx == -1
10923 let indx= 0
10924 while indx < len(g:netrw_bookmarklist)
10925 if g:netrw_bookmarklist[indx] =~ a:fname
10926 call remove(g:netrw_bookmarklist,indx)
10927 let indx= indx - 1
10928 endif
10929 let indx= indx + 1
10930 endwhile
10931 else
10932 " remove exact match
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010010933 call remove(g:netrw_bookmarklist,indx)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010934 endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010010935 endif
10936
Luca Saccarolac363ca12024-12-19 20:16:18 +010010937 " call Dret("s:DeleteBookmark")
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010010938endfun
10939
10940" ---------------------------------------------------------------------
Bram Moolenaar9964e462007-05-05 17:54:07 +000010941" s:FileReadable: o/s independent filereadable {{{2
10942fun! s:FileReadable(fname)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010943 " call Dfunc("s:FileReadable(fname<".a:fname.">)")
Bram Moolenaar9964e462007-05-05 17:54:07 +000010944
10945 if g:netrw_cygwin
Luca Saccarolac363ca12024-12-19 20:16:18 +010010946 let ret= filereadable(s:NetrwFile(substitute(a:fname,g:netrw_cygdrive.'/\(.\)','\1:/','')))
Bram Moolenaar9964e462007-05-05 17:54:07 +000010947 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010010948 let ret= filereadable(s:NetrwFile(a:fname))
Bram Moolenaar9964e462007-05-05 17:54:07 +000010949 endif
10950
Luca Saccarolac363ca12024-12-19 20:16:18 +010010951 " call Dret("s:FileReadable ".ret)
Bram Moolenaar9964e462007-05-05 17:54:07 +000010952 return ret
10953endfun
10954
10955" ---------------------------------------------------------------------
10956" s:GetTempfile: gets a tempname that'll work for various o/s's {{{2
10957" Places correct suffix on end of temporary filename,
10958" using the suffix provided with fname
10959fun! s:GetTempfile(fname)
Luca Saccarolac363ca12024-12-19 20:16:18 +010010960 " call Dfunc("s:GetTempfile(fname<".a:fname.">)")
Bram Moolenaar9964e462007-05-05 17:54:07 +000010961
10962 if !exists("b:netrw_tmpfile")
Luca Saccarolac363ca12024-12-19 20:16:18 +010010963 " get a brand new temporary filename
10964 let tmpfile= tempname()
10965 " call Decho("tmpfile<".tmpfile."> : from tempname()",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +000010966
Luca Saccarolac363ca12024-12-19 20:16:18 +010010967 let tmpfile= substitute(tmpfile,'\','/','ge')
10968 " call Decho("tmpfile<".tmpfile."> : chgd any \\ -> /",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +000010969
Luca Saccarolac363ca12024-12-19 20:16:18 +010010970 " sanity check -- does the temporary file's directory exist?
10971 if !isdirectory(s:NetrwFile(substitute(tmpfile,'[^/]\+$','','e')))
10972 " call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
10973 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"your <".substitute(tmpfile,'[^/]\+$','','e')."> directory is missing!",2)
10974 " call Dret("s:GetTempfile getcwd<".getcwd().">")
10975 return ""
Bram Moolenaar446cb832008-06-24 21:56:24 +000010976 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010010977
10978 " let netrw#NetSource() know about the tmpfile
10979 let s:netrw_tmpfile= tmpfile " used by netrw#NetSource() and netrw#BrowseX()
10980 " call Decho("tmpfile<".tmpfile."> s:netrw_tmpfile<".s:netrw_tmpfile.">",'~'.expand("<slnum>"))
10981
10982 " o/s dependencies
10983 if g:netrw_cygwin != 0
10984 let tmpfile = substitute(tmpfile,'^\(\a\):',g:netrw_cygdrive.'/\1','e')
10985 elseif has("win32")
10986 if !exists("+shellslash") || !&ssl
10987 let tmpfile = substitute(tmpfile,'/','\','g')
10988 endif
10989 else
10990 let tmpfile = tmpfile
10991 endif
10992 let b:netrw_tmpfile= tmpfile
shane.xb.qianc673b802024-12-20 19:36:40 +010010993 " call Decho("o/s dependent fixed tempname<".tmpfile.">",'~'.expand("<slnum>"))
Bram Moolenaar9964e462007-05-05 17:54:07 +000010994 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010010995 " re-use temporary filename
10996 let tmpfile= b:netrw_tmpfile
10997 " call Decho("tmpfile<".tmpfile."> re-using",'~'.expand("<slnum>"))
Bram Moolenaar9964e462007-05-05 17:54:07 +000010998 endif
10999
11000 " use fname's suffix for the temporary file
11001 if a:fname != ""
Luca Saccarolac363ca12024-12-19 20:16:18 +010011002 if a:fname =~ '\.[^./]\+$'
11003 " call Decho("using fname<".a:fname.">'s suffix",'~'.expand("<slnum>"))
11004 if a:fname =~ '\.tar\.gz$' || a:fname =~ '\.tar\.bz2$' || a:fname =~ '\.tar\.xz$'
11005 let suffix = ".tar".substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
11006 elseif a:fname =~ '.txz$'
11007 let suffix = ".txz".substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
11008 else
11009 let suffix = substitute(a:fname,'^.*\(\.[^./]\+\)$','\1','e')
11010 endif
11011 " call Decho("suffix<".suffix.">",'~'.expand("<slnum>"))
11012 let tmpfile= substitute(tmpfile,'\.tmp$','','e')
11013 " call Decho("chgd tmpfile<".tmpfile."> (removed any .tmp suffix)",'~'.expand("<slnum>"))
11014 let tmpfile .= suffix
11015 " call Decho("chgd tmpfile<".tmpfile."> (added ".suffix." suffix) netrw_fname<".b:netrw_fname.">",'~'.expand("<slnum>"))
11016 let s:netrw_tmpfile= tmpfile " supports netrw#NetSource()
Bram Moolenaar9964e462007-05-05 17:54:07 +000011017 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +000011018 endif
11019
Luca Saccarolac363ca12024-12-19 20:16:18 +010011020 " call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
11021 " call Dret("s:GetTempfile <".tmpfile.">")
Bram Moolenaar9964e462007-05-05 17:54:07 +000011022 return tmpfile
Bram Moolenaar446cb832008-06-24 21:56:24 +000011023endfun
Bram Moolenaar9964e462007-05-05 17:54:07 +000011024
11025" ---------------------------------------------------------------------
11026" s:MakeSshCmd: transforms input command using USEPORT HOSTNAME into {{{2
Bram Moolenaarc236c162008-07-13 17:41:49 +000011027" a correct command for use with a system() call
Bram Moolenaar9964e462007-05-05 17:54:07 +000011028fun! s:MakeSshCmd(sshcmd)
Luca Saccarolac363ca12024-12-19 20:16:18 +010011029 " call Dfunc("s:MakeSshCmd(sshcmd<".a:sshcmd.">) user<".s:user."> machine<".s:machine.">")
Bram Moolenaar13600302014-05-22 18:26:40 +020011030 if s:user == ""
Luca Saccarolac363ca12024-12-19 20:16:18 +010011031 let sshcmd = substitute(a:sshcmd,'\<HOSTNAME\>',s:machine,'')
Bram Moolenaar13600302014-05-22 18:26:40 +020011032 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010011033 let sshcmd = substitute(a:sshcmd,'\<HOSTNAME\>',s:user."@".s:machine,'')
Bram Moolenaar13600302014-05-22 18:26:40 +020011034 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +000011035 if exists("g:netrw_port") && g:netrw_port != ""
Luca Saccarolac363ca12024-12-19 20:16:18 +010011036 let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.g:netrw_port,'')
Bram Moolenaar9964e462007-05-05 17:54:07 +000011037 elseif exists("s:port") && s:port != ""
Luca Saccarolac363ca12024-12-19 20:16:18 +010011038 let sshcmd= substitute(sshcmd,"USEPORT",g:netrw_sshport.' '.s:port,'')
Bram Moolenaar9964e462007-05-05 17:54:07 +000011039 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010011040 let sshcmd= substitute(sshcmd,"USEPORT ",'','')
Bram Moolenaar9964e462007-05-05 17:54:07 +000011041 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011042 " call Dret("s:MakeSshCmd <".sshcmd.">")
Bram Moolenaar9964e462007-05-05 17:54:07 +000011043 return sshcmd
11044endfun
11045
11046" ---------------------------------------------------------------------
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011047" s:MakeBookmark: enters a bookmark into Netrw's bookmark system {{{2
11048fun! s:MakeBookmark(fname)
Luca Saccarolac363ca12024-12-19 20:16:18 +010011049 " call Dfunc("s:MakeBookmark(fname<".a:fname.">)")
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011050
11051 if !exists("g:netrw_bookmarklist")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011052 let g:netrw_bookmarklist= []
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011053 endif
11054
11055 if index(g:netrw_bookmarklist,a:fname) == -1
Luca Saccarolac363ca12024-12-19 20:16:18 +010011056 " curdir not currently in g:netrw_bookmarklist, so include it
11057 if isdirectory(s:NetrwFile(a:fname)) && a:fname !~ '/$'
11058 call add(g:netrw_bookmarklist,a:fname.'/')
11059 elseif a:fname !~ '/'
11060 call add(g:netrw_bookmarklist,getcwd()."/".a:fname)
11061 else
11062 call add(g:netrw_bookmarklist,a:fname)
11063 endif
11064 call sort(g:netrw_bookmarklist)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011065 endif
11066
Luca Saccarolac363ca12024-12-19 20:16:18 +010011067 " call Dret("s:MakeBookmark")
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011068endfun
11069
11070" ---------------------------------------------------------------------
11071" s:MergeBookmarks: merge current bookmarks with saved bookmarks {{{2
11072fun! s:MergeBookmarks()
Luca Saccarolac363ca12024-12-19 20:16:18 +010011073 " call Dfunc("s:MergeBookmarks() : merge current bookmarks into .netrwbook")
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011074 " get bookmarks from .netrwbook file
11075 let savefile= s:NetrwHome()."/.netrwbook"
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011076 if filereadable(s:NetrwFile(savefile))
Luca Saccarolac363ca12024-12-19 20:16:18 +010011077 " call Decho("merge bookmarks (active and file)",'~'.expand("<slnum>"))
11078 NetrwKeepj call s:NetrwBookHistSave()
11079 " call Decho("bookmark delete savefile<".savefile.">",'~'.expand("<slnum>"))
11080 NetrwKeepj call delete(savefile)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011081 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011082 " call Dret("s:MergeBookmarks")
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011083endfun
11084
11085" ---------------------------------------------------------------------
Bram Moolenaarc236c162008-07-13 17:41:49 +000011086" s:NetrwBMShow: {{{2
11087fun! s:NetrwBMShow()
Luca Saccarolac363ca12024-12-19 20:16:18 +010011088 " call Dfunc("s:NetrwBMShow()")
Bram Moolenaarc236c162008-07-13 17:41:49 +000011089 redir => bmshowraw
Luca Saccarolac363ca12024-12-19 20:16:18 +010011090 menu
Bram Moolenaarc236c162008-07-13 17:41:49 +000011091 redir END
11092 let bmshowlist = split(bmshowraw,'\n')
11093 if bmshowlist != []
Luca Saccarolac363ca12024-12-19 20:16:18 +010011094 let bmshowfuncs= filter(bmshowlist,'v:val =~# "<SNR>\\d\\+_BMShow()"')
11095 if bmshowfuncs != []
11096 let bmshowfunc = substitute(bmshowfuncs[0],'^.*:\(call.*BMShow()\).*$','\1','')
11097 if bmshowfunc =~# '^call.*BMShow()'
11098 exe "sil! NetrwKeepj ".bmshowfunc
11099 endif
Bram Moolenaarc236c162008-07-13 17:41:49 +000011100 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +000011101 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011102 " call Dret("s:NetrwBMShow : bmshowfunc<".(exists("bmshowfunc")? bmshowfunc : 'n/a').">")
Bram Moolenaarc236c162008-07-13 17:41:49 +000011103endfun
11104
11105" ---------------------------------------------------------------------
Bram Moolenaaradc21822011-04-01 18:03:16 +020011106" s:NetrwCursor: responsible for setting cursorline/cursorcolumn based upon g:netrw_cursor {{{2
Bram Moolenaar89a9c152021-08-29 21:55:35 +020011107fun! s:NetrwCursor(editfile)
Bram Moolenaar00a927d2010-05-14 23:24:24 +020011108 if !exists("w:netrw_liststyle")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011109 let w:netrw_liststyle= g:netrw_liststyle
Bram Moolenaar00a927d2010-05-14 23:24:24 +020011110 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011111 " 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 +020011112
Luca Saccarolac363ca12024-12-19 20:16:18 +010011113 " call Decho("(s:NetrwCursor) COMBAK: cuc=".&l:cuc." cul=".&l:cul)
Bram Moolenaar89a9c152021-08-29 21:55:35 +020011114
Bram Moolenaaradc21822011-04-01 18:03:16 +020011115 if &ft != "netrw"
shane.xb.qianc673b802024-12-20 19:36:40 +010011116 " if the current window isn't a netrw directory listing window, then use user cursorline/column
11117 " settings. Affects when netrw is used to read/write a file using scp/ftp/etc.
11118 " call Decho("case ft!=netrw: use user cul,cuc",'~'.expand("<slnum>"))
Bram Moolenaaradc21822011-04-01 18:03:16 +020011119
Bram Moolenaar89a9c152021-08-29 21:55:35 +020011120 elseif g:netrw_cursor == 8
Luca Saccarolac363ca12024-12-19 20:16:18 +010011121 if w:netrw_liststyle == s:WIDELIST
11122 setl cursorline
11123 setl cursorcolumn
11124 else
11125 setl cursorline
11126 endif
Bram Moolenaar89a9c152021-08-29 21:55:35 +020011127 elseif g:netrw_cursor == 7
11128 setl cursorline
11129 elseif g:netrw_cursor == 6
Luca Saccarolac363ca12024-12-19 20:16:18 +010011130 if w:netrw_liststyle == s:WIDELIST
11131 setl cursorline
11132 endif
Bram Moolenaaradc21822011-04-01 18:03:16 +020011133 elseif g:netrw_cursor == 4
Luca Saccarolac363ca12024-12-19 20:16:18 +010011134 " all styles: cursorline, cursorcolumn
11135 " call Decho("case g:netrw_cursor==4: setl cul cuc",'~'.expand("<slnum>"))
Bram Moolenaar15146672011-10-20 22:22:38 +020011136 setl cursorline
11137 setl cursorcolumn
Luca Saccarolac363ca12024-12-19 20:16:18 +010011138
11139 elseif g:netrw_cursor == 3
11140 " thin-long-tree: cursorline, user's cursorcolumn
11141 " wide : cursorline, cursorcolumn
11142 if w:netrw_liststyle == s:WIDELIST
11143 " call Decho("case g:netrw_cursor==3 and wide: setl cul cuc",'~'.expand("<slnum>"))
11144 setl cursorline
11145 setl cursorcolumn
11146 else
11147 " call Decho("case g:netrw_cursor==3 and not wide: setl cul (use user's cuc)",'~'.expand("<slnum>"))
11148 setl cursorline
11149 endif
Bram Moolenaaradc21822011-04-01 18:03:16 +020011150
11151 elseif g:netrw_cursor == 2
Luca Saccarolac363ca12024-12-19 20:16:18 +010011152 " thin-long-tree: cursorline, user's cursorcolumn
11153 " wide : cursorline, user's cursorcolumn
11154 " call Decho("case g:netrw_cursor==2: setl cuc (use user's cul)",'~'.expand("<slnum>"))
11155 setl cursorline
Bram Moolenaaradc21822011-04-01 18:03:16 +020011156
11157 elseif g:netrw_cursor == 1
Luca Saccarolac363ca12024-12-19 20:16:18 +010011158 " thin-long-tree: user's cursorline, user's cursorcolumn
11159 " wide : cursorline, user's cursorcolumn
11160 if w:netrw_liststyle == s:WIDELIST
11161 " call Decho("case g:netrw_cursor==2 and wide: setl cul (use user's cuc)",'~'.expand("<slnum>"))
11162 setl cursorline
11163 else
11164 " call Decho("case g:netrw_cursor==2 and not wide: (use user's cul,cuc)",'~'.expand("<slnum>"))
11165 endif
Bram Moolenaar00a927d2010-05-14 23:24:24 +020011166
11167 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010011168 " all styles: user's cursorline, user's cursorcolumn
11169 " call Decho("default: (use user's cul,cuc)",'~'.expand("<slnum>"))
11170 let &l:cursorline = s:netrw_usercul
11171 let &l:cursorcolumn = s:netrw_usercuc
Bram Moolenaar00a927d2010-05-14 23:24:24 +020011172 endif
Bram Moolenaaradc21822011-04-01 18:03:16 +020011173
Luca Saccarolac363ca12024-12-19 20:16:18 +010011174 " call Decho("(s:NetrwCursor) COMBAK: cuc=".&l:cuc." cul=".&l:cul)
11175 " call Dret("s:NetrwCursor : l:cursorline=".&l:cursorline." l:cursorcolumn=".&l:cursorcolumn)
Bram Moolenaar00a927d2010-05-14 23:24:24 +020011176endfun
11177
11178" ---------------------------------------------------------------------
11179" s:RestoreCursorline: restores cursorline/cursorcolumn to original user settings {{{2
11180fun! s:RestoreCursorline()
Luca Saccarolac363ca12024-12-19 20:16:18 +010011181 " call Dfunc("s:RestoreCursorline() currently, cul=".&l:cursorline." cuc=".&l:cursorcolumn." win#".winnr()." buf#".bufnr("%"))
Bram Moolenaaradc21822011-04-01 18:03:16 +020011182 if exists("s:netrw_usercul")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011183 let &l:cursorline = s:netrw_usercul
Bram Moolenaaradc21822011-04-01 18:03:16 +020011184 endif
11185 if exists("s:netrw_usercuc")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011186 let &l:cursorcolumn = s:netrw_usercuc
Bram Moolenaaradc21822011-04-01 18:03:16 +020011187 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011188 " call Decho("(s:RestoreCursorline) COMBAK: cuc=".&l:cuc." cul=".&l:cul)
11189 " call Dret("s:RestoreCursorline : restored cul=".&l:cursorline." cuc=".&l:cursorcolumn)
Bram Moolenaar00a927d2010-05-14 23:24:24 +020011190endfun
11191
Christian Brabandt62f7b552024-06-23 20:23:40 +020011192" s:RestoreRegister: restores all registers given in the dict {{{2
11193fun! s:RestoreRegister(dict)
11194 for [key, val] in items(a:dict)
11195 if key == 'unnamed'
11196 let key = ''
11197 endif
11198 call setreg(key, val[0], val[1])
11199 endfor
11200endfun
11201
Bram Moolenaar00a927d2010-05-14 23:24:24 +020011202" ---------------------------------------------------------------------
Bram Moolenaarc236c162008-07-13 17:41:49 +000011203" s:NetrwDelete: Deletes a file. {{{2
11204" Uses Steve Hall's idea to insure that Windows paths stay
11205" acceptable. No effect on Unix paths.
11206" Examples of use: let result= s:NetrwDelete(path)
11207fun! s:NetrwDelete(path)
Luca Saccarolac363ca12024-12-19 20:16:18 +010011208 " call Dfunc("s:NetrwDelete(path<".a:path.">)")
Bram Moolenaarc236c162008-07-13 17:41:49 +000011209
Bram Moolenaar5c736222010-01-06 20:54:52 +010011210 let path = netrw#WinPath(a:path)
Nir Lichtman1e34b952024-05-08 19:19:34 +020011211 if !g:netrw_cygwin && has("win32")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011212 if exists("+shellslash")
11213 let sskeep= &shellslash
11214 setl noshellslash
11215 let result = delete(path)
11216 let &shellslash = sskeep
11217 else
11218 " call Decho("exe let result= ".a:cmd."('".path."')",'~'.expand("<slnum>"))
11219 let result= delete(path)
11220 endif
Bram Moolenaarc236c162008-07-13 17:41:49 +000011221 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010011222 " call Decho("let result= delete(".path.")",'~'.expand("<slnum>"))
11223 let result= delete(path)
Bram Moolenaarc236c162008-07-13 17:41:49 +000011224 endif
11225 if result < 0
Luca Saccarolac363ca12024-12-19 20:16:18 +010011226 NetrwKeepj call netrw#ErrorMsg(s:WARNING,"delete(".path.") failed!",71)
Bram Moolenaarc236c162008-07-13 17:41:49 +000011227 endif
11228
Luca Saccarolac363ca12024-12-19 20:16:18 +010011229 " call Dret("s:NetrwDelete ".result)
Bram Moolenaarc236c162008-07-13 17:41:49 +000011230 return result
Bram Moolenaar446cb832008-06-24 21:56:24 +000011231endfun
11232
11233" ---------------------------------------------------------------------
Bram Moolenaar89a9c152021-08-29 21:55:35 +020011234" s:NetrwBufRemover: removes a buffer that: {{{2s
11235" has buffer-id > 1
11236" is unlisted
11237" is unnamed
11238" does not appear in any window
11239fun! s:NetrwBufRemover(bufid)
Luca Saccarolac363ca12024-12-19 20:16:18 +010011240 " call Dfunc("s:NetrwBufRemover(".a:bufid.")")
11241 " call Decho("buf#".a:bufid." ".((a:bufid > 1)? ">" : "≯")." must be >1 for removal","~".expand("<slnum>"))
11242 " call Decho("buf#".a:bufid." is ".(buflisted(a:bufid)? "listed" : "unlisted"),"~".expand("<slnum>"))
11243 " call Decho("buf#".a:bufid." has name <".bufname(a:bufid).">","~".expand("<slnum>"))
11244 " call Decho("buf#".a:bufid." has winid#".bufwinid(a:bufid),"~".expand("<slnum>"))
Bram Moolenaar89a9c152021-08-29 21:55:35 +020011245
yasuda4dbb2662023-10-04 20:50:35 +020011246 if a:bufid > 1 && !buflisted(a:bufid) && bufloaded(a:bufid) && bufname(a:bufid) == "" && bufwinid(a:bufid) == -1
Luca Saccarolac363ca12024-12-19 20:16:18 +010011247 " call Decho("(s:NetrwBufRemover) removing buffer#".a:bufid,"~".expand("<slnum>"))
11248 exe "sil! bd! ".a:bufid
Bram Moolenaar89a9c152021-08-29 21:55:35 +020011249 endif
11250
Luca Saccarolac363ca12024-12-19 20:16:18 +010011251 " call Dret("s:NetrwBufRemover")
Bram Moolenaar89a9c152021-08-29 21:55:35 +020011252endfun
11253
11254" ---------------------------------------------------------------------
Bram Moolenaar9964e462007-05-05 17:54:07 +000011255" s:NetrwEnew: opens a new buffer, passes netrw buffer variables through {{{2
Bram Moolenaar5c736222010-01-06 20:54:52 +010011256fun! s:NetrwEnew(...)
Luca Saccarolac363ca12024-12-19 20:16:18 +010011257 " call Dfunc("s:NetrwEnew() a:0=".a:0." win#".winnr()." winnr($)=".winnr("$")." bufnr($)=".bufnr("$")." expand(%)<".expand("%").">")
11258 " call Decho("curdir<".((a:0>0)? a:1 : "")."> buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
Bram Moolenaar9964e462007-05-05 17:54:07 +000011259
Christian Brabandt8b0fa7a2024-10-31 09:21:23 +010011260 " Clean out the last buffer:
Bram Moolenaar89a9c152021-08-29 21:55:35 +020011261 " Check if the last buffer has # > 1, is unlisted, is unnamed, and does not appear in a window
11262 " If so, delete it.
11263 call s:NetrwBufRemover(bufnr("$"))
11264
Bram Moolenaar446cb832008-06-24 21:56:24 +000011265 " grab a function-local-variable copy of buffer variables
Luca Saccarolac363ca12024-12-19 20:16:18 +010011266 " call Decho("make function-local copy of netrw variables",'~'.expand("<slnum>"))
Bram Moolenaar9964e462007-05-05 17:54:07 +000011267 if exists("b:netrw_bannercnt") |let netrw_bannercnt = b:netrw_bannercnt |endif
11268 if exists("b:netrw_browser_active") |let netrw_browser_active = b:netrw_browser_active |endif
11269 if exists("b:netrw_cpf") |let netrw_cpf = b:netrw_cpf |endif
11270 if exists("b:netrw_curdir") |let netrw_curdir = b:netrw_curdir |endif
11271 if exists("b:netrw_explore_bufnr") |let netrw_explore_bufnr = b:netrw_explore_bufnr |endif
11272 if exists("b:netrw_explore_indx") |let netrw_explore_indx = b:netrw_explore_indx |endif
11273 if exists("b:netrw_explore_line") |let netrw_explore_line = b:netrw_explore_line |endif
11274 if exists("b:netrw_explore_list") |let netrw_explore_list = b:netrw_explore_list |endif
11275 if exists("b:netrw_explore_listlen")|let netrw_explore_listlen = b:netrw_explore_listlen|endif
11276 if exists("b:netrw_explore_mtchcnt")|let netrw_explore_mtchcnt = b:netrw_explore_mtchcnt|endif
11277 if exists("b:netrw_fname") |let netrw_fname = b:netrw_fname |endif
11278 if exists("b:netrw_lastfile") |let netrw_lastfile = b:netrw_lastfile |endif
11279 if exists("b:netrw_liststyle") |let netrw_liststyle = b:netrw_liststyle |endif
11280 if exists("b:netrw_method") |let netrw_method = b:netrw_method |endif
11281 if exists("b:netrw_option") |let netrw_option = b:netrw_option |endif
11282 if exists("b:netrw_prvdir") |let netrw_prvdir = b:netrw_prvdir |endif
11283
Bram Moolenaar85850f32019-07-19 22:05:51 +020011284 NetrwKeepj call s:NetrwOptionsRestore("w:")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011285 " call Decho("generate a buffer with NetrwKeepj enew!",'~'.expand("<slnum>"))
Bram Moolenaare0fa3742016-02-20 15:47:01 +010011286 " when tree listing uses file TreeListing... a new buffer is made.
11287 " Want the old buffer to be unlisted.
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +020011288 " COMBAK: this causes a problem, see P43
Luca Saccarolac363ca12024-12-19 20:16:18 +010011289 " setl nobl
Bram Moolenaar5ac3b1a2010-07-27 22:50:36 +020011290 let netrw_keepdiff= &l:diff
Bram Moolenaar71badf92023-04-22 22:40:14 +010011291 call s:NetrwEditFile("enew!","","")
Bram Moolenaar5ac3b1a2010-07-27 22:50:36 +020011292 let &l:diff= netrw_keepdiff
Luca Saccarolac363ca12024-12-19 20:16:18 +010011293 " call Decho("bufnr($)=".bufnr("$")."<".bufname(bufnr("$"))."> winnr($)=".winnr("$"),'~'.expand("<slnum>"))
Bram Moolenaar85850f32019-07-19 22:05:51 +020011294 NetrwKeepj call s:NetrwOptionsSave("w:")
Bram Moolenaar9964e462007-05-05 17:54:07 +000011295
Bram Moolenaar446cb832008-06-24 21:56:24 +000011296 " copy function-local-variables to buffer variable equivalents
Luca Saccarolac363ca12024-12-19 20:16:18 +010011297 " call Decho("copy function-local variables back to buffer netrw variables",'~'.expand("<slnum>"))
Bram Moolenaar9964e462007-05-05 17:54:07 +000011298 if exists("netrw_bannercnt") |let b:netrw_bannercnt = netrw_bannercnt |endif
11299 if exists("netrw_browser_active") |let b:netrw_browser_active = netrw_browser_active |endif
11300 if exists("netrw_cpf") |let b:netrw_cpf = netrw_cpf |endif
11301 if exists("netrw_curdir") |let b:netrw_curdir = netrw_curdir |endif
11302 if exists("netrw_explore_bufnr") |let b:netrw_explore_bufnr = netrw_explore_bufnr |endif
11303 if exists("netrw_explore_indx") |let b:netrw_explore_indx = netrw_explore_indx |endif
11304 if exists("netrw_explore_line") |let b:netrw_explore_line = netrw_explore_line |endif
11305 if exists("netrw_explore_list") |let b:netrw_explore_list = netrw_explore_list |endif
11306 if exists("netrw_explore_listlen")|let b:netrw_explore_listlen = netrw_explore_listlen|endif
11307 if exists("netrw_explore_mtchcnt")|let b:netrw_explore_mtchcnt = netrw_explore_mtchcnt|endif
11308 if exists("netrw_fname") |let b:netrw_fname = netrw_fname |endif
11309 if exists("netrw_lastfile") |let b:netrw_lastfile = netrw_lastfile |endif
11310 if exists("netrw_liststyle") |let b:netrw_liststyle = netrw_liststyle |endif
11311 if exists("netrw_method") |let b:netrw_method = netrw_method |endif
11312 if exists("netrw_option") |let b:netrw_option = netrw_option |endif
11313 if exists("netrw_prvdir") |let b:netrw_prvdir = netrw_prvdir |endif
11314
Bram Moolenaar5c736222010-01-06 20:54:52 +010011315 if a:0 > 0
Luca Saccarolac363ca12024-12-19 20:16:18 +010011316 let b:netrw_curdir= a:1
11317 if b:netrw_curdir =~ '/$'
11318 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
11319 setl nobl
11320 file NetrwTreeListing
11321 setl nobl bt=nowrite bh=hide
11322 nno <silent> <buffer> [ :sil call <SID>TreeListMove('[')<cr>
11323 nno <silent> <buffer> ] :sil call <SID>TreeListMove(']')<cr>
11324 else
11325 call s:NetrwBufRename(b:netrw_curdir)
11326 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +010011327 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +000011328 endif
Bram Moolenaar1d59aa12020-09-19 18:50:13 +020011329 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 +010011330 let &l:bexpr = "netrw#BalloonHelp()"
Bram Moolenaar1d59aa12020-09-19 18:50:13 +020011331 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +000011332
Luca Saccarolac363ca12024-12-19 20:16:18 +010011333 " call Dret("s:NetrwEnew : buf#".bufnr("%")."<".bufname("%")."> expand(%)<".expand("%")."> expand(#)<".expand("#")."> bh=".&bh." win#".winnr()." winnr($)#".winnr("$"))
Bram Moolenaar9964e462007-05-05 17:54:07 +000011334endfun
11335
Bram Moolenaar5b435d62012-04-05 17:33:26 +020011336" ---------------------------------------------------------------------
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011337" s:NetrwExe: executes a string using "!" {{{2
11338fun! s:NetrwExe(cmd)
GuyBrushd7745ac2024-11-23 14:13:10 +010011339 if has("win32") && exepath(&shell) !~? '\v[\/]?(cmd|pwsh|powershell)(\.exe)?$' && !g:netrw_cygwin
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011340 let savedShell=[&shell,&shellcmdflag,&shellxquote,&shellxescape,&shellquote,&shellpipe,&shellredir,&shellslash]
11341 set shell& shellcmdflag& shellxquote& shellxescape&
11342 set shellquote& shellpipe& shellredir& shellslash&
Konfekt3d7e5672024-10-27 22:16:49 +010011343 try
Luca Saccarolac363ca12024-12-19 20:16:18 +010011344 exe a:cmd
Konfekt3d7e5672024-10-27 22:16:49 +010011345 finally
11346 let [&shell,&shellcmdflag,&shellxquote,&shellxescape,&shellquote,&shellpipe,&shellredir,&shellslash] = savedShell
11347 endtry
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011348 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010011349 exe a:cmd
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011350 endif
Bram Moolenaar29634562020-01-09 21:46:04 +010011351 if v:shell_error
Luca Saccarolac363ca12024-12-19 20:16:18 +010011352 call netrw#ErrorMsg(s:WARNING,"shell signalled an error",106)
Bram Moolenaar29634562020-01-09 21:46:04 +010011353 endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011354endfun
11355
11356" ---------------------------------------------------------------------
Bram Moolenaar5b435d62012-04-05 17:33:26 +020011357" s:NetrwInsureWinVars: insure that a netrw buffer has its w: variables in spite of a wincmd v or s {{{2
11358fun! s:NetrwInsureWinVars()
Bram Moolenaar5b435d62012-04-05 17:33:26 +020011359 if !exists("w:netrw_liststyle")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011360 " call Dfunc("s:NetrwInsureWinVars() win#".winnr())
11361 let curbuf = bufnr("%")
11362 let curwin = winnr()
11363 let iwin = 1
11364 while iwin <= winnr("$")
11365 exe iwin."wincmd w"
11366 if winnr() != curwin && bufnr("%") == curbuf && exists("w:netrw_liststyle")
11367 " looks like ctrl-w_s or ctrl-w_v was used to split a netrw buffer
11368 let winvars= w:
11369 break
11370 endif
11371 let iwin= iwin + 1
11372 endwhile
11373 exe "keepalt ".curwin."wincmd w"
11374 if exists("winvars")
11375 " call Decho("copying w#".iwin." window variables to w#".curwin,'~'.expand("<slnum>"))
11376 for k in keys(winvars)
11377 let w:{k}= winvars[k]
11378 endfor
Bram Moolenaar5b435d62012-04-05 17:33:26 +020011379 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011380 " call Dret("s:NetrwInsureWinVars win#".winnr())
Bram Moolenaar5b435d62012-04-05 17:33:26 +020011381 endif
Bram Moolenaar5b435d62012-04-05 17:33:26 +020011382endfun
11383
Bram Moolenaara6878372014-03-22 21:02:50 +010011384" ---------------------------------------------------------------------
11385" s:NetrwLcd: handles changing the (local) directory {{{2
Bram Moolenaar85850f32019-07-19 22:05:51 +020011386" Returns: 0=success
11387" -1=failed
Bram Moolenaara6878372014-03-22 21:02:50 +010011388fun! s:NetrwLcd(newdir)
Luca Saccarolac363ca12024-12-19 20:16:18 +010011389 " call Dfunc("s:NetrwLcd(newdir<".a:newdir.">)")
11390 " call Decho("changing local directory",'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +010011391
Bram Moolenaar85850f32019-07-19 22:05:51 +020011392 let err472= 0
Bram Moolenaara6878372014-03-22 21:02:50 +010011393 try
Luca Saccarolac363ca12024-12-19 20:16:18 +010011394 exe 'NetrwKeepj sil lcd '.fnameescape(a:newdir)
Bram Moolenaara6878372014-03-22 21:02:50 +010011395 catch /^Vim\%((\a\+)\)\=:E344/
Luca Saccarolac363ca12024-12-19 20:16:18 +010011396 " Vim's lcd fails with E344 when attempting to go above the 'root' of a Windows share.
11397 " Therefore, detect if a Windows share is present, and if E344 occurs, just settle at
11398 " 'root' (ie. '\'). The share name may start with either backslashes ('\\Foo') or
11399 " forward slashes ('//Foo'), depending on whether backslashes have been converted to
11400 " forward slashes by earlier code; so check for both.
11401 if has("win32") && !g:netrw_cygwin
11402 if a:newdir =~ '^\\\\\w\+' || a:newdir =~ '^//\w\+'
11403 let dirname = '\'
11404 exe 'NetrwKeepj sil lcd '.fnameescape(dirname)
11405 endif
11406 endif
Bram Moolenaara6878372014-03-22 21:02:50 +010011407 catch /^Vim\%((\a\+)\)\=:E472/
Luca Saccarolac363ca12024-12-19 20:16:18 +010011408 let err472= 1
Bram Moolenaar85850f32019-07-19 22:05:51 +020011409 endtry
11410
11411 if err472
Luca Saccarolac363ca12024-12-19 20:16:18 +010011412 call netrw#ErrorMsg(s:ERROR,"unable to change directory to <".a:newdir."> (permissions?)",61)
11413 if exists("w:netrw_prvdir")
11414 let a:newdir= w:netrw_prvdir
11415 else
11416 call s:NetrwOptionsRestore("w:")
11417 " call Decho("setl noma nomod nowrap",'~'.expand("<slnum>"))
11418 exe "setl ".g:netrw_bufsettings
11419 " call Decho(" ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
11420 let a:newdir= dirname
11421 endif
11422 " call Dret("s:NetrwBrowse -1 : reusing buffer#".(exists("bufnum")? bufnum : 'N/A')."<".dirname."> getcwd<".getcwd().">")
11423 return -1
Bram Moolenaar85850f32019-07-19 22:05:51 +020011424 endif
Bram Moolenaara6878372014-03-22 21:02:50 +010011425
Luca Saccarolac363ca12024-12-19 20:16:18 +010011426 " call Decho("getcwd <".getcwd().">")
11427 " call Decho("b:netrw_curdir<".b:netrw_curdir.">")
11428 " call Dret("s:NetrwLcd 0")
Bram Moolenaar85850f32019-07-19 22:05:51 +020011429 return 0
Bram Moolenaara6878372014-03-22 21:02:50 +010011430endfun
11431
Bram Moolenaar9964e462007-05-05 17:54:07 +000011432" ------------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +000011433" s:NetrwSaveWordPosn: used to keep cursor on same word after refresh, {{{2
11434" changed sorting, etc. Also see s:NetrwRestoreWordPosn().
11435fun! s:NetrwSaveWordPosn()
Luca Saccarolac363ca12024-12-19 20:16:18 +010011436 " call Dfunc("NetrwSaveWordPosn()")
Bram Moolenaar446cb832008-06-24 21:56:24 +000011437 let s:netrw_saveword= '^'.fnameescape(getline('.')).'$'
Luca Saccarolac363ca12024-12-19 20:16:18 +010011438 " call Dret("NetrwSaveWordPosn : saveword<".s:netrw_saveword.">")
Bram Moolenaar446cb832008-06-24 21:56:24 +000011439endfun
11440
11441" ---------------------------------------------------------------------
Bram Moolenaare0fa3742016-02-20 15:47:01 +010011442" s:NetrwHumanReadable: takes a number and makes it "human readable" {{{2
11443" 1000 -> 1K, 1000000 -> 1M, 1000000000 -> 1G
11444fun! s:NetrwHumanReadable(sz)
Luca Saccarolac363ca12024-12-19 20:16:18 +010011445 " call Dfunc("s:NetrwHumanReadable(sz=".a:sz.") type=".type(a:sz)." style=".g:netrw_sizestyle )
Bram Moolenaare0fa3742016-02-20 15:47:01 +010011446
11447 if g:netrw_sizestyle == 'h'
Luca Saccarolac363ca12024-12-19 20:16:18 +010011448 if a:sz >= 1000000000
11449 let sz = printf("%.1f",a:sz/1000000000.0)."g"
11450 elseif a:sz >= 10000000
11451 let sz = printf("%d",a:sz/1000000)."m"
11452 elseif a:sz >= 1000000
11453 let sz = printf("%.1f",a:sz/1000000.0)."m"
11454 elseif a:sz >= 10000
11455 let sz = printf("%d",a:sz/1000)."k"
11456 elseif a:sz >= 1000
11457 let sz = printf("%.1f",a:sz/1000.0)."k"
11458 else
11459 let sz= a:sz
11460 endif
Bram Moolenaare0fa3742016-02-20 15:47:01 +010011461
11462 elseif g:netrw_sizestyle == 'H'
Luca Saccarolac363ca12024-12-19 20:16:18 +010011463 if a:sz >= 1073741824
11464 let sz = printf("%.1f",a:sz/1073741824.0)."G"
11465 elseif a:sz >= 10485760
11466 let sz = printf("%d",a:sz/1048576)."M"
11467 elseif a:sz >= 1048576
11468 let sz = printf("%.1f",a:sz/1048576.0)."M"
11469 elseif a:sz >= 10240
11470 let sz = printf("%d",a:sz/1024)."K"
11471 elseif a:sz >= 1024
11472 let sz = printf("%.1f",a:sz/1024.0)."K"
11473 else
11474 let sz= a:sz
11475 endif
Bram Moolenaare0fa3742016-02-20 15:47:01 +010011476
11477 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010011478 let sz= a:sz
Bram Moolenaare0fa3742016-02-20 15:47:01 +010011479 endif
11480
Luca Saccarolac363ca12024-12-19 20:16:18 +010011481 " call Dret("s:NetrwHumanReadable ".sz)
Bram Moolenaare0fa3742016-02-20 15:47:01 +010011482 return sz
11483endfun
11484
11485" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +000011486" s:NetrwRestoreWordPosn: used to keep cursor on same word after refresh, {{{2
11487" changed sorting, etc. Also see s:NetrwSaveWordPosn().
11488fun! s:NetrwRestoreWordPosn()
Luca Saccarolac363ca12024-12-19 20:16:18 +010011489 " call Dfunc("NetrwRestoreWordPosn()")
Bram Moolenaaradc21822011-04-01 18:03:16 +020011490 sil! call search(s:netrw_saveword,'w')
Luca Saccarolac363ca12024-12-19 20:16:18 +010011491 " call Dret("NetrwRestoreWordPosn")
Bram Moolenaar446cb832008-06-24 21:56:24 +000011492endfun
11493
11494" ---------------------------------------------------------------------
Bram Moolenaarc236c162008-07-13 17:41:49 +000011495" s:RestoreBufVars: {{{2
11496fun! s:RestoreBufVars()
Luca Saccarolac363ca12024-12-19 20:16:18 +010011497 " call Dfunc("s:RestoreBufVars()")
Bram Moolenaarc236c162008-07-13 17:41:49 +000011498
11499 if exists("s:netrw_curdir") |let b:netrw_curdir = s:netrw_curdir |endif
11500 if exists("s:netrw_lastfile") |let b:netrw_lastfile = s:netrw_lastfile |endif
11501 if exists("s:netrw_method") |let b:netrw_method = s:netrw_method |endif
11502 if exists("s:netrw_fname") |let b:netrw_fname = s:netrw_fname |endif
11503 if exists("s:netrw_machine") |let b:netrw_machine = s:netrw_machine |endif
11504 if exists("s:netrw_browser_active")|let b:netrw_browser_active = s:netrw_browser_active|endif
11505
Luca Saccarolac363ca12024-12-19 20:16:18 +010011506 " call Dret("s:RestoreBufVars")
Bram Moolenaarc236c162008-07-13 17:41:49 +000011507endfun
11508
11509" ---------------------------------------------------------------------
Bram Moolenaar9964e462007-05-05 17:54:07 +000011510" s:RemotePathAnalysis: {{{2
11511fun! s:RemotePathAnalysis(dirname)
Luca Saccarolac363ca12024-12-19 20:16:18 +010011512 " call Dfunc("s:RemotePathAnalysis(a:dirname<".a:dirname.">)")
Bram Moolenaar9964e462007-05-05 17:54:07 +000011513
Bram Moolenaara6878372014-03-22 21:02:50 +010011514 " method :// user @ machine :port /path
Bram Moolenaar8d043172014-01-23 14:24:41 +010011515 let dirpat = '^\(\w\{-}\)://\(\(\w\+\)@\)\=\([^/:#]\+\)\%([:#]\(\d\+\)\)\=/\(.*\)$'
Bram Moolenaar9964e462007-05-05 17:54:07 +000011516 let s:method = substitute(a:dirname,dirpat,'\1','')
Bram Moolenaar8d043172014-01-23 14:24:41 +010011517 let s:user = substitute(a:dirname,dirpat,'\3','')
11518 let s:machine = substitute(a:dirname,dirpat,'\4','')
11519 let s:port = substitute(a:dirname,dirpat,'\5','')
11520 let s:path = substitute(a:dirname,dirpat,'\6','')
Bram Moolenaar13600302014-05-22 18:26:40 +020011521 let s:fname = substitute(s:path,'^.*/\ze.','','')
Bram Moolenaara6878372014-03-22 21:02:50 +010011522 if s:machine =~ '@'
Luca Saccarolac363ca12024-12-19 20:16:18 +010011523 let dirpat = '^\(.*\)@\(.\{-}\)$'
11524 let s:user = s:user.'@'.substitute(s:machine,dirpat,'\1','')
11525 let s:machine = substitute(s:machine,dirpat,'\2','')
Bram Moolenaara6878372014-03-22 21:02:50 +010011526 endif
Bram Moolenaar9964e462007-05-05 17:54:07 +000011527
Luca Saccarolac363ca12024-12-19 20:16:18 +010011528 " call Decho("set up s:method <".s:method .">",'~'.expand("<slnum>"))
11529 " call Decho("set up s:user <".s:user .">",'~'.expand("<slnum>"))
11530 " call Decho("set up s:machine<".s:machine.">",'~'.expand("<slnum>"))
11531 " call Decho("set up s:port <".s:port.">",'~'.expand("<slnum>"))
11532 " call Decho("set up s:path <".s:path .">",'~'.expand("<slnum>"))
11533 " call Decho("set up s:fname <".s:fname .">",'~'.expand("<slnum>"))
Bram Moolenaar9964e462007-05-05 17:54:07 +000011534
Luca Saccarolac363ca12024-12-19 20:16:18 +010011535 " call Dret("s:RemotePathAnalysis")
Bram Moolenaar9964e462007-05-05 17:54:07 +000011536endfun
11537
11538" ---------------------------------------------------------------------
Bram Moolenaarc236c162008-07-13 17:41:49 +000011539" s:RemoteSystem: runs a command on a remote host using ssh {{{2
11540" Returns status
11541" Runs system() on
11542" [cd REMOTEDIRPATH;] a:cmd
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011543" Note that it doesn't do s:ShellEscape(a:cmd)!
Bram Moolenaarc236c162008-07-13 17:41:49 +000011544fun! s:RemoteSystem(cmd)
Luca Saccarolac363ca12024-12-19 20:16:18 +010011545 " call Dfunc("s:RemoteSystem(cmd<".a:cmd.">)")
Bram Moolenaarc236c162008-07-13 17:41:49 +000011546 if !executable(g:netrw_ssh_cmd)
Luca Saccarolac363ca12024-12-19 20:16:18 +010011547 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 +000011548 elseif !exists("b:netrw_curdir")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011549 NetrwKeepj call netrw#ErrorMsg(s:ERROR,"for some reason b:netrw_curdir doesn't exist!",53)
Bram Moolenaarc236c162008-07-13 17:41:49 +000011550 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010011551 let cmd = s:MakeSshCmd(g:netrw_ssh_cmd." USEPORT HOSTNAME")
11552 let remotedir= substitute(b:netrw_curdir,'^.*//[^/]\+/\(.*\)$','\1','')
11553 if remotedir != ""
11554 let cmd= cmd.' cd '.s:ShellEscape(remotedir).";"
11555 else
11556 let cmd= cmd.' '
11557 endif
11558 let cmd= cmd.a:cmd
11559 " call Decho("call system(".cmd.")",'~'.expand("<slnum>"))
11560 let ret= system(cmd)
Bram Moolenaarc236c162008-07-13 17:41:49 +000011561 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011562 " call Dret("s:RemoteSystem ".ret)
Bram Moolenaarc236c162008-07-13 17:41:49 +000011563 return ret
Bram Moolenaar9964e462007-05-05 17:54:07 +000011564endfun
11565
11566" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +000011567" s:RestoreWinVars: (used by Explore() and NetrwSplit()) {{{2
Bram Moolenaar9964e462007-05-05 17:54:07 +000011568fun! s:RestoreWinVars()
Luca Saccarolac363ca12024-12-19 20:16:18 +010011569 " call Dfunc("s:RestoreWinVars()")
Bram Moolenaar488c6512005-08-11 20:09:58 +000011570 if exists("s:bannercnt") |let w:netrw_bannercnt = s:bannercnt |unlet s:bannercnt |endif
Bram Moolenaar9964e462007-05-05 17:54:07 +000011571 if exists("s:col") |let w:netrw_col = s:col |unlet s:col |endif
11572 if exists("s:curdir") |let w:netrw_curdir = s:curdir |unlet s:curdir |endif
11573 if exists("s:explore_bufnr") |let w:netrw_explore_bufnr = s:explore_bufnr |unlet s:explore_bufnr |endif
11574 if exists("s:explore_indx") |let w:netrw_explore_indx = s:explore_indx |unlet s:explore_indx |endif
11575 if exists("s:explore_line") |let w:netrw_explore_line = s:explore_line |unlet s:explore_line |endif
11576 if exists("s:explore_listlen")|let w:netrw_explore_listlen = s:explore_listlen|unlet s:explore_listlen|endif
11577 if exists("s:explore_list") |let w:netrw_explore_list = s:explore_list |unlet s:explore_list |endif
11578 if exists("s:explore_mtchcnt")|let w:netrw_explore_mtchcnt = s:explore_mtchcnt|unlet s:explore_mtchcnt|endif
11579 if exists("s:fpl") |let w:netrw_fpl = s:fpl |unlet s:fpl |endif
11580 if exists("s:hline") |let w:netrw_hline = s:hline |unlet s:hline |endif
11581 if exists("s:line") |let w:netrw_line = s:line |unlet s:line |endif
11582 if exists("s:liststyle") |let w:netrw_liststyle = s:liststyle |unlet s:liststyle |endif
Bram Moolenaar488c6512005-08-11 20:09:58 +000011583 if exists("s:method") |let w:netrw_method = s:method |unlet s:method |endif
11584 if exists("s:prvdir") |let w:netrw_prvdir = s:prvdir |unlet s:prvdir |endif
Bram Moolenaar9964e462007-05-05 17:54:07 +000011585 if exists("s:treedict") |let w:netrw_treedict = s:treedict |unlet s:treedict |endif
11586 if exists("s:treetop") |let w:netrw_treetop = s:treetop |unlet s:treetop |endif
11587 if exists("s:winnr") |let w:netrw_winnr = s:winnr |unlet s:winnr |endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011588 " call Dret("s:RestoreWinVars")
Bram Moolenaar488c6512005-08-11 20:09:58 +000011589endfun
11590
Bram Moolenaar90cfdbe2005-08-12 19:59:19 +000011591" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +000011592" s:Rexplore: implements returning from a buffer to a netrw directory {{{2
11593"
11594" s:SetRexDir() sets up <2-leftmouse> maps (if g:netrw_retmap
11595" is true) and a command, :Rexplore, which call this function.
11596"
Bram Moolenaar85850f32019-07-19 22:05:51 +020011597" s:netrw_posn is set up by s:NetrwBrowseChgDir()
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011598"
11599" s:rexposn_BUFNR used to save/restore cursor position
Bram Moolenaar446cb832008-06-24 21:56:24 +000011600fun! s:NetrwRexplore(islocal,dirname)
Bram Moolenaarff034192013-04-24 18:51:19 +020011601 if exists("s:netrwdrag")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011602 return
Bram Moolenaarff034192013-04-24 18:51:19 +020011603 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011604 " call Dfunc("s:NetrwRexplore() w:netrw_rexlocal=".w:netrw_rexlocal." w:netrw_rexdir<".w:netrw_rexdir."> win#".winnr())
11605 " call Decho("currently in bufname<".bufname("%").">",'~'.expand("<slnum>"))
11606 " 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 +010011607
11608 if &ft == "netrw" && exists("w:netrw_rexfile") && w:netrw_rexfile != ""
Luca Saccarolac363ca12024-12-19 20:16:18 +010011609 " a :Rex while in a netrw buffer means: edit the file in w:netrw_rexfile
11610 " call Decho("in netrw buffer, will edit file<".w:netrw_rexfile.">",'~'.expand("<slnum>"))
11611 exe "NetrwKeepj e ".w:netrw_rexfile
11612 unlet w:netrw_rexfile
11613 " call Dret("s:NetrwRexplore returning from netrw to buf#".bufnr("%")."<".bufname("%")."> (ft=".&ft.")")
11614 return
11615 " else " Decho
11616 " call Decho("treating as not-netrw-buffer: ft=".&ft.((&ft == "netrw")? " == netrw" : "!= netrw"),'~'.expand("<slnum>"))
11617 " 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 +020011618 endif
Bram Moolenaara6878372014-03-22 21:02:50 +010011619
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011620 " ---------------------------
11621 " :Rex issued while in a file
11622 " ---------------------------
11623
Bram Moolenaara6878372014-03-22 21:02:50 +010011624 " record current file so :Rex can return to it from netrw
11625 let w:netrw_rexfile= expand("%")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011626 " call Decho("set w:netrw_rexfile<".w:netrw_rexfile."> (win#".winnr().")",'~'.expand("<slnum>"))
Bram Moolenaara6878372014-03-22 21:02:50 +010011627
11628 if !exists("w:netrw_rexlocal")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011629 " call Dret("s:NetrwRexplore w:netrw_rexlocal doesn't exist (".&ft." win#".winnr().")")
11630 return
Bram Moolenaara6878372014-03-22 21:02:50 +010011631 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011632 " 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 +020011633 if w:netrw_rexlocal
Luca Saccarolac363ca12024-12-19 20:16:18 +010011634 NetrwKeepj call netrw#LocalBrowseCheck(w:netrw_rexdir)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011635 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010011636 NetrwKeepj call s:NetrwBrowse(0,w:netrw_rexdir)
Bram Moolenaar446cb832008-06-24 21:56:24 +000011637 endif
Bram Moolenaar15146672011-10-20 22:22:38 +020011638 if exists("s:initbeval")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011639 setl beval
Bram Moolenaar15146672011-10-20 22:22:38 +020011640 endif
Bram Moolenaar5b435d62012-04-05 17:33:26 +020011641 if exists("s:rexposn_".bufnr("%"))
Luca Saccarolac363ca12024-12-19 20:16:18 +010011642 " call Decho("restore posn, then unlet s:rexposn_".bufnr('%')."<".bufname("%").">",'~'.expand("<slnum>"))
11643 " restore position in directory listing
11644 " call Decho("restoring posn to s:rexposn_".bufnr('%')."<".string(s:rexposn_{bufnr('%')}).">",'~'.expand("<slnum>"))
11645 NetrwKeepj call winrestview(s:rexposn_{bufnr('%')})
11646 if exists("s:rexposn_".bufnr('%'))
11647 unlet s:rexposn_{bufnr('%')}
11648 endif
Bram Moolenaar5b435d62012-04-05 17:33:26 +020011649 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010011650 " call Decho("s:rexposn_".bufnr('%')."<".bufname("%")."> doesn't exist",'~'.expand("<slnum>"))
Bram Moolenaar446cb832008-06-24 21:56:24 +000011651 endif
Bram Moolenaara6878372014-03-22 21:02:50 +010011652
Bram Moolenaar85850f32019-07-19 22:05:51 +020011653 if has("syntax") && exists("g:syntax_on") && g:syntax_on
Luca Saccarolac363ca12024-12-19 20:16:18 +010011654 if exists("s:explore_match")
11655 exe "2match netrwMarkFile /".s:explore_match."/"
11656 endif
Bram Moolenaar5c736222010-01-06 20:54:52 +010011657 endif
Bram Moolenaara6878372014-03-22 21:02:50 +010011658
Luca Saccarolac363ca12024-12-19 20:16:18 +010011659 " 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>"))
11660 " call Dret("s:NetrwRexplore : ft=".&ft)
Bram Moolenaar446cb832008-06-24 21:56:24 +000011661endfun
11662
11663" ---------------------------------------------------------------------
Bram Moolenaar8d043172014-01-23 14:24:41 +010011664" s:SaveBufVars: save selected b: variables to s: variables {{{2
11665" use s:RestoreBufVars() to restore b: variables from s: variables
Bram Moolenaar9964e462007-05-05 17:54:07 +000011666fun! s:SaveBufVars()
Luca Saccarolac363ca12024-12-19 20:16:18 +010011667 " call Dfunc("s:SaveBufVars() buf#".bufnr("%"))
Bram Moolenaar9964e462007-05-05 17:54:07 +000011668
11669 if exists("b:netrw_curdir") |let s:netrw_curdir = b:netrw_curdir |endif
11670 if exists("b:netrw_lastfile") |let s:netrw_lastfile = b:netrw_lastfile |endif
11671 if exists("b:netrw_method") |let s:netrw_method = b:netrw_method |endif
11672 if exists("b:netrw_fname") |let s:netrw_fname = b:netrw_fname |endif
11673 if exists("b:netrw_machine") |let s:netrw_machine = b:netrw_machine |endif
11674 if exists("b:netrw_browser_active")|let s:netrw_browser_active = b:netrw_browser_active|endif
11675
Luca Saccarolac363ca12024-12-19 20:16:18 +010011676 " call Dret("s:SaveBufVars")
Bram Moolenaar9964e462007-05-05 17:54:07 +000011677endfun
11678
11679" ---------------------------------------------------------------------
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +020011680" s:SavePosn: saves position associated with current buffer into a dictionary {{{2
11681fun! s:SavePosn(posndict)
Luca Saccarolac363ca12024-12-19 20:16:18 +010011682 " call Dfunc("s:SavePosn(posndict) curbuf#".bufnr("%")."<".bufname("%").">")
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +020011683
Bram Moolenaar85850f32019-07-19 22:05:51 +020011684 if !exists("a:posndict[bufnr('%')]")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011685 let a:posndict[bufnr("%")]= []
Bram Moolenaar85850f32019-07-19 22:05:51 +020011686 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011687 " call Decho("before push: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')]))
Bram Moolenaar85850f32019-07-19 22:05:51 +020011688 call add(a:posndict[bufnr("%")],winsaveview())
Luca Saccarolac363ca12024-12-19 20:16:18 +010011689 " call Decho("after push: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')]))
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +020011690
Luca Saccarolac363ca12024-12-19 20:16:18 +010011691 " call Dret("s:SavePosn posndict")
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +020011692 return a:posndict
11693endfun
11694
11695" ---------------------------------------------------------------------
11696" s:RestorePosn: restores position associated with current buffer using dictionary {{{2
11697fun! s:RestorePosn(posndict)
Luca Saccarolac363ca12024-12-19 20:16:18 +010011698 " call Dfunc("s:RestorePosn(posndict) curbuf#".bufnr("%")."<".bufname("%").">")
Bram Moolenaar85850f32019-07-19 22:05:51 +020011699 if exists("a:posndict")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011700 if has_key(a:posndict,bufnr("%"))
11701 " call Decho("before pop: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')]))
11702 let posnlen= len(a:posndict[bufnr("%")])
11703 if posnlen > 0
11704 let posnlen= posnlen - 1
11705 " call Decho("restoring posn posndict[".bufnr("%")."][".posnlen."]=".string(a:posndict[bufnr("%")][posnlen]),'~'.expand("<slnum>"))
11706 call winrestview(a:posndict[bufnr("%")][posnlen])
11707 call remove(a:posndict[bufnr("%")],posnlen)
11708 " call Decho("after pop: a:posndict[buf#".bufnr("%")."]=".string(a:posndict[bufnr('%')]))
11709 endif
Bram Moolenaar85850f32019-07-19 22:05:51 +020011710 endif
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +020011711 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011712 " call Dret("s:RestorePosn")
Bram Moolenaaraa3b15d2016-04-21 08:53:19 +020011713endfun
11714
11715" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +000011716" s:SaveWinVars: (used by Explore() and NetrwSplit()) {{{2
Bram Moolenaar9964e462007-05-05 17:54:07 +000011717fun! s:SaveWinVars()
Luca Saccarolac363ca12024-12-19 20:16:18 +010011718 " call Dfunc("s:SaveWinVars() win#".winnr())
Bram Moolenaar9964e462007-05-05 17:54:07 +000011719 if exists("w:netrw_bannercnt") |let s:bannercnt = w:netrw_bannercnt |endif
11720 if exists("w:netrw_col") |let s:col = w:netrw_col |endif
11721 if exists("w:netrw_curdir") |let s:curdir = w:netrw_curdir |endif
11722 if exists("w:netrw_explore_bufnr") |let s:explore_bufnr = w:netrw_explore_bufnr |endif
11723 if exists("w:netrw_explore_indx") |let s:explore_indx = w:netrw_explore_indx |endif
11724 if exists("w:netrw_explore_line") |let s:explore_line = w:netrw_explore_line |endif
11725 if exists("w:netrw_explore_listlen")|let s:explore_listlen = w:netrw_explore_listlen|endif
11726 if exists("w:netrw_explore_list") |let s:explore_list = w:netrw_explore_list |endif
11727 if exists("w:netrw_explore_mtchcnt")|let s:explore_mtchcnt = w:netrw_explore_mtchcnt|endif
11728 if exists("w:netrw_fpl") |let s:fpl = w:netrw_fpl |endif
11729 if exists("w:netrw_hline") |let s:hline = w:netrw_hline |endif
11730 if exists("w:netrw_line") |let s:line = w:netrw_line |endif
11731 if exists("w:netrw_liststyle") |let s:liststyle = w:netrw_liststyle |endif
11732 if exists("w:netrw_method") |let s:method = w:netrw_method |endif
11733 if exists("w:netrw_prvdir") |let s:prvdir = w:netrw_prvdir |endif
11734 if exists("w:netrw_treedict") |let s:treedict = w:netrw_treedict |endif
11735 if exists("w:netrw_treetop") |let s:treetop = w:netrw_treetop |endif
11736 if exists("w:netrw_winnr") |let s:winnr = w:netrw_winnr |endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011737 " call Dret("s:SaveWinVars")
Bram Moolenaar9964e462007-05-05 17:54:07 +000011738endfun
11739
11740" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +000011741" s:SetBufWinVars: (used by NetrwBrowse() and LocalBrowseCheck()) {{{2
Bram Moolenaar90cfdbe2005-08-12 19:59:19 +000011742" To allow separate windows to have their own activities, such as
11743" Explore **/pattern, several variables have been made window-oriented.
11744" However, when the user splits a browser window (ex: ctrl-w s), these
Bram Moolenaar1afcace2005-11-25 19:54:28 +000011745" variables are not inherited by the new window. SetBufWinVars() and
Bram Moolenaar90cfdbe2005-08-12 19:59:19 +000011746" UseBufWinVars() get around that.
Bram Moolenaar1afcace2005-11-25 19:54:28 +000011747fun! s:SetBufWinVars()
Luca Saccarolac363ca12024-12-19 20:16:18 +010011748 " call Dfunc("s:SetBufWinVars() win#".winnr())
Bram Moolenaar9964e462007-05-05 17:54:07 +000011749 if exists("w:netrw_liststyle") |let b:netrw_liststyle = w:netrw_liststyle |endif
11750 if exists("w:netrw_bannercnt") |let b:netrw_bannercnt = w:netrw_bannercnt |endif
11751 if exists("w:netrw_method") |let b:netrw_method = w:netrw_method |endif
11752 if exists("w:netrw_prvdir") |let b:netrw_prvdir = w:netrw_prvdir |endif
11753 if exists("w:netrw_explore_indx") |let b:netrw_explore_indx = w:netrw_explore_indx |endif
11754 if exists("w:netrw_explore_listlen")|let b:netrw_explore_listlen= w:netrw_explore_listlen|endif
11755 if exists("w:netrw_explore_mtchcnt")|let b:netrw_explore_mtchcnt= w:netrw_explore_mtchcnt|endif
11756 if exists("w:netrw_explore_bufnr") |let b:netrw_explore_bufnr = w:netrw_explore_bufnr |endif
11757 if exists("w:netrw_explore_line") |let b:netrw_explore_line = w:netrw_explore_line |endif
11758 if exists("w:netrw_explore_list") |let b:netrw_explore_list = w:netrw_explore_list |endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011759 " call Dret("s:SetBufWinVars")
Bram Moolenaar90cfdbe2005-08-12 19:59:19 +000011760endfun
11761
11762" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +000011763" s:SetRexDir: set directory for :Rexplore {{{2
11764fun! s:SetRexDir(islocal,dirname)
Luca Saccarolac363ca12024-12-19 20:16:18 +010011765 " call Dfunc("s:SetRexDir(islocal=".a:islocal." dirname<".a:dirname.">) win#".winnr())
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011766 let w:netrw_rexdir = a:dirname
11767 let w:netrw_rexlocal = a:islocal
Bram Moolenaare0fa3742016-02-20 15:47:01 +010011768 let s:rexposn_{bufnr("%")} = winsaveview()
Luca Saccarolac363ca12024-12-19 20:16:18 +010011769 " call Decho("setting w:netrw_rexdir =".w:netrw_rexdir,'~'.expand("<slnum>"))
11770 " call Decho("setting w:netrw_rexlocal=".w:netrw_rexlocal,'~'.expand("<slnum>"))
11771 " call Decho("saving posn to s:rexposn_".bufnr("%")."<".string(s:rexposn_{bufnr("%")}).">",'~'.expand("<slnum>"))
11772 " call Decho("setting s:rexposn_".bufnr("%")."<".bufname("%")."> to ".string(winsaveview()),'~'.expand("<slnum>"))
11773 " call Dret("s:SetRexDir : win#".winnr()." ".(a:islocal? "local" : "remote")." dir: ".a:dirname)
Bram Moolenaar446cb832008-06-24 21:56:24 +000011774endfun
11775
11776" ---------------------------------------------------------------------
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011777" s:ShowLink: used to modify thin and tree listings to show links {{{2
11778fun! s:ShowLink()
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011779 if exists("b:netrw_curdir")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011780 keepp :norm! $?\a
11781 "call histdel("/",-1)
11782 if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST && exists("w:netrw_treetop")
11783 let basedir = s:NetrwTreePath(w:netrw_treetop)
11784 else
11785 let basedir = b:netrw_curdir.'/'
11786 endif
11787 let fname = basedir.s:NetrwGetWord()
11788 let resname = resolve(fname)
11789 if resname =~ '^\M'.basedir
11790 let dirlen = strlen(basedir)
11791 let resname = strpart(resname,dirlen)
11792 endif
11793 let modline = getline(".")."\t --> ".resname
11794 setl noro ma
11795 call setline(".",modline)
11796 setl ro noma nomod
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011797 endif
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011798endfun
11799
11800" ---------------------------------------------------------------------
11801" s:ShowStyle: {{{2
11802fun! s:ShowStyle()
11803 if !exists("w:netrw_liststyle")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011804 let liststyle= g:netrw_liststyle
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011805 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010011806 let liststyle= w:netrw_liststyle
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011807 endif
11808 if liststyle == s:THINLIST
Luca Saccarolac363ca12024-12-19 20:16:18 +010011809 return s:THINLIST.":thin"
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011810 elseif liststyle == s:LONGLIST
Luca Saccarolac363ca12024-12-19 20:16:18 +010011811 return s:LONGLIST.":long"
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011812 elseif liststyle == s:WIDELIST
Luca Saccarolac363ca12024-12-19 20:16:18 +010011813 return s:WIDELIST.":wide"
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011814 elseif liststyle == s:TREELIST
Luca Saccarolac363ca12024-12-19 20:16:18 +010011815 return s:TREELIST.":tree"
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011816 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010011817 return 'n/a'
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010011818 endif
11819endfun
11820
11821" ---------------------------------------------------------------------
Bram Moolenaar8d043172014-01-23 14:24:41 +010011822" s:Strlen: this function returns the length of a string, even if its using multi-byte characters. {{{2
11823" Solution from Nicolai Weibull, vim docs (:help strlen()),
11824" Tony Mechelynck, and my own invention.
Bram Moolenaar446cb832008-06-24 21:56:24 +000011825fun! s:Strlen(x)
Luca Saccarolac363ca12024-12-19 20:16:18 +010011826 " "" call Dfunc("s:Strlen(x<".a:x."> g:Align_xstrlen=".g:Align_xstrlen.")")
Bram Moolenaar8d043172014-01-23 14:24:41 +010011827
11828 if v:version >= 703 && exists("*strdisplaywidth")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011829 let ret= strdisplaywidth(a:x)
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011830
Bram Moolenaar8d043172014-01-23 14:24:41 +010011831 elseif type(g:Align_xstrlen) == 1
Luca Saccarolac363ca12024-12-19 20:16:18 +010011832 " allow user to specify a function to compute the string length (ie. let g:Align_xstrlen="mystrlenfunc")
11833 exe "let ret= ".g:Align_xstrlen."('".substitute(a:x,"'","''","g")."')"
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011834
Bram Moolenaar8d043172014-01-23 14:24:41 +010011835 elseif g:Align_xstrlen == 1
Luca Saccarolac363ca12024-12-19 20:16:18 +010011836 " number of codepoints (Latin a + combining circumflex is two codepoints)
11837 " (comment from TM, solution from NW)
11838 let ret= strlen(substitute(a:x,'.','c','g'))
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011839
Bram Moolenaar8d043172014-01-23 14:24:41 +010011840 elseif g:Align_xstrlen == 2
Luca Saccarolac363ca12024-12-19 20:16:18 +010011841 " number of spacing codepoints (Latin a + combining circumflex is one spacing
11842 " codepoint; a hard tab is one; wide and narrow CJK are one each; etc.)
11843 " (comment from TM, solution from TM)
11844 let ret=strlen(substitute(a:x, '.\Z', 'x', 'g'))
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011845
Bram Moolenaar8d043172014-01-23 14:24:41 +010011846 elseif g:Align_xstrlen == 3
Luca Saccarolac363ca12024-12-19 20:16:18 +010011847 " virtual length (counting, for instance, tabs as anything between 1 and
11848 " 'tabstop', wide CJK as 2 rather than 1, Arabic alif as zero when immediately
11849 " preceded by lam, one otherwise, etc.)
11850 " (comment from TM, solution from me)
11851 let modkeep= &l:mod
11852 exe "norm! o\<esc>"
11853 call setline(line("."),a:x)
11854 let ret= virtcol("$") - 1
11855 d
11856 NetrwKeepj norm! k
11857 let &l:mod= modkeep
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011858
Bram Moolenaar446cb832008-06-24 21:56:24 +000011859 else
Luca Saccarolac363ca12024-12-19 20:16:18 +010011860 " at least give a decent default
Bram Moolenaar8d043172014-01-23 14:24:41 +010011861 let ret= strlen(a:x)
Bram Moolenaar446cb832008-06-24 21:56:24 +000011862 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011863 " "" call Dret("s:Strlen ".ret)
Bram Moolenaar446cb832008-06-24 21:56:24 +000011864 return ret
11865endfun
11866
11867" ---------------------------------------------------------------------
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011868" s:ShellEscape: shellescape(), or special windows handling {{{2
11869fun! s:ShellEscape(s, ...)
Nir Lichtman1e34b952024-05-08 19:19:34 +020011870 if has('win32') && $SHELL == '' && &shellslash
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011871 return printf('"%s"', substitute(a:s, '"', '""', 'g'))
Christian Brabandt8b0fa7a2024-10-31 09:21:23 +010011872 endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011873 let f = a:0 > 0 ? a:1 : 0
11874 return shellescape(a:s, f)
11875endfun
11876
11877" ---------------------------------------------------------------------
Bram Moolenaare0fa3742016-02-20 15:47:01 +010011878" s:TreeListMove: supports [[, ]], [], and ][ in tree mode {{{2
Bram Moolenaar446cb832008-06-24 21:56:24 +000011879fun! s:TreeListMove(dir)
Luca Saccarolac363ca12024-12-19 20:16:18 +010011880 " call Dfunc("s:TreeListMove(dir<".a:dir.">)")
Bram Moolenaare0fa3742016-02-20 15:47:01 +010011881 let curline = getline('.')
11882 let prvline = (line(".") > 1)? getline(line(".")-1) : ''
11883 let nxtline = (line(".") < line("$"))? getline(line(".")+1) : ''
11884 let curindent = substitute(getline('.'),'^\(\%('.s:treedepthstring.'\)*\)[^'.s:treedepthstring.'].\{-}$','\1','e')
11885 let indentm1 = substitute(curindent,'^'.s:treedepthstring,'','')
11886 let treedepthchr = substitute(s:treedepthstring,' ','','g')
11887 let stopline = exists("w:netrw_bannercnt")? w:netrw_bannercnt : 1
Luca Saccarolac363ca12024-12-19 20:16:18 +010011888 " call Decho("prvline <".prvline."> #".(line(".")-1), '~'.expand("<slnum>"))
11889 " call Decho("curline <".curline."> #".line(".") , '~'.expand("<slnum>"))
11890 " call Decho("nxtline <".nxtline."> #".(line(".")+1), '~'.expand("<slnum>"))
11891 " call Decho("curindent<".curindent.">" , '~'.expand("<slnum>"))
11892 " call Decho("indentm1 <".indentm1.">" , '~'.expand("<slnum>"))
Bram Moolenaare0fa3742016-02-20 15:47:01 +010011893 " COMBAK : need to handle when on a directory
11894 " COMBAK : need to handle ]] and ][. In general, needs work!!!
Bram Moolenaar446cb832008-06-24 21:56:24 +000011895 if curline !~ '/$'
Luca Saccarolac363ca12024-12-19 20:16:18 +010011896 if a:dir == '[[' && prvline != ''
11897 NetrwKeepj norm! 0
11898 let nl = search('^'.indentm1.'\%('.s:treedepthstring.'\)\@!','bWe',stopline) " search backwards
shane.xb.qianc673b802024-12-20 19:36:40 +010011899 " call Decho("regfile srch back: ".nl,'~'.expand("<slnum>"))
Luca Saccarolac363ca12024-12-19 20:16:18 +010011900 elseif a:dir == '[]' && nxtline != ''
11901 NetrwKeepj norm! 0
11902 " call Decho('srchpat<'.'^\%('.curindent.'\)\@!'.'>','~'.expand("<slnum>"))
11903 let nl = search('^\%('.curindent.'\)\@!','We') " search forwards
11904 if nl != 0
11905 NetrwKeepj norm! k
11906 else
11907 NetrwKeepj norm! G
11908 endif
11909 " call Decho("regfile srch fwd: ".nl,'~'.expand("<slnum>"))
Bram Moolenaare0fa3742016-02-20 15:47:01 +010011910 endif
Bram Moolenaar446cb832008-06-24 21:56:24 +000011911 endif
11912
Luca Saccarolac363ca12024-12-19 20:16:18 +010011913 " call Dret("s:TreeListMove")
Bram Moolenaar446cb832008-06-24 21:56:24 +000011914endfun
11915
11916" ---------------------------------------------------------------------
Bram Moolenaarc236c162008-07-13 17:41:49 +000011917" s:UpdateBuffersMenu: does emenu Buffers.Refresh (but due to locale, the menu item may not be called that) {{{2
11918" The Buffers.Refresh menu calls s:BMShow(); unfortunately, that means that that function
11919" can't be called except via emenu. But due to locale, that menu line may not be called
11920" Buffers.Refresh; hence, s:NetrwBMShow() utilizes a "cheat" to call that function anyway.
11921fun! s:UpdateBuffersMenu()
Luca Saccarolac363ca12024-12-19 20:16:18 +010011922 " call Dfunc("s:UpdateBuffersMenu()")
Bram Moolenaaradc21822011-04-01 18:03:16 +020011923 if has("gui") && has("menu") && has("gui_running") && &go =~# 'm' && g:netrw_menu
Luca Saccarolac363ca12024-12-19 20:16:18 +010011924 try
11925 sil emenu Buffers.Refresh\ menu
11926 catch /^Vim\%((\a\+)\)\=:E/
11927 let v:errmsg= ""
11928 sil NetrwKeepj call s:NetrwBMShow()
11929 endtry
Bram Moolenaarc236c162008-07-13 17:41:49 +000011930 endif
Luca Saccarolac363ca12024-12-19 20:16:18 +010011931 " call Dret("s:UpdateBuffersMenu")
Bram Moolenaarc236c162008-07-13 17:41:49 +000011932endfun
11933
11934" ---------------------------------------------------------------------
Bram Moolenaar446cb832008-06-24 21:56:24 +000011935" s:UseBufWinVars: (used by NetrwBrowse() and LocalBrowseCheck() {{{2
Bram Moolenaaradc21822011-04-01 18:03:16 +020011936" Matching function to s:SetBufWinVars()
Bram Moolenaar90cfdbe2005-08-12 19:59:19 +000011937fun! s:UseBufWinVars()
Luca Saccarolac363ca12024-12-19 20:16:18 +010011938 " call Dfunc("s:UseBufWinVars()")
Bram Moolenaar9964e462007-05-05 17:54:07 +000011939 if exists("b:netrw_liststyle") && !exists("w:netrw_liststyle") |let w:netrw_liststyle = b:netrw_liststyle |endif
Bram Moolenaar90cfdbe2005-08-12 19:59:19 +000011940 if exists("b:netrw_bannercnt") && !exists("w:netrw_bannercnt") |let w:netrw_bannercnt = b:netrw_bannercnt |endif
11941 if exists("b:netrw_method") && !exists("w:netrw_method") |let w:netrw_method = b:netrw_method |endif
11942 if exists("b:netrw_prvdir") && !exists("w:netrw_prvdir") |let w:netrw_prvdir = b:netrw_prvdir |endif
11943 if exists("b:netrw_explore_indx") && !exists("w:netrw_explore_indx") |let w:netrw_explore_indx = b:netrw_explore_indx |endif
11944 if exists("b:netrw_explore_listlen") && !exists("w:netrw_explore_listlen")|let w:netrw_explore_listlen = b:netrw_explore_listlen|endif
11945 if exists("b:netrw_explore_mtchcnt") && !exists("w:netrw_explore_mtchcnt")|let w:netrw_explore_mtchcnt = b:netrw_explore_mtchcnt|endif
11946 if exists("b:netrw_explore_bufnr") && !exists("w:netrw_explore_bufnr") |let w:netrw_explore_bufnr = b:netrw_explore_bufnr |endif
11947 if exists("b:netrw_explore_line") && !exists("w:netrw_explore_line") |let w:netrw_explore_line = b:netrw_explore_line |endif
11948 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 +010011949 " call Dret("s:UseBufWinVars")
Bram Moolenaar90cfdbe2005-08-12 19:59:19 +000011950endfun
11951
Bram Moolenaar1afcace2005-11-25 19:54:28 +000011952" ---------------------------------------------------------------------
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011953" s:UserMaps: supports user-defined UserMaps {{{2
11954" * calls a user-supplied funcref(islocal,curdir)
11955" * interprets result
11956" See netrw#UserMaps()
11957fun! s:UserMaps(islocal,funcname)
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011958 if !exists("b:netrw_curdir")
Luca Saccarolac363ca12024-12-19 20:16:18 +010011959 let b:netrw_curdir= getcwd()
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011960 endif
11961 let Funcref = function(a:funcname)
11962 let result = Funcref(a:islocal)
11963
11964 if type(result) == 1
Luca Saccarolac363ca12024-12-19 20:16:18 +010011965 " if result from user's funcref is a string...
11966 if result == "refresh"
11967 call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
11968 elseif result != ""
11969 exe result
11970 endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011971
11972 elseif type(result) == 3
Luca Saccarolac363ca12024-12-19 20:16:18 +010011973 " if result from user's funcref is a List...
11974 for action in result
11975 if action == "refresh"
11976 call s:NetrwRefresh(a:islocal,s:NetrwBrowseChgDir(a:islocal,'./',0))
11977 elseif action != ""
11978 exe action
11979 endif
11980 endfor
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011981 endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +010011982endfun
11983
Bram Moolenaar85850f32019-07-19 22:05:51 +020011984" ==========================
Bram Moolenaare6ae6222013-05-21 21:01:10 +020011985" Settings Restoration: {{{1
Bram Moolenaar85850f32019-07-19 22:05:51 +020011986" ==========================
Bram Moolenaar83bab712005-08-01 21:58:57 +000011987let &cpo= s:keepcpo
11988unlet s:keepcpo
Bram Moolenaar5b8d8fd2005-08-16 23:01:50 +000011989
Bram Moolenaar85850f32019-07-19 22:05:51 +020011990" ===============
Bram Moolenaar83bab712005-08-01 21:58:57 +000011991" Modelines: {{{1
Bram Moolenaar85850f32019-07-19 22:05:51 +020011992" ===============
Luca Saccarolac363ca12024-12-19 20:16:18 +010011993" vim:ts=8 sts=2 sw=2 et fdm=marker