blob: ed6f7dc0084cf9eb31856d4ddefeb12706f74cfe [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
Christian Brabandtf9ca1392024-02-19 20:37:11 +01005" Former Maintainer: Charles E Campbell
Bram Moolenaar482aaeb2005-09-29 18:26:07 +00006" GetLatestVimScripts: 1075 1 :AutoInstall: netrw.vim
Bram Moolenaar89a9c152021-08-29 21:55:35 +02007" Copyright: Copyright (C) 1999-2021 Charles E. Campbell {{{1
Bram Moolenaar482aaeb2005-09-29 18:26:07 +00008" Permission is hereby granted to use and distribute this code,
9" with or without modifications, provided that this copyright
10" notice is copied with it. Like anything else that's free,
11" netrw.vim, netrwPlugin.vim, and netrwSettings.vim are provided
12" *as is* and comes with no warranty of any kind, either
13" expressed or implied. By using this plugin, you agree that
14" in no event will the copyright holder be liable for any damages
15" resulting from the use of this software.
16"
17" But be doers of the Word, and not only hearers, deluding your own selves {{{1
18" (James 1:22 RSV)
19" =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000020" Load Once: {{{1
Bram Moolenaardd2a3cd2007-05-05 17:10:09 +000021if &cp || exists("g:loaded_netrwPlugin")
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000022 finish
23endif
Bram Moolenaarb7398fe2023-05-14 18:50:25 +010024let g:loaded_netrwPlugin = "v173"
Bram Moolenaar5c736222010-01-06 20:54:52 +010025let s:keepcpo = &cpo
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000026set cpo&vim
Bram Moolenaar8d043172014-01-23 14:24:41 +010027"DechoRemOn
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000028
29" ---------------------------------------------------------------------
30" Public Interface: {{{1
31
Bram Moolenaar8d043172014-01-23 14:24:41 +010032" Local Browsing Autocmds: {{{2
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000033augroup FileExplorer
34 au!
Bram Moolenaara6878372014-03-22 21:02:50 +010035 au BufLeave * if &ft != "netrw"|let w:netrw_prvfile= expand("%:p")|endif
Bram Moolenaar8d043172014-01-23 14:24:41 +010036 au BufEnter * sil call s:LocalBrowse(expand("<amatch>"))
37 au VimEnter * sil call s:VimEnter(expand("<amatch>"))
Bram Moolenaardd2a3cd2007-05-05 17:10:09 +000038 if has("win32") || has("win95") || has("win64") || has("win16")
Bram Moolenaar8d043172014-01-23 14:24:41 +010039 au BufEnter .* sil call s:LocalBrowse(expand("<amatch>"))
Bram Moolenaardd2a3cd2007-05-05 17:10:09 +000040 endif
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000041augroup END
42
43" Network Browsing Reading Writing: {{{2
44augroup Network
45 au!
Bram Moolenaar85850f32019-07-19 22:05:51 +020046 au BufReadCmd file://* call netrw#FileUrlEdit(expand("<amatch>"))
47 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 +010048 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>"))
49 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>"))
50 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 +020051 try
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010052 au SourceCmd ftp://*,rcp://*,scp://*,http://*,file://*,https://*,dav://*,davs://*,rsync://*,sftp://* exe 'Nsource '.fnameescape(expand("<amatch>"))
Bram Moolenaar589edb32019-09-20 14:38:13 +020053 catch /^Vim\%((\a\+)\)\=:E216/
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010054 au SourcePre ftp://*,rcp://*,scp://*,http://*,file://*,https://*,dav://*,davs://*,rsync://*,sftp://* exe 'Nsource '.fnameescape(expand("<amatch>"))
Bram Moolenaardd2a3cd2007-05-05 17:10:09 +000055 endtry
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000056augroup END
57
58" Commands: :Nread, :Nwrite, :NetUserPass {{{2
Bram Moolenaare0fa3742016-02-20 15:47:01 +010059com! -count=1 -nargs=* Nread let s:svpos= winsaveview()<bar>call netrw#NetRead(<count>,<f-args>)<bar>call winrestview(s:svpos)
60com! -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 +000061com! -nargs=* NetUserPass call NetUserPass(<f-args>)
Bram Moolenaare0fa3742016-02-20 15:47:01 +010062com! -nargs=* Nsource let s:svpos= winsaveview()<bar>call netrw#NetSource(<f-args>)<bar>call winrestview(s:svpos)
Bram Moolenaar85850f32019-07-19 22:05:51 +020063com! -nargs=? Ntree call netrw#SetTreetop(1,<q-args>)
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000064
Bram Moolenaar8d043172014-01-23 14:24:41 +010065" Commands: :Explore, :Sexplore, Hexplore, Vexplore, Lexplore {{{2
Bram Moolenaardd2a3cd2007-05-05 17:10:09 +000066com! -nargs=* -bar -bang -count=0 -complete=dir Explore call netrw#Explore(<count>,0,0+<bang>0,<q-args>)
67com! -nargs=* -bar -bang -count=0 -complete=dir Sexplore call netrw#Explore(<count>,1,0+<bang>0,<q-args>)
68com! -nargs=* -bar -bang -count=0 -complete=dir Hexplore call netrw#Explore(<count>,1,2+<bang>0,<q-args>)
69com! -nargs=* -bar -bang -count=0 -complete=dir Vexplore call netrw#Explore(<count>,1,4+<bang>0,<q-args>)
70com! -nargs=* -bar -count=0 -complete=dir Texplore call netrw#Explore(<count>,0,6 ,<q-args>)
71com! -nargs=* -bar -bang Nexplore call netrw#Explore(-1,0,0,<q-args>)
72com! -nargs=* -bar -bang Pexplore call netrw#Explore(-2,0,0,<q-args>)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010073com! -nargs=* -bar -bang -count=0 -complete=dir Lexplore call netrw#Lexplore(<count>,<bang>0,<q-args>)
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000074
75" Commands: NetrwSettings {{{2
Bram Moolenaarf2330482008-06-24 20:19:36 +000076com! -nargs=0 NetrwSettings call netrwSettings#NetrwSettings()
Bram Moolenaara6878372014-03-22 21:02:50 +010077com! -bang NetrwClean call netrw#Clean(<bang>0)
Bram Moolenaar482aaeb2005-09-29 18:26:07 +000078
Bram Moolenaarb8a7b562006-02-01 21:47:16 +000079" Maps:
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010080if !exists("g:netrw_nogx")
81 if maparg('gx','n') == ""
82 if !hasmapto('<Plug>NetrwBrowseX')
83 nmap <unique> gx <Plug>NetrwBrowseX
84 endif
Bram Moolenaar5ef1c6a2019-11-10 22:09:11 +010085 nno <silent> <Plug>NetrwBrowseX :call netrw#BrowseX(netrw#GX(),netrw#CheckIfRemote(netrw#GX()))<cr>
Bram Moolenaardd2a3cd2007-05-05 17:10:09 +000086 endif
Bram Moolenaar89a9c152021-08-29 21:55:35 +020087 if maparg('gx','x') == ""
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010088 if !hasmapto('<Plug>NetrwBrowseXVis')
Bram Moolenaar89a9c152021-08-29 21:55:35 +020089 xmap <unique> gx <Plug>NetrwBrowseXVis
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010090 endif
Bram Moolenaar89a9c152021-08-29 21:55:35 +020091 xno <silent> <Plug>NetrwBrowseXVis :<c-u>call netrw#BrowseXVis()<cr>
Bram Moolenaar8feef4f2015-01-07 16:57:10 +010092 endif
Bram Moolenaarb8a7b562006-02-01 21:47:16 +000093endif
Bram Moolenaara0f849e2015-10-30 14:37:44 +010094if exists("g:netrw_usetab") && g:netrw_usetab
95 if maparg('<c-tab>','n') == ""
96 nmap <unique> <c-tab> <Plug>NetrwShrink
97 endif
98 nno <silent> <Plug>NetrwShrink :call netrw#Shrink()<cr>
99endif
Bram Moolenaarb8a7b562006-02-01 21:47:16 +0000100
Bram Moolenaar482aaeb2005-09-29 18:26:07 +0000101" ---------------------------------------------------------------------
Bram Moolenaar8d043172014-01-23 14:24:41 +0100102" LocalBrowse: invokes netrw#LocalBrowseCheck() on directory buffers {{{2
Bram Moolenaar482aaeb2005-09-29 18:26:07 +0000103fun! s:LocalBrowse(dirname)
Bram Moolenaar8d043172014-01-23 14:24:41 +0100104 " Unfortunate interaction -- only DechoMsg debugging calls can be safely used here.
105 " Otherwise, the BufEnter event gets triggered when attempts to write to
Bram Moolenaar482aaeb2005-09-29 18:26:07 +0000106 " the DBG buffer are made.
Bram Moolenaar589edb32019-09-20 14:38:13 +0200107
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200108 if !exists("s:vimentered")
Bram Moolenaar8d043172014-01-23 14:24:41 +0100109 " If s:vimentered doesn't exist, then the VimEnter event hasn't fired. It will,
110 " and so s:VimEnter() will then be calling this routine, but this time with s:vimentered defined.
111" call Dfunc("s:LocalBrowse(dirname<".a:dirname.">) (s:vimentered doesn't exist)")
112" call Dret("s:LocalBrowse")
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200113 return
114 endif
Bram Moolenaar8d043172014-01-23 14:24:41 +0100115
116" call Dfunc("s:LocalBrowse(dirname<".a:dirname.">) (s:vimentered=".s:vimentered.")")
117
Bram Moolenaardd2a3cd2007-05-05 17:10:09 +0000118 if has("amiga")
119 " The check against '' is made for the Amiga, where the empty
120 " string is the current directory and not checking would break
121 " things such as the help command.
Bram Moolenaar8d043172014-01-23 14:24:41 +0100122" call Decho("(LocalBrowse) dirname<".a:dirname."> (isdirectory, amiga)")
Bram Moolenaardd2a3cd2007-05-05 17:10:09 +0000123 if a:dirname != '' && isdirectory(a:dirname)
Bram Moolenaaradc21822011-04-01 18:03:16 +0200124 sil! call netrw#LocalBrowseCheck(a:dirname)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100125 if exists("w:netrw_bannercnt") && line('.') < w:netrw_bannercnt
Bram Moolenaara6878372014-03-22 21:02:50 +0100126 exe w:netrw_bannercnt
127 endif
Bram Moolenaardd2a3cd2007-05-05 17:10:09 +0000128 endif
Bram Moolenaar8d043172014-01-23 14:24:41 +0100129
Bram Moolenaardd2a3cd2007-05-05 17:10:09 +0000130 elseif isdirectory(a:dirname)
Bram Moolenaara6878372014-03-22 21:02:50 +0100131" call Decho("(LocalBrowse) dirname<".a:dirname."> ft=".&ft." (isdirectory, not amiga)")
132" call Dredir("LocalBrowse ft last set: ","verbose set ft")
Bram Moolenaar89a9c152021-08-29 21:55:35 +0200133 " Jul 13, 2021: for whatever reason, preceding the following call with
134 " a sil! causes an unbalanced if-endif vim error
135 call netrw#LocalBrowseCheck(a:dirname)
Bram Moolenaar8feef4f2015-01-07 16:57:10 +0100136 if exists("w:netrw_bannercnt") && line('.') < w:netrw_bannercnt
Bram Moolenaara6878372014-03-22 21:02:50 +0100137 exe w:netrw_bannercnt
138 endif
Bram Moolenaar8d043172014-01-23 14:24:41 +0100139
140 else
141 " not a directory, ignore it
142" call Decho("(LocalBrowse) dirname<".a:dirname."> not a directory, ignoring...")
Bram Moolenaar482aaeb2005-09-29 18:26:07 +0000143 endif
Bram Moolenaar8d043172014-01-23 14:24:41 +0100144
145" call Dret("s:LocalBrowse")
Bram Moolenaar482aaeb2005-09-29 18:26:07 +0000146endfun
147
148" ---------------------------------------------------------------------
Bram Moolenaar8d043172014-01-23 14:24:41 +0100149" s:VimEnter: after all vim startup stuff is done, this function is called. {{{2
150" Its purpose: to look over all windows and run s:LocalBrowse() on
151" them, which checks if they're directories and will create a directory
152" listing when appropriate.
153" It also sets s:vimentered, letting s:LocalBrowse() know that s:VimEnter()
154" has already been called.
Bram Moolenaar00a927d2010-05-14 23:24:24 +0200155fun! s:VimEnter(dirname)
Bram Moolenaar8d043172014-01-23 14:24:41 +0100156" call Dfunc("s:VimEnter(dirname<".a:dirname.">) expand(%)<".expand("%").">")
Bram Moolenaar89a9c152021-08-29 21:55:35 +0200157 if has('nvim') || v:version < 802
158 " Johann Höchtl: reported that the call range... line causes an E488: Trailing characters
159 " error with neovim. I suspect its because neovim hasn't updated with recent
160 " vim patches. As is, this code will have problems with popup terminals
161 " instantiated before the VimEnter event runs.
162 " Ingo Karkat : E488 also in Vim 8.1.1602
Bram Moolenaare6ae6222013-05-21 21:01:10 +0200163 let curwin = winnr()
164 let s:vimentered = 1
Bram Moolenaar8d043172014-01-23 14:24:41 +0100165 windo call s:LocalBrowse(expand("%:p"))
Bram Moolenaar477db062010-07-28 18:17:41 +0200166 exe curwin."wincmd w"
Bram Moolenaar89a9c152021-08-29 21:55:35 +0200167 else
168 " the following complicated expression comes courtesy of lacygoill; largely does the same thing as the windo and
169 " wincmd which are commented out, but avoids some side effects. Allows popup terminal before VimEnter.
170 let s:vimentered = 1
171 call range(1, winnr('$'))->map({_, v -> win_execute(win_getid(v), 'call expand("%:p")->s:LocalBrowse()')})
172 endif
Bram Moolenaar8d043172014-01-23 14:24:41 +0100173" call Dret("s:VimEnter")
Bram Moolenaar00a927d2010-05-14 23:24:24 +0200174endfun
175
176" ---------------------------------------------------------------------
Bram Moolenaar482aaeb2005-09-29 18:26:07 +0000177" NetrwStatusLine: {{{1
178fun! NetrwStatusLine()
Bram Moolenaaraf48b092006-03-14 22:51:38 +0000179" let g:stlmsg= "Xbufnr=".w:netrw_explore_bufnr." bufnr=".bufnr("%")." Xline#".w:netrw_explore_line." line#".line(".")
180 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 +0000181 let &stl= s:netrw_explore_stl
182 if exists("w:netrw_explore_bufnr")|unlet w:netrw_explore_bufnr|endif
183 if exists("w:netrw_explore_line")|unlet w:netrw_explore_line|endif
184 return ""
185 else
186 return "Match ".w:netrw_explore_mtchcnt." of ".w:netrw_explore_listlen
187 endif
188endfun
189
190" ------------------------------------------------------------------------
191" NetUserPass: set username and password for subsequent ftp transfer {{{1
192" Usage: :call NetUserPass() -- will prompt for userid and password
193" :call NetUserPass("uid") -- will prompt for password
194" :call NetUserPass("uid","password") -- sets global userid and password
195fun! NetUserPass(...)
196
197 " get/set userid
198 if a:0 == 0
199" call Dfunc("NetUserPass(a:0<".a:0.">)")
200 if !exists("g:netrw_uid") || g:netrw_uid == ""
201 " via prompt
202 let g:netrw_uid= input('Enter username: ')
203 endif
204 else " from command line
205" call Dfunc("NetUserPass(a:1<".a:1.">) {")
206 let g:netrw_uid= a:1
207 endif
208
209 " get password
210 if a:0 <= 1 " via prompt
211" call Decho("a:0=".a:0." case <=1:")
212 let g:netrw_passwd= inputsecret("Enter Password: ")
213 else " from command line
214" call Decho("a:0=".a:0." case >1: a:2<".a:2.">")
215 let g:netrw_passwd=a:2
216 endif
217" call Dret("NetUserPass")
218endfun
219
220" ------------------------------------------------------------------------
Bram Moolenaar482aaeb2005-09-29 18:26:07 +0000221" Modelines And Restoration: {{{1
222let &cpo= s:keepcpo
223unlet s:keepcpo
224" vim:ts=8 fdm=marker