blob: 775b650e719365af4eb086803f7a30d8917ccde7 [file] [log] [blame]
Bram Moolenaar482aaeb2005-09-29 18:26:07 +00001" netrwPlugin.vim: Handles file transfer and remote directory listing across a network
Bram Moolenaardd2a3cd2007-05-05 17:10:09 +00002" PLUGIN SECTION
Christian Brabandtf9ca1392024-02-19 20:37:11 +01003" Maintainer: This runtime file is looking for a new maintainer.
Konfekt3d7e5672024-10-27 22:16:49 +01004" Date: Sep 09, 2021
Nir Lichtman1e34b952024-05-08 19:19:34 +02005" Last Change:
6" 2024 May 08 by Vim Project: cleanup legacy Win9X checks
Konfekt3d7e5672024-10-27 22:16:49 +01007" 2024 Oct 27 by Vim Project: cleanup gx mapping
Christian Brabandtd69ffbe2024-10-28 21:23:54 +01008" 2024 Oct 28 by Vim Project: further improvements
Christian Brabandt8b0fa7a2024-10-31 09:21:23 +01009" 2024 Oct 31 by Vim Project: use autoloaded functions
Christian Brabandtf9ca1392024-02-19 20:37:11 +010010" Former Maintainer: Charles E Campbell
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000011" GetLatestVimScripts: 1075 1 :AutoInstall: netrw.vim
Bram Moolenaar89a9c152021-08-29 21:55:35 +020012" Copyright: Copyright (C) 1999-2021 Charles E. Campbell {{{1
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000013" Permission is hereby granted to use and distribute this code,
14" with or without modifications, provided that this copyright
15" notice is copied with it. Like anything else that's free,
16" netrw.vim, netrwPlugin.vim, and netrwSettings.vim are provided
17" *as is* and comes with no warranty of any kind, either
18" expressed or implied. By using this plugin, you agree that
19" in no event will the copyright holder be liable for any damages
20" resulting from the use of this software.
21"
22" But be doers of the Word, and not only hearers, deluding your own selves {{{1
23" (James 1:22 RSV)
24" =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000025" Load Once: {{{1
Bram Moolenaardd2a3cd2007-05-05 17:10:09 +000026if &cp || exists("g:loaded_netrwPlugin")
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000027 finish
28endif
Bram Moolenaarb7398fe2023-05-14 18:50:25 +010029let g:loaded_netrwPlugin = "v173"
Bram Moolenaar5c736222010-01-06 20:54:52 +010030let s:keepcpo = &cpo
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000031set cpo&vim
Bram Moolenaar8d043172014-01-23 14:24:41 +010032"DechoRemOn
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000033
34" ---------------------------------------------------------------------
35" Public Interface: {{{1
36
Konfekt3d7e5672024-10-27 22:16:49 +010037" Commands Launch/URL {{{2
Christian Brabandt8b0fa7a2024-10-31 09:21:23 +010038command -complete=shellcmd -nargs=1 Launch call netrw#Launch(trim(<q-args>))
39command -complete=file -nargs=1 Open call netrw#Open(trim(<q-args>))
Konfekt3d7e5672024-10-27 22:16:49 +010040" " }}}
Bram Moolenaar8d043172014-01-23 14:24:41 +010041" Local Browsing Autocmds: {{{2
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000042augroup FileExplorer
43 au!
Bram Moolenaara6878372014-03-22 21:02:50 +010044 au BufLeave * if &ft != "netrw"|let w:netrw_prvfile= expand("%:p")|endif
Bram Moolenaar8d043172014-01-23 14:24:41 +010045 au BufEnter * sil call s:LocalBrowse(expand("<amatch>"))
46 au VimEnter * sil call s:VimEnter(expand("<amatch>"))
Nir Lichtman1e34b952024-05-08 19:19:34 +020047 if has("win32")
Bram Moolenaar8d043172014-01-23 14:24:41 +010048 au BufEnter .* sil call s:LocalBrowse(expand("<amatch>"))
Bram Moolenaardd2a3cd2007-05-05 17:10:09 +000049 endif
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000050augroup END
51
52" Network Browsing Reading Writing: {{{2
53augroup Network
54 au!
Bram Moolenaar85850f32019-07-19 22:05:51 +020055 au BufReadCmd file://* call netrw#FileUrlEdit(expand("<amatch>"))
56 au BufReadCmd ftp://*,rcp://*,scp://*,http://*,https://*,dav://*,davs://*,rsync://*,sftp://* exe "sil doau BufReadPre ".fnameescape(expand("<amatch>"))|call netrw#Nread(2,expand("<amatch>"))|exe "sil doau BufReadPost ".fnameescape(expand("<amatch>"))
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010057 au FileReadCmd ftp://*,rcp://*,scp://*,http://*,file://*,https://*,dav://*,davs://*,rsync://*,sftp://* exe "sil doau FileReadPre ".fnameescape(expand("<amatch>"))|call netrw#Nread(1,expand("<amatch>"))|exe "sil doau FileReadPost ".fnameescape(expand("<amatch>"))
58 au BufWriteCmd ftp://*,rcp://*,scp://*,http://*,file://*,dav://*,davs://*,rsync://*,sftp://* exe "sil doau BufWritePre ".fnameescape(expand("<amatch>"))|exe 'Nwrite '.fnameescape(expand("<amatch>"))|exe "sil doau BufWritePost ".fnameescape(expand("<amatch>"))
59 au FileWriteCmd ftp://*,rcp://*,scp://*,http://*,file://*,dav://*,davs://*,rsync://*,sftp://* exe "sil doau FileWritePre ".fnameescape(expand("<amatch>"))|exe "'[,']".'Nwrite '.fnameescape(expand("<amatch>"))|exe "sil doau FileWritePost ".fnameescape(expand("<amatch>"))
Bram Moolenaar589edb32019-09-20 14:38:13 +020060 try
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010061 au SourceCmd ftp://*,rcp://*,scp://*,http://*,file://*,https://*,dav://*,davs://*,rsync://*,sftp://* exe 'Nsource '.fnameescape(expand("<amatch>"))
Bram Moolenaar589edb32019-09-20 14:38:13 +020062 catch /^Vim\%((\a\+)\)\=:E216/
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010063 au SourcePre ftp://*,rcp://*,scp://*,http://*,file://*,https://*,dav://*,davs://*,rsync://*,sftp://* exe 'Nsource '.fnameescape(expand("<amatch>"))
Bram Moolenaardd2a3cd2007-05-05 17:10:09 +000064 endtry
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000065augroup END
66
67" Commands: :Nread, :Nwrite, :NetUserPass {{{2
Bram Moolenaare0fa3742016-02-20 15:47:01 +010068com! -count=1 -nargs=* Nread let s:svpos= winsaveview()<bar>call netrw#NetRead(<count>,<f-args>)<bar>call winrestview(s:svpos)
69com! -range=% -nargs=* Nwrite let s:svpos= winsaveview()<bar><line1>,<line2>call netrw#NetWrite(<f-args>)<bar>call winrestview(s:svpos)
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000070com! -nargs=* NetUserPass call NetUserPass(<f-args>)
Bram Moolenaare0fa3742016-02-20 15:47:01 +010071com! -nargs=* Nsource let s:svpos= winsaveview()<bar>call netrw#NetSource(<f-args>)<bar>call winrestview(s:svpos)
Bram Moolenaar85850f32019-07-19 22:05:51 +020072com! -nargs=? Ntree call netrw#SetTreetop(1,<q-args>)
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000073
Bram Moolenaar8d043172014-01-23 14:24:41 +010074" Commands: :Explore, :Sexplore, Hexplore, Vexplore, Lexplore {{{2
Bram Moolenaardd2a3cd2007-05-05 17:10:09 +000075com! -nargs=* -bar -bang -count=0 -complete=dir Explore call netrw#Explore(<count>,0,0+<bang>0,<q-args>)
76com! -nargs=* -bar -bang -count=0 -complete=dir Sexplore call netrw#Explore(<count>,1,0+<bang>0,<q-args>)
77com! -nargs=* -bar -bang -count=0 -complete=dir Hexplore call netrw#Explore(<count>,1,2+<bang>0,<q-args>)
78com! -nargs=* -bar -bang -count=0 -complete=dir Vexplore call netrw#Explore(<count>,1,4+<bang>0,<q-args>)
79com! -nargs=* -bar -count=0 -complete=dir Texplore call netrw#Explore(<count>,0,6 ,<q-args>)
80com! -nargs=* -bar -bang Nexplore call netrw#Explore(-1,0,0,<q-args>)
81com! -nargs=* -bar -bang Pexplore call netrw#Explore(-2,0,0,<q-args>)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010082com! -nargs=* -bar -bang -count=0 -complete=dir Lexplore call netrw#Lexplore(<count>,<bang>0,<q-args>)
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000083
84" Commands: NetrwSettings {{{2
Bram Moolenaarf2330482008-06-24 20:19:36 +000085com! -nargs=0 NetrwSettings call netrwSettings#NetrwSettings()
Bram Moolenaara6878372014-03-22 21:02:50 +010086com! -bang NetrwClean call netrw#Clean(<bang>0)
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000087
Bram Moolenaarb8a7b562006-02-01 21:47:16 +000088" Maps:
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010089if !exists("g:netrw_nogx")
90 if maparg('gx','n') == ""
91 if !hasmapto('<Plug>NetrwBrowseX')
92 nmap <unique> gx <Plug>NetrwBrowseX
93 endif
Bram Moolenaar5ef1c6a2019-11-10 22:09:11 +010094 nno <silent> <Plug>NetrwBrowseX :call netrw#BrowseX(netrw#GX(),netrw#CheckIfRemote(netrw#GX()))<cr>
Bram Moolenaardd2a3cd2007-05-05 17:10:09 +000095 endif
Bram Moolenaar89a9c152021-08-29 21:55:35 +020096 if maparg('gx','x') == ""
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010097 if !hasmapto('<Plug>NetrwBrowseXVis')
Bram Moolenaar89a9c152021-08-29 21:55:35 +020098 xmap <unique> gx <Plug>NetrwBrowseXVis
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010099 endif
Bram Moolenaar89a9c152021-08-29 21:55:35 +0200100 xno <silent> <Plug>NetrwBrowseXVis :<c-u>call netrw#BrowseXVis()<cr>
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100101 endif
Bram Moolenaarb8a7b562006-02-01 21:47:16 +0000102endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +0100103if exists("g:netrw_usetab") && g:netrw_usetab
104 if maparg('<c-tab>','n') == ""
105 nmap <unique> <c-tab> <Plug>NetrwShrink
106 endif
107 nno <silent> <Plug>NetrwShrink :call netrw#Shrink()<cr>
108endif
Bram Moolenaarb8a7b562006-02-01 21:47:16 +0000109
Bram Moolenaar482aaeb2005-09-29 18:26:07 +0000110" ---------------------------------------------------------------------
Bram Moolenaar8d043172014-01-23 14:24:41 +0100111" LocalBrowse: invokes netrw#LocalBrowseCheck() on directory buffers {{{2
Bram Moolenaar482aaeb2005-09-29 18:26:07 +0000112fun! s:LocalBrowse(dirname)
Bram Moolenaar8d043172014-01-23 14:24:41 +0100113 " Unfortunate interaction -- only DechoMsg debugging calls can be safely used here.
114 " Otherwise, the BufEnter event gets triggered when attempts to write to
Bram Moolenaar482aaeb2005-09-29 18:26:07 +0000115 " the DBG buffer are made.
Bram Moolenaar589edb32019-09-20 14:38:13 +0200116
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200117 if !exists("s:vimentered")
Bram Moolenaar8d043172014-01-23 14:24:41 +0100118 " If s:vimentered doesn't exist, then the VimEnter event hasn't fired. It will,
119 " and so s:VimEnter() will then be calling this routine, but this time with s:vimentered defined.
120" call Dfunc("s:LocalBrowse(dirname<".a:dirname.">) (s:vimentered doesn't exist)")
121" call Dret("s:LocalBrowse")
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200122 return
123 endif
Bram Moolenaar8d043172014-01-23 14:24:41 +0100124
125" call Dfunc("s:LocalBrowse(dirname<".a:dirname.">) (s:vimentered=".s:vimentered.")")
126
Bram Moolenaardd2a3cd2007-05-05 17:10:09 +0000127 if has("amiga")
128 " The check against '' is made for the Amiga, where the empty
129 " string is the current directory and not checking would break
130 " things such as the help command.
Bram Moolenaar8d043172014-01-23 14:24:41 +0100131" call Decho("(LocalBrowse) dirname<".a:dirname."> (isdirectory, amiga)")
Bram Moolenaardd2a3cd2007-05-05 17:10:09 +0000132 if a:dirname != '' && isdirectory(a:dirname)
Bram Moolenaaradc21822011-04-01 18:03:16 +0200133 sil! call netrw#LocalBrowseCheck(a:dirname)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100134 if exists("w:netrw_bannercnt") && line('.') < w:netrw_bannercnt
Bram Moolenaara6878372014-03-22 21:02:50 +0100135 exe w:netrw_bannercnt
136 endif
Bram Moolenaardd2a3cd2007-05-05 17:10:09 +0000137 endif
Bram Moolenaar8d043172014-01-23 14:24:41 +0100138
Bram Moolenaardd2a3cd2007-05-05 17:10:09 +0000139 elseif isdirectory(a:dirname)
Bram Moolenaara6878372014-03-22 21:02:50 +0100140" call Decho("(LocalBrowse) dirname<".a:dirname."> ft=".&ft." (isdirectory, not amiga)")
141" call Dredir("LocalBrowse ft last set: ","verbose set ft")
Bram Moolenaar89a9c152021-08-29 21:55:35 +0200142 " Jul 13, 2021: for whatever reason, preceding the following call with
143 " a sil! causes an unbalanced if-endif vim error
144 call netrw#LocalBrowseCheck(a:dirname)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100145 if exists("w:netrw_bannercnt") && line('.') < w:netrw_bannercnt
Bram Moolenaara6878372014-03-22 21:02:50 +0100146 exe w:netrw_bannercnt
147 endif
Bram Moolenaar8d043172014-01-23 14:24:41 +0100148
149 else
150 " not a directory, ignore it
151" call Decho("(LocalBrowse) dirname<".a:dirname."> not a directory, ignoring...")
Bram Moolenaar482aaeb2005-09-29 18:26:07 +0000152 endif
Bram Moolenaar8d043172014-01-23 14:24:41 +0100153
154" call Dret("s:LocalBrowse")
Bram Moolenaar482aaeb2005-09-29 18:26:07 +0000155endfun
156
157" ---------------------------------------------------------------------
Bram Moolenaar8d043172014-01-23 14:24:41 +0100158" s:VimEnter: after all vim startup stuff is done, this function is called. {{{2
159" Its purpose: to look over all windows and run s:LocalBrowse() on
160" them, which checks if they're directories and will create a directory
161" listing when appropriate.
162" It also sets s:vimentered, letting s:LocalBrowse() know that s:VimEnter()
163" has already been called.
Bram Moolenaar00a927d2010-05-14 23:24:24 +0200164fun! s:VimEnter(dirname)
Bram Moolenaar8d043172014-01-23 14:24:41 +0100165" call Dfunc("s:VimEnter(dirname<".a:dirname.">) expand(%)<".expand("%").">")
Bram Moolenaar89a9c152021-08-29 21:55:35 +0200166 if has('nvim') || v:version < 802
167 " Johann Höchtl: reported that the call range... line causes an E488: Trailing characters
168 " error with neovim. I suspect its because neovim hasn't updated with recent
169 " vim patches. As is, this code will have problems with popup terminals
170 " instantiated before the VimEnter event runs.
171 " Ingo Karkat : E488 also in Vim 8.1.1602
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200172 let curwin = winnr()
173 let s:vimentered = 1
Bram Moolenaar8d043172014-01-23 14:24:41 +0100174 windo call s:LocalBrowse(expand("%:p"))
Bram Moolenaar477db062010-07-28 18:17:41 +0200175 exe curwin."wincmd w"
Bram Moolenaar89a9c152021-08-29 21:55:35 +0200176 else
177 " the following complicated expression comes courtesy of lacygoill; largely does the same thing as the windo and
178 " wincmd which are commented out, but avoids some side effects. Allows popup terminal before VimEnter.
179 let s:vimentered = 1
180 call range(1, winnr('$'))->map({_, v -> win_execute(win_getid(v), 'call expand("%:p")->s:LocalBrowse()')})
181 endif
Bram Moolenaar8d043172014-01-23 14:24:41 +0100182" call Dret("s:VimEnter")
Bram Moolenaar00a927d2010-05-14 23:24:24 +0200183endfun
184
185" ---------------------------------------------------------------------
Bram Moolenaar482aaeb2005-09-29 18:26:07 +0000186" NetrwStatusLine: {{{1
187fun! NetrwStatusLine()
Bram Moolenaaraf48b092006-03-14 22:51:38 +0000188" let g:stlmsg= "Xbufnr=".w:netrw_explore_bufnr." bufnr=".bufnr("%")." Xline#".w:netrw_explore_line." line#".line(".")
189 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")
Bram Moolenaar482aaeb2005-09-29 18:26:07 +0000190 let &stl= s:netrw_explore_stl
191 if exists("w:netrw_explore_bufnr")|unlet w:netrw_explore_bufnr|endif
192 if exists("w:netrw_explore_line")|unlet w:netrw_explore_line|endif
193 return ""
194 else
195 return "Match ".w:netrw_explore_mtchcnt." of ".w:netrw_explore_listlen
196 endif
197endfun
198
199" ------------------------------------------------------------------------
200" NetUserPass: set username and password for subsequent ftp transfer {{{1
201" Usage: :call NetUserPass() -- will prompt for userid and password
202" :call NetUserPass("uid") -- will prompt for password
203" :call NetUserPass("uid","password") -- sets global userid and password
204fun! NetUserPass(...)
205
206 " get/set userid
207 if a:0 == 0
208" call Dfunc("NetUserPass(a:0<".a:0.">)")
209 if !exists("g:netrw_uid") || g:netrw_uid == ""
210 " via prompt
211 let g:netrw_uid= input('Enter username: ')
212 endif
213 else " from command line
214" call Dfunc("NetUserPass(a:1<".a:1.">) {")
215 let g:netrw_uid= a:1
216 endif
217
218 " get password
219 if a:0 <= 1 " via prompt
220" call Decho("a:0=".a:0." case <=1:")
221 let g:netrw_passwd= inputsecret("Enter Password: ")
222 else " from command line
223" call Decho("a:0=".a:0." case >1: a:2<".a:2.">")
224 let g:netrw_passwd=a:2
225 endif
226" call Dret("NetUserPass")
227endfun
228
229" ------------------------------------------------------------------------
Bram Moolenaar482aaeb2005-09-29 18:26:07 +0000230" Modelines And Restoration: {{{1
231let &cpo= s:keepcpo
232unlet s:keepcpo
233" vim:ts=8 fdm=marker