Merge pull request #31008 from zeertzjq/vim-3d7e567

vim-patch: netrw fixes
This commit is contained in:
zeertzjq 2024-10-31 19:28:24 +08:00 committed by GitHub
commit 0ab4d36254
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 258 additions and 270 deletions

View File

@ -27,6 +27,11 @@
" 2024 Sep 19 by Vim Project: mf-selection highlight uses wrong pattern (#15700) " 2024 Sep 19 by Vim Project: mf-selection highlight uses wrong pattern (#15700)
" 2024 Sep 21 by Vim Project: remove extraneous closing bracket (#15718) " 2024 Sep 21 by Vim Project: remove extraneous closing bracket (#15718)
" 2024 Oct 21 by Vim Project: remove netrwFileHandlers (#15895) " 2024 Oct 21 by Vim Project: remove netrwFileHandlers (#15895)
" 2024 Oct 27 by Vim Project: clean up gx mapping (#15721)
" 2024 Oct 30 by Vim Project: fix filetype detection for remote files (#15961)
" 2024 Oct 30 by Vim Project: fix x mapping on cygwin (#13687)
" 2024 Oct 31 by Vim Project: add netrw#Launch() and netrw#Open() (#15962)
" 2024 Oct 31 by Vim Project: fix E874 when browsing remote dir (#15964)
" }}} " }}}
" Former Maintainer: Charles E Campbell " Former Maintainer: Charles E Campbell
" GetLatestVimScripts: 1075 1 :AutoInstall: netrw.vim " GetLatestVimScripts: 1075 1 :AutoInstall: netrw.vim
@ -533,7 +538,6 @@ if !exists("g:netrw_sort_sequence")
endif endif
call s:NetrwInit("g:netrw_special_syntax" , 0) call s:NetrwInit("g:netrw_special_syntax" , 0)
call s:NetrwInit("g:netrw_ssh_browse_reject", '^total\s\+\d\+$') call s:NetrwInit("g:netrw_ssh_browse_reject", '^total\s\+\d\+$')
call s:NetrwInit("g:netrw_suppress_gx_mesg", 1)
call s:NetrwInit("g:netrw_use_noswf" , 1) call s:NetrwInit("g:netrw_use_noswf" , 1)
call s:NetrwInit("g:netrw_sizestyle" ,"b") call s:NetrwInit("g:netrw_sizestyle" ,"b")
" Default values - t-w ---------- {{{3 " Default values - t-w ---------- {{{3
@ -1153,47 +1157,35 @@ fun! netrw#Lexplore(count,rightside,...)
" if a netrw window is already on the left-side of the tab " if a netrw window is already on the left-side of the tab
" and a directory has been specified, explore with that " and a directory has been specified, explore with that
" directory. " directory.
" call Decho("case has input argument(s) (a:1<".a:1.">)")
let a1 = expand(a:1) let a1 = expand(a:1)
" call Decho("a:1<".a:1."> curwin#".curwin,'~'.expand("<slnum>"))
exe "1wincmd w" exe "1wincmd w"
if &ft == "netrw" if &ft == "netrw"
" call Decho("exe Explore ".fnameescape(a:1),'~'.expand("<slnum>"))
exe "Explore ".fnameescape(a1) exe "Explore ".fnameescape(a1)
exe curwin."wincmd w" exe curwin."wincmd w"
let s:lexplore_win= curwin let s:lexplore_win= curwin
let w:lexplore_buf= bufnr("%") let w:lexplore_buf= bufnr("%")
if exists("t:netrw_lexposn") if exists("t:netrw_lexposn")
" call Decho("forgetting t:netrw_lexposn",'~'.expand("<slnum>"))
unlet t:netrw_lexposn unlet t:netrw_lexposn
endif endif
" call Dret("netrw#Lexplore")
return return
endif endif
exe curwin."wincmd w" exe curwin."wincmd w"
else else
let a1= "" let a1= ""
" call Decho("no input arguments")
endif endif
if exists("t:netrw_lexbufnr") if exists("t:netrw_lexbufnr")
" check if t:netrw_lexbufnr refers to a netrw window " check if t:netrw_lexbufnr refers to a netrw window
let lexwinnr = bufwinnr(t:netrw_lexbufnr) let lexwinnr = bufwinnr(t:netrw_lexbufnr)
" call Decho("lexwinnr= bufwinnr(t:netrw_lexbufnr#".t:netrw_lexbufnr.")=".lexwinnr)
else else
let lexwinnr= 0 let lexwinnr= 0
" call Decho("t:netrw_lexbufnr doesn't exist")
endif endif
" call Decho("lexwinnr=".lexwinnr,'~'.expand("<slnum>"))
if lexwinnr > 0 if lexwinnr > 0
" close down netrw explorer window " close down netrw explorer window
" call Decho("t:netrw_lexbufnr#".t:netrw_lexbufnr.": close down netrw window",'~'.expand("<slnum>"))
exe lexwinnr."wincmd w" exe lexwinnr."wincmd w"
let g:netrw_winsize = -winwidth(0) let g:netrw_winsize = -winwidth(0)
let t:netrw_lexposn = winsaveview() let t:netrw_lexposn = winsaveview()
" call Decho("saving posn to t:netrw_lexposn<".string(t:netrw_lexposn).">",'~'.expand("<slnum>"))
" call Decho("saving t:netrw_lexposn",'~'.expand("<slnum>"))
close close
if lexwinnr < curwin if lexwinnr < curwin
let curwin= curwin - 1 let curwin= curwin - 1
@ -1202,11 +1194,9 @@ fun! netrw#Lexplore(count,rightside,...)
exe curwin."wincmd w" exe curwin."wincmd w"
endif endif
unlet t:netrw_lexbufnr unlet t:netrw_lexbufnr
" call Decho("unlet t:netrw_lexbufnr")
else else
" open netrw explorer window " open netrw explorer window
" call Decho("t:netrw_lexbufnr<n/a>: open netrw explorer window",'~'.expand("<slnum>"))
exe "1wincmd w" exe "1wincmd w"
let keep_altv = g:netrw_altv let keep_altv = g:netrw_altv
let g:netrw_altv = 0 let g:netrw_altv = 0
@ -1215,18 +1205,13 @@ fun! netrw#Lexplore(count,rightside,...)
let g:netrw_winsize = a:count let g:netrw_winsize = a:count
endif endif
let curfile= expand("%") let curfile= expand("%")
" call Decho("curfile<".curfile.">",'~'.expand("<slnum>"))
exe (a:rightside? "botright" : "topleft")." vertical ".((g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize) . " new" exe (a:rightside? "botright" : "topleft")." vertical ".((g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize) . " new"
" call Decho("new buf#".bufnr("%")." win#".winnr())
if a:0 > 0 && a1 != "" if a:0 > 0 && a1 != ""
" call Decho("case 1: Explore ".a1,'~'.expand("<slnum>"))
call netrw#Explore(0,0,0,a1) call netrw#Explore(0,0,0,a1)
exe "Explore ".fnameescape(a1) exe "Explore ".fnameescape(a1)
elseif curfile =~ '^\a\{3,}://' elseif curfile =~ '^\a\{3,}://'
" call Decho("case 2: Explore ".substitute(curfile,'[^/\\]*$','',''),'~'.expand("<slnum>"))
call netrw#Explore(0,0,0,substitute(curfile,'[^/\\]*$','','')) call netrw#Explore(0,0,0,substitute(curfile,'[^/\\]*$','',''))
else else
" call Decho("case 3: Explore .",'~'.expand("<slnum>"))
call netrw#Explore(0,0,0,".") call netrw#Explore(0,0,0,".")
endif endif
if a:count != 0 if a:count != 0
@ -1239,11 +1224,7 @@ fun! netrw#Lexplore(count,rightside,...)
" Since the intended use of :Lexplore is to have an always-present explorer window, the extra " Since the intended use of :Lexplore is to have an always-present explorer window, the extra
" effort to prevent mis-use of :Lex is warranted. " effort to prevent mis-use of :Lex is warranted.
set bh=wipe set bh=wipe
" call Decho("let t:netrw_lexbufnr=".t:netrw_lexbufnr)
" call Decho("t:netrw_lexposn".(exists("t:netrw_lexposn")? string(t:netrw_lexposn) : " n/a"))
if exists("t:netrw_lexposn") if exists("t:netrw_lexposn")
" call Decho("restoring to t:netrw_lexposn",'~'.expand("<slnum>"))
" call Decho("restoring posn to t:netrw_lexposn<".string(t:netrw_lexposn).">",'~'.expand("<slnum>"))
call winrestview(t:netrw_lexposn) call winrestview(t:netrw_lexposn)
unlet t:netrw_lexposn unlet t:netrw_lexposn
endif endif
@ -1256,10 +1237,8 @@ fun! netrw#Lexplore(count,rightside,...)
else else
let g:netrw_chgwin= 2 let g:netrw_chgwin= 2
endif endif
" call Decho("let g:netrw_chgwin=".g:netrw_chgwin)
endif endif
" call Dret("netrw#Lexplore")
endfun endfun
" --------------------------------------------------------------------- " ---------------------------------------------------------------------
@ -1743,29 +1722,20 @@ endfun
" --------------------------------------------------------------------- " ---------------------------------------------------------------------
" s:NetrwOptionsRestore: restore options (based on prior s:NetrwOptionsSave) {{{2 " s:NetrwOptionsRestore: restore options (based on prior s:NetrwOptionsSave) {{{2
fun! s:NetrwOptionsRestore(vt) fun! s:NetrwOptionsRestore(vt)
" call Dfunc("s:NetrwOptionsRestore(vt<".a:vt.">) win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> winnr($)=".winnr("$"))
" call Decho("(s:NetrwOptionsRestore) lines=".&lines)
" 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>"))
if !exists("{a:vt}netrw_optionsave") if !exists("{a:vt}netrw_optionsave")
" call Decho("case ".a:vt."netrw_optionsave : doesn't exist",'~'.expand("<slnum>")) " filereadable() returns zero for remote files (e.g. scp://user@localhost//etc/fstab)
" Note: @ may not be in 'isfname', so '^\w\+://\f\+/' may not match
" filereadable() returns zero for remote files (e.g. scp://localhost//etc/fstab) if filereadable(expand("%")) || expand("%") =~# '^\w\+://\f\+'
if filereadable(expand("%")) || expand("%") =~# '^\w\+://\f\+/'
" call Decho("..doing filetype detect anyway")
filetype detect filetype detect
" 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>"))
else else
setl ft=netrw setl ft=netrw
endif endif
" call Decho("..ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
" call Dret("s:NetrwOptionsRestore : ".a:vt."netrw_optionsave doesn't exist")
return return
endif endif
unlet {a:vt}netrw_optionsave unlet {a:vt}netrw_optionsave
if exists("+acd") if exists("+acd")
if exists("{a:vt}netrw_acdkeep") if exists("{a:vt}netrw_acdkeep")
" call Decho("g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("<slnum>"))
let curdir = getcwd() let curdir = getcwd()
let &l:acd = {a:vt}netrw_acdkeep let &l:acd = {a:vt}netrw_acdkeep
unlet {a:vt}netrw_acdkeep unlet {a:vt}netrw_acdkeep
@ -1774,53 +1744,43 @@ fun! s:NetrwOptionsRestore(vt)
endif endif
endif endif
endif endif
" call Decho("(s:NetrwOptionsRestore) #1 lines=".&lines)
call s:NetrwRestoreSetting(a:vt."netrw_aikeep","&l:ai") call s:NetrwRestoreSetting(a:vt."netrw_aikeep","&l:ai")
call s:NetrwRestoreSetting(a:vt."netrw_awkeep","&l:aw") call s:NetrwRestoreSetting(a:vt."netrw_awkeep","&l:aw")
call s:NetrwRestoreSetting(a:vt."netrw_blkeep","&l:bl") call s:NetrwRestoreSetting(a:vt."netrw_blkeep","&l:bl")
call s:NetrwRestoreSetting(a:vt."netrw_btkeep","&l:bt") call s:NetrwRestoreSetting(a:vt."netrw_btkeep","&l:bt")
call s:NetrwRestoreSetting(a:vt."netrw_bombkeep","&l:bomb") call s:NetrwRestoreSetting(a:vt."netrw_bombkeep","&l:bomb")
" call Decho("(s:NetrwOptionsRestore) #2 lines=".&lines)
call s:NetrwRestoreSetting(a:vt."netrw_cedit","&cedit") call s:NetrwRestoreSetting(a:vt."netrw_cedit","&cedit")
call s:NetrwRestoreSetting(a:vt."netrw_cikeep","&l:ci") call s:NetrwRestoreSetting(a:vt."netrw_cikeep","&l:ci")
call s:NetrwRestoreSetting(a:vt."netrw_cinkeep","&l:cin") call s:NetrwRestoreSetting(a:vt."netrw_cinkeep","&l:cin")
call s:NetrwRestoreSetting(a:vt."netrw_cinokeep","&l:cino") call s:NetrwRestoreSetting(a:vt."netrw_cinokeep","&l:cino")
call s:NetrwRestoreSetting(a:vt."netrw_comkeep","&l:com") call s:NetrwRestoreSetting(a:vt."netrw_comkeep","&l:com")
" call Decho("(s:NetrwOptionsRestore) #3 lines=".&lines)
call s:NetrwRestoreSetting(a:vt."netrw_cpokeep","&l:cpo") call s:NetrwRestoreSetting(a:vt."netrw_cpokeep","&l:cpo")
call s:NetrwRestoreSetting(a:vt."netrw_diffkeep","&l:diff") call s:NetrwRestoreSetting(a:vt."netrw_diffkeep","&l:diff")
call s:NetrwRestoreSetting(a:vt."netrw_fenkeep","&l:fen") call s:NetrwRestoreSetting(a:vt."netrw_fenkeep","&l:fen")
if exists("g:netrw_ffkeep") && g:netrw_ffkeep if exists("g:netrw_ffkeep") && g:netrw_ffkeep
call s:NetrwRestoreSetting(a:vt."netrw_ffkeep")","&l:ff") call s:NetrwRestoreSetting(a:vt."netrw_ffkeep")","&l:ff")
endif endif
" call Decho("(s:NetrwOptionsRestore) #4 lines=".&lines)
call s:NetrwRestoreSetting(a:vt."netrw_fokeep" ,"&l:fo") call s:NetrwRestoreSetting(a:vt."netrw_fokeep" ,"&l:fo")
call s:NetrwRestoreSetting(a:vt."netrw_gdkeep" ,"&l:gd") call s:NetrwRestoreSetting(a:vt."netrw_gdkeep" ,"&l:gd")
call s:NetrwRestoreSetting(a:vt."netrw_gokeep" ,"&go") call s:NetrwRestoreSetting(a:vt."netrw_gokeep" ,"&go")
call s:NetrwRestoreSetting(a:vt."netrw_hidkeep" ,"&l:hidden") call s:NetrwRestoreSetting(a:vt."netrw_hidkeep" ,"&l:hidden")
" call Decho("(s:NetrwOptionsRestore) #5 lines=".&lines)
call s:NetrwRestoreSetting(a:vt."netrw_imkeep" ,"&l:im") call s:NetrwRestoreSetting(a:vt."netrw_imkeep" ,"&l:im")
call s:NetrwRestoreSetting(a:vt."netrw_iskkeep" ,"&l:isk") call s:NetrwRestoreSetting(a:vt."netrw_iskkeep" ,"&l:isk")
" call Decho("(s:NetrwOptionsRestore) #6 lines=".&lines)
call s:NetrwRestoreSetting(a:vt."netrw_lines" ,"&lines") call s:NetrwRestoreSetting(a:vt."netrw_lines" ,"&lines")
" call Decho("(s:NetrwOptionsRestore) #7 lines=".&lines)
call s:NetrwRestoreSetting(a:vt."netrw_lskeep" ,"&l:ls") call s:NetrwRestoreSetting(a:vt."netrw_lskeep" ,"&l:ls")
call s:NetrwRestoreSetting(a:vt."netrw_makeep" ,"&l:ma") call s:NetrwRestoreSetting(a:vt."netrw_makeep" ,"&l:ma")
call s:NetrwRestoreSetting(a:vt."netrw_magickeep","&l:magic") call s:NetrwRestoreSetting(a:vt."netrw_magickeep","&l:magic")
call s:NetrwRestoreSetting(a:vt."netrw_modkeep" ,"&l:mod") call s:NetrwRestoreSetting(a:vt."netrw_modkeep" ,"&l:mod")
call s:NetrwRestoreSetting(a:vt."netrw_nukeep" ,"&l:nu") call s:NetrwRestoreSetting(a:vt."netrw_nukeep" ,"&l:nu")
" call Decho("(s:NetrwOptionsRestore) #8 lines=".&lines)
call s:NetrwRestoreSetting(a:vt."netrw_rnukeep" ,"&l:rnu") call s:NetrwRestoreSetting(a:vt."netrw_rnukeep" ,"&l:rnu")
call s:NetrwRestoreSetting(a:vt."netrw_repkeep" ,"&l:report") call s:NetrwRestoreSetting(a:vt."netrw_repkeep" ,"&l:report")
call s:NetrwRestoreSetting(a:vt."netrw_rokeep" ,"&l:ro") call s:NetrwRestoreSetting(a:vt."netrw_rokeep" ,"&l:ro")
call s:NetrwRestoreSetting(a:vt."netrw_selkeep" ,"&l:sel") call s:NetrwRestoreSetting(a:vt."netrw_selkeep" ,"&l:sel")
" call Decho("(s:NetrwOptionsRestore) #9 lines=".&lines)
call s:NetrwRestoreSetting(a:vt."netrw_spellkeep","&l:spell") call s:NetrwRestoreSetting(a:vt."netrw_spellkeep","&l:spell")
call s:NetrwRestoreSetting(a:vt."netrw_twkeep" ,"&l:tw") call s:NetrwRestoreSetting(a:vt."netrw_twkeep" ,"&l:tw")
call s:NetrwRestoreSetting(a:vt."netrw_wigkeep" ,"&l:wig") call s:NetrwRestoreSetting(a:vt."netrw_wigkeep" ,"&l:wig")
call s:NetrwRestoreSetting(a:vt."netrw_wrapkeep" ,"&l:wrap") call s:NetrwRestoreSetting(a:vt."netrw_wrapkeep" ,"&l:wrap")
call s:NetrwRestoreSetting(a:vt."netrw_writekeep","&l:write") call s:NetrwRestoreSetting(a:vt."netrw_writekeep","&l:write")
" call Decho("(s:NetrwOptionsRestore) #10 lines=".&lines)
call s:NetrwRestoreSetting("s:yykeep","@@") call s:NetrwRestoreSetting("s:yykeep","@@")
" former problem: start with liststyle=0; press <i> : result, following line resets l:ts. " former problem: start with liststyle=0; press <i> : result, following line resets l:ts.
" Fixed; in s:PerformListing, when w:netrw_liststyle is s:LONGLIST, will use a printf to pad filename with spaces " Fixed; in s:PerformListing, when w:netrw_liststyle is s:LONGLIST, will use a printf to pad filename with spaces
@ -1853,22 +1813,12 @@ fun! s:NetrwOptionsRestore(vt)
endif endif
call s:NetrwRestoreSetting(a:vt."netrw_slashkeep","@/") call s:NetrwRestoreSetting(a:vt."netrw_slashkeep","@/")
" call Decho("g:netrw_keepdir=".g:netrw_keepdir.": getcwd<".getcwd()."> acd=".&acd,'~'.expand("<slnum>"))
" call Decho("fo=".&fo.(exists("+acd")? " acd=".&acd : " acd doesn't exist"),'~'.expand("<slnum>"))
" call Decho("ro=".&l:ro." ma=".&l:ma." mod=".&l:mod." wrap=".&l:wrap." (filename<".expand("%")."> win#".winnr()." ft<".&ft.">)",'~'.expand("<slnum>"))
" call Decho("diff=".&l:diff." win#".winnr()." w:netrw_diffkeep=".(exists("w:netrw_diffkeep")? w:netrw_diffkeep : "doesn't exist"),'~'.expand("<slnum>"))
" call Decho("ts=".&l:ts,'~'.expand("<slnum>"))
" Moved the filetype detect here from NetrwGetFile() because remote files " Moved the filetype detect here from NetrwGetFile() because remote files
" were having their filetype detect-generated settings overwritten by " were having their filetype detect-generated settings overwritten by
" NetrwOptionRestore. " NetrwOptionRestore.
if &ft != "netrw" if &ft != "netrw"
" call Decho("before: filetype detect (ft=".&ft.")",'~'.expand("<slnum>"))
filetype detect filetype detect
" call Decho("after : filetype detect (ft=".&ft.")",'~'.expand("<slnum>"))
endif endif
" call Decho("(s:NetrwOptionsRestore) lines=".&lines)
" 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>"))
" call Dret("s:NetrwOptionsRestore : tab#".tabpagenr()." win#".winnr()." buf#".bufnr("%")."<".bufname("%")."> modified=".&modified." modifiable=".&modifiable." readonly=".&readonly)
endfun endfun
" --------------------------------------------------------------------- " ---------------------------------------------------------------------
@ -5244,32 +5194,132 @@ fun! s:NetrwBrowseUpDir(islocal)
" call Dret("s:NetrwBrowseUpDir") " call Dret("s:NetrwBrowseUpDir")
endfun endfun
func s:redir()
" set up redirection (avoids browser messages)
" by default if not set, g:netrw_suppress_gx_mesg is true
if get(g:, 'netrw_suppress_gx_mesg', 1)
if &srr =~# "%s"
return printf(&srr, has("win32") ? "nul" : "/dev/null")
else
return &srr .. (has("win32") ? "nul" : "/dev/null")
endif
endif
return ''
endfunc
if has('unix')
if has('win32unix')
" Cygwin provides cygstart
if executable('cygstart')
fun! netrw#Launch(args)
exe 'silent ! cygstart --hide' a:args s:redir() | redraw!
endfun
elseif !empty($MSYSTEM) && executable('start')
" MSYS2/Git Bash comes by default without cygstart; see
" https://www.msys2.org/wiki/How-does-MSYS2-differ-from-Cygwin
" Instead it provides /usr/bin/start script running `cmd.exe //c start`
" Adding "" //b` sets void title, hides cmd window and blocks path conversion
" of /b to \b\ " by MSYS2; see https://www.msys2.org/docs/filesystem-paths/
fun! netrw#Launch(args)
exe 'silent !start "" //b' a:args s:redir() | redraw!
endfun
else
" imitate /usr/bin/start script for other environments and hope for the best
fun! netrw#Launch(args)
exe 'silent !cmd //c start "" //b' a:args s:redir() | redraw!
endfun
endif
elseif exists('$WSL_DISTRO_NAME') " use cmd.exe to start GUI apps in WSL
fun! netrw#Launch(args)
let args = a:args
exe 'silent !' ..
\ ((args =~? '\v<\f+\.(exe|com|bat|cmd)>') ?
\ 'cmd.exe /c start "" /b ' .. args :
\ 'nohup ' .. args .. ' ' .. s:redir() .. ' &')
\ | redraw!
endfun
else
fun! netrw#Launch(args)
exe ':silent ! nohup' a:args s:redir() '&' | redraw!
endfun
endif
elseif has('win32')
fun! netrw#Launch(args)
exe 'silent !' .. (&shell =~? '\<cmd\.exe\>' ? '' : 'cmd.exe /c')
\ 'start "" /b' a:args s:redir() | redraw!
endfun
else
fun! netrw#Launch(dummy)
echom 'No common launcher found'
endfun
endif
" Git Bash
if has('win32unix')
" (cyg)start suffices
let s:os_viewer = ''
" Windows / WSL
elseif executable('explorer.exe')
let s:os_viewer = 'explorer.exe'
" Linux / BSD
elseif executable('xdg-open')
let s:os_viewer = 'xdg-open'
" MacOS
elseif executable('open')
let s:os_viewer = 'open'
endif
fun! s:viewer()
if exists('g:netrw_browsex_viewer') && executable(g:netrw_browsex_viewer)
" extract any viewing options. Assumes that they're set apart by spaces.
" call Decho("extract any viewing options from g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
if g:netrw_browsex_viewer =~ '\s'
let viewer = substitute(g:netrw_browsex_viewer,'\s.*$','','')
let viewopt = substitute(g:netrw_browsex_viewer,'^\S\+\s*','','')." "
let oviewer = ''
let cnt = 1
while !executable(viewer) && viewer != oviewer
let viewer = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\1','')
let viewopt = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\3','')." "
let cnt = cnt + 1
let oviewer = viewer
" call Decho("!exe: viewer<".viewer."> viewopt<".viewopt.">",'~'.expand("<slnum>"))
endwhile
else
let viewer = g:netrw_browsex_viewer
let viewopt = ""
endif
" call Decho("viewer<".viewer."> viewopt<".viewopt.">",'~'.expand("<slnum>"))
return viewer .. ' ' .. viewopt
else
if !exists('s:os_viewer')
call netrw#ErrorMsg(s:ERROR,"No program to open this path found. See :help Open for more information.",106)
else
return s:os_viewer
endif
endif
endfun
fun! netrw#Open(file) abort
call netrw#Launch(s:viewer() .. ' ' .. shellescape(a:file, 1))
endf
if !exists('g:netrw_regex_url')
let g:netrw_regex_url = '\%(\%(http\|ftp\|irc\)s\?\|file\)://\S\{-}'
endif
" --------------------------------------------------------------------- " ---------------------------------------------------------------------
" netrw#BrowseX: (implements "x" and "gx") executes a special "viewer" script or program for the {{{2 " netrw#BrowseX: (implements "x" and "gx") executes a special "viewer" script or program for the {{{2
" given filename; typically this means given their extension. " given filename; typically this means given their extension.
" 0=local, 1=remote " 0=local, 1=remote
fun! netrw#BrowseX(fname,remote) fun! netrw#BrowseX(fname,remote)
let use_ctrlo= 1
" call Dfunc("netrw#BrowseX(fname<".a:fname."> remote=".a:remote.") implements x and gx maps")
if a:remote == 0 && isdirectory(a:fname) if a:remote == 0 && isdirectory(a:fname)
" if its really just a local directory, then do a "gf" instead " if its really just a local directory, then do a "gf" instead
" call Decho("remote≡0 and a:fname<".a:fname."> ".(isdirectory(a:fname)? "is a directory" : "is not a directory"),'~'.expand("<slnum>"))
" call Decho("..appears to be a local directory; using e ".a:fname." instead",'~'.expand("<slnum>"))
exe "e ".a:fname exe "e ".a:fname
" call Dret("netrw#BrowseX")
return
elseif a:remote == 1 && a:fname !~ '^https\=:' && a:fname =~ '/$' elseif a:remote == 1 && a:fname !~ '^https\=:' && a:fname =~ '/$'
" remote directory, not a webpage access, looks like an attempt to do a directory listing " remote directory, not a webpage access, looks like an attempt to do a directory listing
" call Decho("remote≡1 and a:fname<".a:fname.">",'~'.expand("<slnum>"))
" call Decho("..and fname ".((a:fname =~ '^https\=:')? 'matches' : 'does not match').'^https\=:','~'.expand("<slnum>"))
" call Decho("..and fname ".((a:fname =~ '/$')? 'matches' : 'does not match').' /$','~'.expand("<slnum>"))
" call Decho("..appears to be a remote directory listing request; using gf instead",'~'.expand("<slnum>"))
norm! gf norm! gf
" call Dret("netrw#BrowseX")
return
endif endif
" call Decho("not a local file nor a webpage request",'~'.expand("<slnum>"))
if exists("g:netrw_browsex_viewer") && exists("g:netrw_browsex_support_remote") && !g:netrw_browsex_support_remote if exists("g:netrw_browsex_viewer") && exists("g:netrw_browsex_support_remote") && !g:netrw_browsex_support_remote
let remote = a:remote let remote = a:remote
@ -5279,7 +5329,6 @@ fun! netrw#BrowseX(fname,remote)
let ykeep = @@ let ykeep = @@
let screenposn = winsaveview() let screenposn = winsaveview()
" call Decho("saving posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
" need to save and restore aw setting as gx can invoke this function from non-netrw buffers " need to save and restore aw setting as gx can invoke this function from non-netrw buffers
let awkeep = &aw let awkeep = &aw
@ -5290,22 +5339,18 @@ fun! netrw#BrowseX(fname,remote)
if exists("g:Netrw_corehandler") if exists("g:Netrw_corehandler")
if type(g:Netrw_corehandler) == 2 if type(g:Netrw_corehandler) == 2
" g:Netrw_corehandler is a function reference (see :help Funcref) " g:Netrw_corehandler is a function reference (see :help Funcref)
" call Decho("g:Netrw_corehandler is a funcref",'~'.expand("<slnum>"))
call g:Netrw_corehandler(s:NetrwFile(a:fname)) call g:Netrw_corehandler(s:NetrwFile(a:fname))
elseif type(g:Netrw_corehandler) == 3 elseif type(g:Netrw_corehandler) == 3
" g:Netrw_corehandler is a List of function references (see :help Funcref) " g:Netrw_corehandler is a List of function references (see :help Funcref)
" call Decho("g:Netrw_corehandler is a List",'~'.expand("<slnum>"))
for Fncref in g:Netrw_corehandler for Fncref in g:Netrw_corehandler
if type(Fncref) == 2 if type(Fncref) == 2
call Fncref(a:fname) call Fncref(a:fname)
endif endif
endfor endfor
endif endif
" call Decho("restoring posn: screenposn<".string(screenposn).">,'~'.expand("<slnum>"))"
call winrestview(screenposn) call winrestview(screenposn)
let @@= ykeep let @@= ykeep
let &aw= awkeep let &aw= awkeep
" call Dret("netrw#BrowseX : coredump handler invoked")
return return
endif endif
endif endif
@ -5319,163 +5364,35 @@ fun! netrw#BrowseX(fname,remote)
if exten =~ "[\\/]" if exten =~ "[\\/]"
let exten= "" let exten= ""
endif endif
" call Decho("exten<".exten.">",'~'.expand("<slnum>"))
if remote == 1 if remote == 1
" create a local copy " create a local copy
" call Decho("remote: remote=".remote.": create a local copy of <".a:fname.">",'~'.expand("<slnum>"))
setl bh=delete setl bh=delete
call netrw#NetRead(3,a:fname) call netrw#NetRead(3,a:fname)
" attempt to rename tempfile " attempt to rename tempfile
let basename= substitute(a:fname,'^\(.*\)/\(.*\)\.\([^.]*\)$','\2','') let basename= substitute(a:fname,'^\(.*\)/\(.*\)\.\([^.]*\)$','\2','')
let newname = substitute(s:netrw_tmpfile,'^\(.*\)/\(.*\)\.\([^.]*\)$','\1/'.basename.'.\3','') let newname = substitute(s:netrw_tmpfile,'^\(.*\)/\(.*\)\.\([^.]*\)$','\1/'.basename.'.\3','')
" call Decho("basename<".basename.">",'~'.expand("<slnum>"))
" call Decho("newname <".newname.">",'~'.expand("<slnum>"))
if s:netrw_tmpfile != newname && newname != "" if s:netrw_tmpfile != newname && newname != ""
if rename(s:netrw_tmpfile,newname) == 0 if rename(s:netrw_tmpfile,newname) == 0
" renaming succeeded " renaming succeeded
" call Decho("renaming succeeded (tmpfile<".s:netrw_tmpfile."> to <".newname.">)")
let fname= newname let fname= newname
else else
" renaming failed " renaming failed
" call Decho("renaming failed (tmpfile<".s:netrw_tmpfile."> to <".newname.">)")
let fname= s:netrw_tmpfile let fname= s:netrw_tmpfile
endif endif
else else
let fname= s:netrw_tmpfile let fname= s:netrw_tmpfile
endif endif
else else
" call Decho("local: remote=".remote.": handling local copy of <".a:fname.">",'~'.expand("<slnum>"))
let fname= a:fname let fname= a:fname
" special ~ handler for local " special ~ handler for local
if fname =~ '^\~' && expand("$HOME") != "" if fname =~ '^\~' && expand("$HOME") != ""
" call Decho('invoking special ~ handler','~'.expand("<slnum>"))
let fname= s:NetrwFile(substitute(fname,'^\~',expand("$HOME"),'')) let fname= s:NetrwFile(substitute(fname,'^\~',expand("$HOME"),''))
endif endif
endif endif
" call Decho("fname<".fname.">",'~'.expand("<slnum>"))
" call Decho("exten<".exten."> "."netrwFileHandlers#NFH_".exten."():exists=".exists("*netrwFileHandlers#NFH_".exten),'~'.expand("<slnum>"))
" set up redirection (avoids browser messages) " although shellescape(..., 1) is used in netrw#Open(), it's insufficient
" by default, g:netrw_suppress_gx_mesg is true call netrw#Open(escape(fname, '#%'))
if g:netrw_suppress_gx_mesg
if &srr =~ "%s"
if has("win32")
let redir= substitute(&srr,"%s","nul","")
else
let redir= substitute(&srr,"%s","/dev/null","")
endif
elseif has("win32")
let redir= &srr . "nul"
else
let redir= &srr . "/dev/null"
endif
else
let redir= ""
endif
" call Decho("set up redirection: redir{".redir."} srr{".&srr."}",'~'.expand("<slnum>"))
" extract any viewing options. Assumes that they're set apart by spaces.
if exists("g:netrw_browsex_viewer")
" call Decho("extract any viewing options from g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
if g:netrw_browsex_viewer =~ '\s'
let viewer = substitute(g:netrw_browsex_viewer,'\s.*$','','')
let viewopt = substitute(g:netrw_browsex_viewer,'^\S\+\s*','','')." "
let oviewer = ''
let cnt = 1
while !executable(viewer) && viewer != oviewer
let viewer = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\1','')
let viewopt = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\3','')." "
let cnt = cnt + 1
let oviewer = viewer
" call Decho("!exe: viewer<".viewer."> viewopt<".viewopt.">",'~'.expand("<slnum>"))
endwhile
else
let viewer = g:netrw_browsex_viewer
let viewopt = ""
endif
" call Decho("viewer<".viewer."> viewopt<".viewopt.">",'~'.expand("<slnum>"))
endif
" execute the file handler
" call Decho("execute the file handler (if any)",'~'.expand("<slnum>"))
if exists("g:netrw_browsex_viewer") && executable(viewer)
" call Decho("(netrw#BrowseX) g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
call s:NetrwExe("sil !".viewer." ".viewopt.s:ShellEscape(fname,1).redir)
let ret= v:shell_error
elseif has("win32")
" call Decho("(netrw#BrowseX) win".(has("win32")? "32" : "64"),'~'.expand("<slnum>"))
if executable("start")
call s:NetrwExe('sil! !start rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(fname,1))
elseif executable("rundll32")
call s:NetrwExe('sil! !rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(fname,1))
else
call netrw#ErrorMsg(s:WARNING,"rundll32 not on path",74)
endif
let ret= v:shell_error
elseif has("win32unix")
let winfname= 'c:\cygwin'.substitute(fname,'/','\\','g')
" call Decho("(netrw#BrowseX) cygwin: winfname<".s:ShellEscape(winfname,1).">",'~'.expand("<slnum>"))
if executable("start")
" call Decho("(netrw#BrowseX) win32unix+start",'~'.expand("<slnum>"))
call s:NetrwExe('sil !start rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(winfname,1))
elseif executable("rundll32")
" call Decho("(netrw#BrowseX) win32unix+rundll32",'~'.expand("<slnum>"))
call s:NetrwExe('sil !rundll32 url.dll,FileProtocolHandler '.s:ShellEscape(winfname,1))
elseif executable("cygstart")
" call Decho("(netrw#BrowseX) win32unix+cygstart",'~'.expand("<slnum>"))
call s:NetrwExe('sil !cygstart '.s:ShellEscape(fname,1))
else
call netrw#ErrorMsg(s:WARNING,"rundll32 not on path",74)
endif
let ret= v:shell_error
elseif has("unix") && $DESKTOP_SESSION == "mate" && executable("atril")
" call Decho("(netrw#BrowseX) unix and atril",'~'.expand("<slnum>"))
if a:fname =~ '^https\=://'
" atril does not appear to understand how to handle html -- so use gvim to edit the document
let use_ctrlo= 0
" call Decho("fname<".fname.">")
" call Decho("a:fname<".a:fname.">")
call s:NetrwExe("sil! !gvim ".fname.' -c "keepj keepalt file '.fnameescape(a:fname).'"')
else
call s:NetrwExe("sil !atril ".s:ShellEscape(fname,1).redir)
endif
let ret= v:shell_error
elseif has("unix") && executable("kfmclient") && s:CheckIfKde()
" call Decho("(netrw#BrowseX) unix and kfmclient",'~'.expand("<slnum>"))
call s:NetrwExe("sil !kfmclient exec ".s:ShellEscape(fname,1)." ".redir)
let ret= v:shell_error
elseif has("unix") && executable("exo-open") && executable("xdg-open") && executable("setsid")
" call Decho("(netrw#BrowseX) unix, exo-open, xdg-open",'~'.expand("<slnum>"))
call s:NetrwExe("sil !setsid xdg-open ".s:ShellEscape(fname,1).redir.'&')
let ret= v:shell_error
elseif has("unix") && executable("xdg-open")
" call Decho("(netrw#BrowseX) unix and xdg-open",'~'.expand("<slnum>"))
call s:NetrwExe("sil !xdg-open ".s:ShellEscape(fname,1).redir.'&')
let ret= v:shell_error
elseif has("macunix") && executable("open")
" call Decho("(netrw#BrowseX) macunix and open",'~'.expand("<slnum>"))
call s:NetrwExe("sil !open ".s:ShellEscape(fname,1)." ".redir)
let ret= v:shell_error
else
call netrw#ErrorMsg(s:ERROR, "Couldn't find a program to open '".a:fname."'", 0)
let ret=0
endif
if ret
call netrw#ErrorMsg(s:ERROR, "Failed to open '".a:fname."'", 0)
endif
" restoring redraw! after external file handlers
redraw!
" cleanup: remove temporary file, " cleanup: remove temporary file,
" delete current buffer if success with handler, " delete current buffer if success with handler,
@ -5483,7 +5400,6 @@ fun! netrw#BrowseX(fname,remote)
" Feb 12, 2008: had to de-activate removal of " Feb 12, 2008: had to de-activate removal of
" temporary file because it wasn't getting seen. " temporary file because it wasn't getting seen.
" if remote == 1 && fname != a:fname " if remote == 1 && fname != a:fname
"" call Decho("deleting temporary file<".fname.">",'~'.expand("<slnum>"))
" call s:NetrwDelete(fname) " call s:NetrwDelete(fname)
" endif " endif
@ -5492,16 +5408,11 @@ fun! netrw#BrowseX(fname,remote)
if g:netrw_use_noswf if g:netrw_use_noswf
setl noswf setl noswf
endif endif
if use_ctrlo exe "sil! NetrwKeepj norm! \<c-o>"
exe "sil! NetrwKeepj norm! \<c-o>"
endif
endif endif
" call Decho("restoring posn to screenposn<".string(screenposn).">",'~'.expand("<slnum>"))
call winrestview(screenposn) call winrestview(screenposn)
let @@ = ykeep let @@ = ykeep
let &aw= awkeep let &aw= awkeep
" call Dret("netrw#BrowseX")
endfun endfun
" --------------------------------------------------------------------- " ---------------------------------------------------------------------
@ -5513,12 +5424,37 @@ fun! netrw#GX()
if &ft == "netrw" if &ft == "netrw"
let fname= s:NetrwGetWord() let fname= s:NetrwGetWord()
else else
let fname= expand((exists("g:netrw_gx")? g:netrw_gx : '<cfile>')) let fname= exists("g:netrw_gx")? expand(g:netrw_gx) : s:GetURL()
endif endif
" call Dret("netrw#GX <".fname.">") " call Dret("netrw#GX <".fname.">")
return fname return fname
endfun endfun
fun! s:GetURL() abort
let URL = ''
if exists('*Netrw_get_URL_' .. &filetype)
let URL = call('Netrw_get_URL_' .. &filetype, [])
endif
if !empty(URL) | return URL | endif
" URLs end in letter, digit or forward slash
let URL = matchstr(expand("<cWORD>"), '\<' .. g:netrw_regex_url .. '\ze[^A-Za-z0-9/]*$')
if !empty(URL) | return URL | endif
" Is it a file in the current work dir ...
let file = expand("<cfile>")
if filereadable(file) | return file | endif
" ... or in that of the current buffer?
let path = fnamemodify(expand('%'), ':p')
if isdirectory(path)
let dir = path
elseif filereadable(path)
let dir = fnamemodify(path, ':h')
endif
if exists('dir') && filereadable(dir..'/'..file) | return dir..'/'..file | endif
return ''
endf
" --------------------------------------------------------------------- " ---------------------------------------------------------------------
" netrw#BrowseXVis: used by gx in visual mode to select a file for browsing {{{2 " netrw#BrowseXVis: used by gx in visual mode to select a file for browsing {{{2
fun! netrw#BrowseXVis() fun! netrw#BrowseXVis()
@ -5753,7 +5689,7 @@ fun! s:NetrwGlob(direntry,expr,pare)
endif endif
let w:netrw_liststyle= keep_liststyle let w:netrw_liststyle= keep_liststyle
else else
let path= s:ComposePath(fnameescape(a:direntry),a:expr) let path= s:ComposePath(fnameescape(a:direntry), a:expr)
if has("win32") if has("win32")
" escape [ so it is not detected as wildcard character, see :h wildcard " escape [ so it is not detected as wildcard character, see :h wildcard
let path= substitute(path, '[', '[[]', 'g') let path= substitute(path, '[', '[[]', 'g')
@ -5767,7 +5703,6 @@ fun! s:NetrwGlob(direntry,expr,pare)
let filelist= map(filelist,'substitute(v:val, "^.*/", "", "")') let filelist= map(filelist,'substitute(v:val, "^.*/", "", "")')
endif endif
endif endif
" call Dret("s:NetrwGlob ".string(filelist))
return filelist return filelist
endfun endfun
@ -6670,6 +6605,7 @@ fun! s:NetrwMaps(islocal)
nnoremap <buffer> <silent> <nowait> U :<c-u>call <SID>NetrwBookHistHandler(5,b:netrw_curdir)<cr> nnoremap <buffer> <silent> <nowait> U :<c-u>call <SID>NetrwBookHistHandler(5,b:netrw_curdir)<cr>
nnoremap <buffer> <silent> <nowait> v :call <SID>NetrwSplit(2)<cr> nnoremap <buffer> <silent> <nowait> v :call <SID>NetrwSplit(2)<cr>
nnoremap <buffer> <silent> <nowait> x :<c-u>call netrw#BrowseX(<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()),1)<cr> nnoremap <buffer> <silent> <nowait> x :<c-u>call netrw#BrowseX(<SID>NetrwBrowseChgDir(0,<SID>NetrwGetWord()),1)<cr>
nmap <buffer> <nowait> gx x
if !hasmapto('<Plug>NetrwHideEdit') if !hasmapto('<Plug>NetrwHideEdit')
nmap <buffer> <c-h> <Plug>NetrwHideEdit nmap <buffer> <c-h> <Plug>NetrwHideEdit
endif endif
@ -8241,7 +8177,7 @@ fun! netrw#Shrink()
elseif winwidth(bufwinnr(t:netrw_lexbufnr)) >= 0 elseif winwidth(bufwinnr(t:netrw_lexbufnr)) >= 0
exe "vert resize ".t:netrw_winwidth exe "vert resize ".t:netrw_winwidth
" call Decho("vert resize ".t:netrw_winwidth,'~'.expand("<slnum>")) " call Decho("vert resize ".t:netrw_winwidth,'~'.expand("<slnum>"))
else else
call netrw#Lexplore(0,0) call netrw#Lexplore(0,0)
endif endif
@ -8558,7 +8494,7 @@ fun! s:NetrwPrevWinOpen(islocal)
" call Decho("COMBAK#11: mod=".&mod) " call Decho("COMBAK#11: mod=".&mod)
" call Decho("wincmd p (now in win#".winnr().") curdir<".curdir.">",'~'.expand("<slnum>")) " call Decho("wincmd p (now in win#".winnr().") curdir<".curdir.">",'~'.expand("<slnum>"))
" call Decho("COMBAK#12: mod=".&mod) " call Decho("COMBAK#12: mod=".&mod)
if exists("s:lexplore_win") && s:lexplore_win == winnr() if exists("s:lexplore_win") && s:lexplore_win == winnr()
" whoops -- user trying to open file in the Lexplore window. " whoops -- user trying to open file in the Lexplore window.
" Use Lexplore's opening-file window instead. " Use Lexplore's opening-file window instead.
@ -9539,22 +9475,16 @@ endfun
" Called by s:PerformListing() " Called by s:PerformListing()
fun! s:NetrwTreeListing(dirname) fun! s:NetrwTreeListing(dirname)
if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST if exists("w:netrw_liststyle") && w:netrw_liststyle == s:TREELIST
" call Dfunc("s:NetrwTreeListing() bufname<".expand("%").">")
" call Decho("curdir<".a:dirname.">",'~'.expand("<slnum>"))
" call Decho("win#".winnr().": w:netrw_treetop ".(exists("w:netrw_treetop")? "exists" : "doesn't exist")." w:netrw_treedict ".(exists("w:netrw_treedict")? "exists" : "doesn't exit"),'~'.expand("<slnum>"))
" 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>"))
" update the treetop " update the treetop
if !exists("w:netrw_treetop") if !exists("w:netrw_treetop")
" call Decho("update the treetop (w:netrw_treetop doesn't exist yet)",'~'.expand("<slnum>"))
let w:netrw_treetop= a:dirname let w:netrw_treetop= a:dirname
let s:netrw_treetop= w:netrw_treetop let s:netrw_treetop= w:netrw_treetop
" call Decho("w:netrw_treetop<".w:netrw_treetop."> (reusing)",'~'.expand("<slnum>")) " use \V in case the directory contains specials chars like '$' or '~'
elseif (w:netrw_treetop =~ ('^'.a:dirname) && s:Strlen(a:dirname) < s:Strlen(w:netrw_treetop)) || a:dirname !~ ('^'.w:netrw_treetop) elseif (w:netrw_treetop =~ ('^'.'\V'.a:dirname) && s:Strlen(a:dirname) < s:Strlen(w:netrw_treetop))
" call Decho("update the treetop (override w:netrw_treetop with a:dirname<".a:dirname.">)",'~'.expand("<slnum>")) \ || a:dirname !~ ('^'.'\V'.w:netrw_treetop)
let w:netrw_treetop= a:dirname let w:netrw_treetop= a:dirname
let s:netrw_treetop= w:netrw_treetop let s:netrw_treetop= w:netrw_treetop
" call Decho("w:netrw_treetop<".w:netrw_treetop."> (went up)",'~'.expand("<slnum>"))
endif endif
if exists("w:netrw_treetop") if exists("w:netrw_treetop")
let s:netrw_treetop= w:netrw_treetop let s:netrw_treetop= w:netrw_treetop
@ -9565,16 +9495,12 @@ fun! s:NetrwTreeListing(dirname)
if !exists("w:netrw_treedict") if !exists("w:netrw_treedict")
" insure that we have a treedict, albeit empty " insure that we have a treedict, albeit empty
" call Decho("initializing w:netrw_treedict to empty",'~'.expand("<slnum>"))
let w:netrw_treedict= {} let w:netrw_treedict= {}
endif endif
" update the dictionary for the current directory " update the dictionary for the current directory
" call Decho("updating: w:netrw_treedict[".a:dirname.'] -> [directory listing]','~'.expand("<slnum>"))
" call Decho("w:netrw_bannercnt=".w:netrw_bannercnt." line($)=".line("$"),'~'.expand("<slnum>"))
exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g@^\.\.\=/$@d _' exe "sil! NetrwKeepj ".w:netrw_bannercnt.',$g@^\.\.\=/$@d _'
let w:netrw_treedict[a:dirname]= getline(w:netrw_bannercnt,line("$")) let w:netrw_treedict[a:dirname]= getline(w:netrw_bannercnt,line("$"))
" call Decho("w:treedict[".a:dirname."]= ".string(w:netrw_treedict[a:dirname]),'~'.expand("<slnum>"))
exe "sil! NetrwKeepj ".w:netrw_bannercnt.",$d _" exe "sil! NetrwKeepj ".w:netrw_bannercnt.",$d _"
" if past banner, record word " if past banner, record word
@ -9583,23 +9509,17 @@ fun! s:NetrwTreeListing(dirname)
else else
let fname= "" let fname= ""
endif endif
" call Decho("fname<".fname.">",'~'.expand("<slnum>"))
" 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>"))
" display from treetop on down " display from treetop on down
" call Decho("(s:NetrwTreeListing) w:netrw_treetop<".w:netrw_treetop.">")
NetrwKeepj call s:NetrwTreeDisplay(w:netrw_treetop,"") NetrwKeepj call s:NetrwTreeDisplay(w:netrw_treetop,"")
" call Decho("s:NetrwTreeDisplay) setl noma nomod ro",'~'.expand("<slnum>"))
" remove any blank line remaining as line#1 (happens in treelisting mode with banner suppressed) " remove any blank line remaining as line#1 (happens in treelisting mode with banner suppressed)
while getline(1) =~ '^\s*$' && byte2line(1) > 0 while getline(1) =~ '^\s*$' && byte2line(1) > 0
" call Decho("deleting blank line",'~'.expand("<slnum>"))
1d 1d
endwhile endwhile
exe "setl ".g:netrw_bufsettings exe "setl ".g:netrw_bufsettings
" call Dret("s:NetrwTreeListing : bufname<".expand("%").">")
return return
endif endif
endfun endfun
@ -11963,7 +11883,7 @@ fun! s:NetrwEnew(...)
" call Dfunc("s:NetrwEnew() a:0=".a:0." win#".winnr()." winnr($)=".winnr("$")." bufnr($)=".bufnr("$")." expand(%)<".expand("%").">") " call Dfunc("s:NetrwEnew() a:0=".a:0." win#".winnr()." winnr($)=".winnr("$")." bufnr($)=".bufnr("$")." expand(%)<".expand("%").">")
" call Decho("curdir<".((a:0>0)? a:1 : "")."> buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>")) " call Decho("curdir<".((a:0>0)? a:1 : "")."> buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
" Clean out the last buffer: " Clean out the last buffer:
" Check if the last buffer has # > 1, is unlisted, is unnamed, and does not appear in a window " Check if the last buffer has # > 1, is unlisted, is unnamed, and does not appear in a window
" If so, delete it. " If so, delete it.
call s:NetrwBufRemover(bufnr("$")) call s:NetrwBufRemover(bufnr("$"))
@ -12043,13 +11963,16 @@ endfun
" s:NetrwExe: executes a string using "!" {{{2 " s:NetrwExe: executes a string using "!" {{{2
fun! s:NetrwExe(cmd) fun! s:NetrwExe(cmd)
" call Dfunc("s:NetrwExe(a:cmd<".a:cmd.">)") " call Dfunc("s:NetrwExe(a:cmd<".a:cmd.">)")
if has("win32") && &shell !~? 'cmd\|pwsh\|powershell' && !g:netrw_cygwin if has("win32")
" call Decho("using win32:",expand("<slnum>")) " call Decho("using win32:",expand("<slnum>"))
let savedShell=[&shell,&shellcmdflag,&shellxquote,&shellxescape,&shellquote,&shellpipe,&shellredir,&shellslash] let savedShell=[&shell,&shellcmdflag,&shellxquote,&shellxescape,&shellquote,&shellpipe,&shellredir,&shellslash]
set shell& shellcmdflag& shellxquote& shellxescape& set shell& shellcmdflag& shellxquote& shellxescape&
set shellquote& shellpipe& shellredir& shellslash& set shellquote& shellpipe& shellredir& shellslash&
exe a:cmd try
let [&shell,&shellcmdflag,&shellxquote,&shellxescape,&shellquote,&shellpipe,&shellredir,&shellslash] = savedShell exe a:cmd
finally
let [&shell,&shellcmdflag,&shellxquote,&shellxescape,&shellquote,&shellpipe,&shellredir,&shellslash] = savedShell
endtry
else else
" call Decho("exe ".a:cmd,'~'.expand("<slnum>")) " call Decho("exe ".a:cmd,'~'.expand("<slnum>"))
exe a:cmd exe a:cmd
@ -12152,7 +12075,7 @@ fun! s:NetrwHumanReadable(sz)
" call Dfunc("s:NetrwHumanReadable(sz=".a:sz.") type=".type(a:sz)." style=".g:netrw_sizestyle ) " call Dfunc("s:NetrwHumanReadable(sz=".a:sz.") type=".type(a:sz)." style=".g:netrw_sizestyle )
if g:netrw_sizestyle == 'h' if g:netrw_sizestyle == 'h'
if a:sz >= 1000000000 if a:sz >= 1000000000
let sz = printf("%.1f",a:sz/1000000000.0)."g" let sz = printf("%.1f",a:sz/1000000000.0)."g"
elseif a:sz >= 10000000 elseif a:sz >= 10000000
let sz = printf("%d",a:sz/1000000)."m" let sz = printf("%d",a:sz/1000000)."m"
@ -12580,7 +12503,7 @@ endfun
fun! s:ShellEscape(s, ...) fun! s:ShellEscape(s, ...)
if has('win32') && $SHELL == '' && &shellslash if has('win32') && $SHELL == '' && &shellslash
return printf('"%s"', substitute(a:s, '"', '""', 'g')) return printf('"%s"', substitute(a:s, '"', '""', 'g'))
endif endif
let f = a:0 > 0 ? a:1 : 0 let f = a:0 > 0 ? a:1 : 0
return shellescape(a:s, f) return shellescape(a:s, f)
endfun endfun

View File

@ -1465,48 +1465,106 @@ With either form of the command, netrw will first ask for confirmation
that the removal is in fact what you want to do. If netrw doesn't have that the removal is in fact what you want to do. If netrw doesn't have
permission to remove a file, it will issue an error message. permission to remove a file, it will issue an error message.
*netrw-gx*
CUSTOMIZING BROWSING WITH A SPECIAL HANDLER *netrw-x* *netrw-handler* {{{2 CUSTOMIZING BROWSING WITH A SPECIAL HANDLER *netrw-x* *netrw-handler* {{{2
Certain files, such as html, gif, jpeg, (word/office) doc, etc, files, are Certain files, such as html, gif, jpeg, (word/office) doc, etc, files, are
best seen with a special handler (ie. a tool provided with your computer's best seen with a special handler (ie. a tool provided with your computer's
operating system). Netrw allows one to invoke such special handlers by: > operating system). Netrw allows one to invoke such special handlers by:
* when Exploring, hit the "x" key * hitting gx with the cursor atop the file path or alternatively x
* when editing, hit gx with the cursor atop the special filename in a netrw buffer; the former can be disabled by defining the
< (latter not available if the |g:netrw_nogx| variable exists) |g:netrw_nogx| variable
* when in command line, typing :Open <path>, see |:Open| below.
Netrw determines which special handler by the following method:
* if |g:netrw_browsex_viewer| exists, then it will be used to attempt to
view files. Examples of useful settings (place into your <.vimrc>): >
:let g:netrw_browsex_viewer= "kfmclient exec"
< or >
:let g:netrw_browsex_viewer= "xdg-open"
<
If the viewer you wish to use does not support handling of a remote URL
directory, set |g:netrw_browsex_support_remote| to 0.
* for Windows 32 or 64, the URL and FileProtocolHandler dlls are used.
* for Gnome (with gnome-open): gnome-open is used.
* for KDE (with kfmclient) : kfmclient is used
* for Mac OS X : open is used.
The gx mapping extends to all buffers; apply "gx" while atop a word and netrw
will apply a special handler to it (like "x" works when in a netrw buffer).
One may also use visual mode (see |visual-start|) to select the text that the One may also use visual mode (see |visual-start|) to select the text that the
special handler will use. Normally gx uses expand("<cfile>") to pick up the special handler will use. Normally gx checks for a close-by URL or file name
text under the cursor; one may change what |expand()| uses via the to pick up the text under the cursor; one may change what |expand()| uses via the
|g:netrw_gx| variable (options include "<cword>", "<cWORD>"). Note that |g:netrw_gx| variable (options include "<cword>", "<cWORD>"). Note that
expand("<cfile>") depends on the |'isfname'| setting. Alternatively, one may expand("<cfile>") depends on the |'isfname'| setting. Alternatively, one may
select the text to be used by gx by making a visual selection (see select the text to be used by gx by making a visual selection (see
|visual-block|) and then pressing gx. |visual-block|) and then pressing gx.
The selection function can be adapted for each filetype by adding a function
`Netrw_get_URL_<filetype>`, where <filetype> is given by the 'filetype'.
The function should return the URL or file name to be used by gx, and will
fall back to the default behavior if it returns an empty string.
For example, special handlers for links Markdown and HTML are
" make gx work on concealed links regardless of exact cursor position: >
function Netrw_get_URL_markdown()
" markdown URL such as [link text](http://ya.ru 'yandex search')
try
let save_view = winsaveview()
if searchpair('\[.\{-}\](', '', ')\zs', 'cbW', '', line('.')) > 0
return matchstr(getline('.')[col('.')-1:],
\ '\[.\{-}\](\zs' .. g:netrw_regex_url .. '\ze\(\s\+.\{-}\)\?)')
endif
finally
call winrestview(save_view)
return ''
endtry
endfunction
function Netrw_get_URL_html()
" HTML URL such as <a href='http://www.python.org'>Python is here</a>
" <a href="http://www.python.org"/>
try
let save_view = winsaveview()
if searchpair('<a\s\+href=', '', '\%(</a>\|/>\)\zs', 'cbW', '', line('.')) > 0
return matchstr(getline('.')[col('.') - 1 : ],
\ 'href=["'.."'"..']\?\zs\S\{-}\ze["'.."'"..']\?/\?>')
endif
finally
call winrestview(save_view)
return ''
endtry
endfunction
<
Other than a file path, the text under the cursor may be a URL. Netrw uses
by default the following regular expression to determine if the text under the
cursor is a URL:
>
:let g:netrw_regex_url = '\%(\%(http\|ftp\|irc\)s\?\|file\)://\S\{-}'
<
Associated setting variables: Associated setting variables:
|g:netrw_gx| control how gx picks up the text under the cursor |g:netrw_gx| control how gx picks up the text under the cursor
|g:netrw_nogx| prevent gx map while editing |g:netrw_nogx| prevent gx map while editing
|g:netrw_suppress_gx_mesg| controls gx's suppression of browser messages |g:netrw_suppress_gx_mesg| controls gx's suppression of browser messages
OPENING FILES AND LAUNCHING APPS *netrw-gx* *:Open* *:Launch* {{{2
Netrw determines which special handler by the following method:
* if |g:netrw_browsex_viewer| exists, then it will be used to attempt to
view files. Examples of useful settings (place into your <.vimrc>):
If the viewer you wish to use does not support handling of a remote URL
directory, set |g:netrw_browsex_support_remote| to 0.
* otherwise:
* for Windows : explorer.exe is used
* for Mac OS X : open is used.
* for Linux : xdg-open is used.
To open a path (or URL) <path> by the appropriate handler, type >
:Open <path>
<
No escaping, neither for the shell nor for Vim's command-line, is needed.
To launch a specific application <app> <args>, often <args> being <path> >
:Launch <app> <args>.
Since <args> can be arbitrarily complex, in particular contain many file
paths, the escaping is left to the user.
If you disabled the netrw plugin by setting g:loaded_netrwPlugin (see
|netrw-noload|), then you can use >
:call netrw#Launch('<app> <args>')
:call netrw#Open('<path>')
<
*netrw-curdir* *netrw-curdir*
DELETING BOOKMARKS *netrw-mB* {{{2 DELETING BOOKMARKS *netrw-mB* {{{2

View File

@ -1,9 +1,12 @@
" netrwPlugin.vim: Handles file transfer and remote directory listing across a network " netrwPlugin.vim: Handles file transfer and remote directory listing across a network
" PLUGIN SECTION " PLUGIN SECTION
" Maintainer: This runtime file is looking for a new maintainer. " Maintainer: This runtime file is looking for a new maintainer.
" Date: Feb 09, 2021 " Date: Sep 09, 2021
" Last Change: " Last Change:
" 2024 May 08 by Vim Project: cleanup legacy Win9X checks " 2024 May 08 by Vim Project: cleanup legacy Win9X checks
" 2024 Oct 27 by Vim Project: cleanup gx mapping
" 2024 Oct 28 by Vim Project: further improvements
" 2024 Oct 31 by Vim Project: use autoloaded functions
" Former Maintainer: Charles E Campbell " Former Maintainer: Charles E Campbell
" GetLatestVimScripts: 1075 1 :AutoInstall: netrw.vim " GetLatestVimScripts: 1075 1 :AutoInstall: netrw.vim
" Copyright: Copyright (C) 1999-2021 Charles E. Campbell {{{1 " Copyright: Copyright (C) 1999-2021 Charles E. Campbell {{{1
@ -31,6 +34,10 @@ set cpo&vim
" --------------------------------------------------------------------- " ---------------------------------------------------------------------
" Public Interface: {{{1 " Public Interface: {{{1
" Commands Launch/URL {{{2
command -complete=shellcmd -nargs=1 Launch call netrw#Launch(trim(<q-args>))
command -complete=file -nargs=1 Open call netrw#Open(trim(<q-args>))
" " }}}
" Local Browsing Autocmds: {{{2 " Local Browsing Autocmds: {{{2
augroup FileExplorer augroup FileExplorer
au! au!