blob: c70e6518fffc43246ef3617ce5ae802916308fda [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.
Bram Moolenaar89a9c152021-08-29 21:55:35 +02004" Date: Feb 09, 2021
Nir Lichtman1e34b952024-05-08 19:19:34 +02005" Last Change:
6" 2024 May 08 by Vim Project: cleanup legacy Win9X checks
Christian Brabandtf9ca1392024-02-19 20:37:11 +01007" Former Maintainer: Charles E Campbell
Bram Moolenaar482aaeb2005-09-29 18:26:07 +00008" GetLatestVimScripts: 1075 1 :AutoInstall: netrw.vim
Bram Moolenaar89a9c152021-08-29 21:55:35 +02009" Copyright: Copyright (C) 1999-2021 Charles E. Campbell {{{1
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000010" Permission is hereby granted to use and distribute this code,
11" with or without modifications, provided that this copyright
12" notice is copied with it. Like anything else that's free,
13" netrw.vim, netrwPlugin.vim, and netrwSettings.vim are provided
14" *as is* and comes with no warranty of any kind, either
15" expressed or implied. By using this plugin, you agree that
16" in no event will the copyright holder be liable for any damages
17" resulting from the use of this software.
18"
19" But be doers of the Word, and not only hearers, deluding your own selves {{{1
20" (James 1:22 RSV)
21" =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000022" Load Once: {{{1
Bram Moolenaardd2a3cd2007-05-05 17:10:09 +000023if &cp || exists("g:loaded_netrwPlugin")
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000024 finish
25endif
Bram Moolenaarb7398fe2023-05-14 18:50:25 +010026let g:loaded_netrwPlugin = "v173"
Bram Moolenaar5c736222010-01-06 20:54:52 +010027let s:keepcpo = &cpo
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000028set cpo&vim
Bram Moolenaar8d043172014-01-23 14:24:41 +010029"DechoRemOn
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000030
31" ---------------------------------------------------------------------
32" Public Interface: {{{1
33
Bram Moolenaar8d043172014-01-23 14:24:41 +010034" Local Browsing Autocmds: {{{2
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000035augroup FileExplorer
36 au!
Bram Moolenaara6878372014-03-22 21:02:50 +010037 au BufLeave * if &ft != "netrw"|let w:netrw_prvfile= expand("%:p")|endif
Bram Moolenaar8d043172014-01-23 14:24:41 +010038 au BufEnter * sil call s:LocalBrowse(expand("<amatch>"))
39 au VimEnter * sil call s:VimEnter(expand("<amatch>"))
Nir Lichtman1e34b952024-05-08 19:19:34 +020040 if has("win32")
Bram Moolenaar8d043172014-01-23 14:24:41 +010041 au BufEnter .* sil call s:LocalBrowse(expand("<amatch>"))
Bram Moolenaardd2a3cd2007-05-05 17:10:09 +000042 endif
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000043augroup END
44
45" Network Browsing Reading Writing: {{{2
46augroup Network
47 au!
Bram Moolenaar85850f32019-07-19 22:05:51 +020048 au BufReadCmd file://* call netrw#FileUrlEdit(expand("<amatch>"))
49 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 +010050 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>"))
51 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>"))
52 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 +020053 try
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010054 au SourceCmd ftp://*,rcp://*,scp://*,http://*,file://*,https://*,dav://*,davs://*,rsync://*,sftp://* exe 'Nsource '.fnameescape(expand("<amatch>"))
Bram Moolenaar589edb32019-09-20 14:38:13 +020055 catch /^Vim\%((\a\+)\)\=:E216/
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010056 au SourcePre ftp://*,rcp://*,scp://*,http://*,file://*,https://*,dav://*,davs://*,rsync://*,sftp://* exe 'Nsource '.fnameescape(expand("<amatch>"))
Bram Moolenaardd2a3cd2007-05-05 17:10:09 +000057 endtry
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000058augroup END
59
60" Commands: :Nread, :Nwrite, :NetUserPass {{{2
Bram Moolenaare0fa3742016-02-20 15:47:01 +010061com! -count=1 -nargs=* Nread let s:svpos= winsaveview()<bar>call netrw#NetRead(<count>,<f-args>)<bar>call winrestview(s:svpos)
62com! -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 +000063com! -nargs=* NetUserPass call NetUserPass(<f-args>)
Bram Moolenaare0fa3742016-02-20 15:47:01 +010064com! -nargs=* Nsource let s:svpos= winsaveview()<bar>call netrw#NetSource(<f-args>)<bar>call winrestview(s:svpos)
Bram Moolenaar85850f32019-07-19 22:05:51 +020065com! -nargs=? Ntree call netrw#SetTreetop(1,<q-args>)
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000066
Bram Moolenaar8d043172014-01-23 14:24:41 +010067" Commands: :Explore, :Sexplore, Hexplore, Vexplore, Lexplore {{{2
Bram Moolenaardd2a3cd2007-05-05 17:10:09 +000068com! -nargs=* -bar -bang -count=0 -complete=dir Explore call netrw#Explore(<count>,0,0+<bang>0,<q-args>)
69com! -nargs=* -bar -bang -count=0 -complete=dir Sexplore call netrw#Explore(<count>,1,0+<bang>0,<q-args>)
70com! -nargs=* -bar -bang -count=0 -complete=dir Hexplore call netrw#Explore(<count>,1,2+<bang>0,<q-args>)
71com! -nargs=* -bar -bang -count=0 -complete=dir Vexplore call netrw#Explore(<count>,1,4+<bang>0,<q-args>)
72com! -nargs=* -bar -count=0 -complete=dir Texplore call netrw#Explore(<count>,0,6 ,<q-args>)
73com! -nargs=* -bar -bang Nexplore call netrw#Explore(-1,0,0,<q-args>)
74com! -nargs=* -bar -bang Pexplore call netrw#Explore(-2,0,0,<q-args>)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010075com! -nargs=* -bar -bang -count=0 -complete=dir Lexplore call netrw#Lexplore(<count>,<bang>0,<q-args>)
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000076
77" Commands: NetrwSettings {{{2
Bram Moolenaarf2330482008-06-24 20:19:36 +000078com! -nargs=0 NetrwSettings call netrwSettings#NetrwSettings()
Bram Moolenaara6878372014-03-22 21:02:50 +010079com! -bang NetrwClean call netrw#Clean(<bang>0)
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000080
Bram Moolenaarb8a7b562006-02-01 21:47:16 +000081" Maps:
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010082if !exists("g:netrw_nogx")
83 if maparg('gx','n') == ""
84 if !hasmapto('<Plug>NetrwBrowseX')
85 nmap <unique> gx <Plug>NetrwBrowseX
86 endif
Bram Moolenaar5ef1c6a2019-11-10 22:09:11 +010087 nno <silent> <Plug>NetrwBrowseX :call netrw#BrowseX(netrw#GX(),netrw#CheckIfRemote(netrw#GX()))<cr>
Bram Moolenaardd2a3cd2007-05-05 17:10:09 +000088 endif
Bram Moolenaar89a9c152021-08-29 21:55:35 +020089 if maparg('gx','x') == ""
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010090 if !hasmapto('<Plug>NetrwBrowseXVis')
Bram Moolenaar89a9c152021-08-29 21:55:35 +020091 xmap <unique> gx <Plug>NetrwBrowseXVis
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010092 endif
Bram Moolenaar89a9c152021-08-29 21:55:35 +020093 xno <silent> <Plug>NetrwBrowseXVis :<c-u>call netrw#BrowseXVis()<cr>
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010094 endif
Bram Moolenaarb8a7b562006-02-01 21:47:16 +000095endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +010096if exists("g:netrw_usetab") && g:netrw_usetab
97 if maparg('<c-tab>','n') == ""
98 nmap <unique> <c-tab> <Plug>NetrwShrink
99 endif
100 nno <silent> <Plug>NetrwShrink :call netrw#Shrink()<cr>
101endif
Bram Moolenaarb8a7b562006-02-01 21:47:16 +0000102
Bram Moolenaar482aaeb2005-09-29 18:26:07 +0000103" ---------------------------------------------------------------------
Bram Moolenaar8d043172014-01-23 14:24:41 +0100104" LocalBrowse: invokes netrw#LocalBrowseCheck() on directory buffers {{{2
Bram Moolenaar482aaeb2005-09-29 18:26:07 +0000105fun! s:LocalBrowse(dirname)
Bram Moolenaar8d043172014-01-23 14:24:41 +0100106 " Unfortunate interaction -- only DechoMsg debugging calls can be safely used here.
107 " Otherwise, the BufEnter event gets triggered when attempts to write to
Bram Moolenaar482aaeb2005-09-29 18:26:07 +0000108 " the DBG buffer are made.
Bram Moolenaar589edb32019-09-20 14:38:13 +0200109
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200110 if !exists("s:vimentered")
Bram Moolenaar8d043172014-01-23 14:24:41 +0100111 " If s:vimentered doesn't exist, then the VimEnter event hasn't fired. It will,
112 " and so s:VimEnter() will then be calling this routine, but this time with s:vimentered defined.
113" call Dfunc("s:LocalBrowse(dirname<".a:dirname.">) (s:vimentered doesn't exist)")
114" call Dret("s:LocalBrowse")
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200115 return
116 endif
Bram Moolenaar8d043172014-01-23 14:24:41 +0100117
118" call Dfunc("s:LocalBrowse(dirname<".a:dirname.">) (s:vimentered=".s:vimentered.")")
119
Bram Moolenaardd2a3cd2007-05-05 17:10:09 +0000120 if has("amiga")
121 " The check against '' is made for the Amiga, where the empty
122 " string is the current directory and not checking would break
123 " things such as the help command.
Bram Moolenaar8d043172014-01-23 14:24:41 +0100124" call Decho("(LocalBrowse) dirname<".a:dirname."> (isdirectory, amiga)")
Bram Moolenaardd2a3cd2007-05-05 17:10:09 +0000125 if a:dirname != '' && isdirectory(a:dirname)
Bram Moolenaaradc21822011-04-01 18:03:16 +0200126 sil! call netrw#LocalBrowseCheck(a:dirname)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100127 if exists("w:netrw_bannercnt") && line('.') < w:netrw_bannercnt
Bram Moolenaara6878372014-03-22 21:02:50 +0100128 exe w:netrw_bannercnt
129 endif
Bram Moolenaardd2a3cd2007-05-05 17:10:09 +0000130 endif
Bram Moolenaar8d043172014-01-23 14:24:41 +0100131
Bram Moolenaardd2a3cd2007-05-05 17:10:09 +0000132 elseif isdirectory(a:dirname)
Bram Moolenaara6878372014-03-22 21:02:50 +0100133" call Decho("(LocalBrowse) dirname<".a:dirname."> ft=".&ft." (isdirectory, not amiga)")
134" call Dredir("LocalBrowse ft last set: ","verbose set ft")
Bram Moolenaar89a9c152021-08-29 21:55:35 +0200135 " Jul 13, 2021: for whatever reason, preceding the following call with
136 " a sil! causes an unbalanced if-endif vim error
137 call netrw#LocalBrowseCheck(a:dirname)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100138 if exists("w:netrw_bannercnt") && line('.') < w:netrw_bannercnt
Bram Moolenaara6878372014-03-22 21:02:50 +0100139 exe w:netrw_bannercnt
140 endif
Bram Moolenaar8d043172014-01-23 14:24:41 +0100141
142 else
143 " not a directory, ignore it
144" call Decho("(LocalBrowse) dirname<".a:dirname."> not a directory, ignoring...")
Bram Moolenaar482aaeb2005-09-29 18:26:07 +0000145 endif
Bram Moolenaar8d043172014-01-23 14:24:41 +0100146
147" call Dret("s:LocalBrowse")
Bram Moolenaar482aaeb2005-09-29 18:26:07 +0000148endfun
149
150" ---------------------------------------------------------------------
Bram Moolenaar8d043172014-01-23 14:24:41 +0100151" s:VimEnter: after all vim startup stuff is done, this function is called. {{{2
152" Its purpose: to look over all windows and run s:LocalBrowse() on
153" them, which checks if they're directories and will create a directory
154" listing when appropriate.
155" It also sets s:vimentered, letting s:LocalBrowse() know that s:VimEnter()
156" has already been called.
Bram Moolenaar00a927d2010-05-14 23:24:24 +0200157fun! s:VimEnter(dirname)
Bram Moolenaar8d043172014-01-23 14:24:41 +0100158" call Dfunc("s:VimEnter(dirname<".a:dirname.">) expand(%)<".expand("%").">")
Bram Moolenaar89a9c152021-08-29 21:55:35 +0200159 if has('nvim') || v:version < 802
160 " Johann Höchtl: reported that the call range... line causes an E488: Trailing characters
161 " error with neovim. I suspect its because neovim hasn't updated with recent
162 " vim patches. As is, this code will have problems with popup terminals
163 " instantiated before the VimEnter event runs.
164 " Ingo Karkat : E488 also in Vim 8.1.1602
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200165 let curwin = winnr()
166 let s:vimentered = 1
Bram Moolenaar8d043172014-01-23 14:24:41 +0100167 windo call s:LocalBrowse(expand("%:p"))
Bram Moolenaar477db062010-07-28 18:17:41 +0200168 exe curwin."wincmd w"
Bram Moolenaar89a9c152021-08-29 21:55:35 +0200169 else
170 " the following complicated expression comes courtesy of lacygoill; largely does the same thing as the windo and
171 " wincmd which are commented out, but avoids some side effects. Allows popup terminal before VimEnter.
172 let s:vimentered = 1
173 call range(1, winnr('$'))->map({_, v -> win_execute(win_getid(v), 'call expand("%:p")->s:LocalBrowse()')})
174 endif
Bram Moolenaar8d043172014-01-23 14:24:41 +0100175" call Dret("s:VimEnter")
Bram Moolenaar00a927d2010-05-14 23:24:24 +0200176endfun
177
178" ---------------------------------------------------------------------
Bram Moolenaar482aaeb2005-09-29 18:26:07 +0000179" NetrwStatusLine: {{{1
180fun! NetrwStatusLine()
Bram Moolenaaraf48b092006-03-14 22:51:38 +0000181" let g:stlmsg= "Xbufnr=".w:netrw_explore_bufnr." bufnr=".bufnr("%")." Xline#".w:netrw_explore_line." line#".line(".")
182 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 +0000183 let &stl= s:netrw_explore_stl
184 if exists("w:netrw_explore_bufnr")|unlet w:netrw_explore_bufnr|endif
185 if exists("w:netrw_explore_line")|unlet w:netrw_explore_line|endif
186 return ""
187 else
188 return "Match ".w:netrw_explore_mtchcnt." of ".w:netrw_explore_listlen
189 endif
190endfun
191
192" ------------------------------------------------------------------------
193" NetUserPass: set username and password for subsequent ftp transfer {{{1
194" Usage: :call NetUserPass() -- will prompt for userid and password
195" :call NetUserPass("uid") -- will prompt for password
196" :call NetUserPass("uid","password") -- sets global userid and password
197fun! NetUserPass(...)
198
199 " get/set userid
200 if a:0 == 0
201" call Dfunc("NetUserPass(a:0<".a:0.">)")
202 if !exists("g:netrw_uid") || g:netrw_uid == ""
203 " via prompt
204 let g:netrw_uid= input('Enter username: ')
205 endif
206 else " from command line
207" call Dfunc("NetUserPass(a:1<".a:1.">) {")
208 let g:netrw_uid= a:1
209 endif
210
211 " get password
212 if a:0 <= 1 " via prompt
213" call Decho("a:0=".a:0." case <=1:")
214 let g:netrw_passwd= inputsecret("Enter Password: ")
215 else " from command line
216" call Decho("a:0=".a:0." case >1: a:2<".a:2.">")
217 let g:netrw_passwd=a:2
218 endif
219" call Dret("NetUserPass")
220endfun
221
222" ------------------------------------------------------------------------
Bram Moolenaar482aaeb2005-09-29 18:26:07 +0000223" Modelines And Restoration: {{{1
224let &cpo= s:keepcpo
225unlet s:keepcpo
226" vim:ts=8 fdm=marker