Skip to content

Commit 8b0fa7a

Browse files
chrisbrazzzyxwvut
andcommitted
runtime(netrw): make :Launch/Open autoloadable
fixes: #15959 closes: #15962 Co-authored-by: Aliaksei Budavei <[email protected]> Signed-off-by: Konfekt <[email protected]> Signed-off-by: Christian Brabandt <[email protected]>
1 parent 9f32069 commit 8b0fa7a

4 files changed

Lines changed: 180 additions & 182 deletions

File tree

runtime/autoload/netrw.vim

Lines changed: 123 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
" 2024 Oct 27 by Vim Project: clean up gx mapping (#15721)
3131
" 2024 Oct 30 by Vim Project: fix filetype detection for remote files (#15961)
3232
" 2024 Oct 30 by Vim Project: fix x mapping on cygwin (#13687)
33+
" 2024 Oct 31 by Vim Project: add netrw#Launch() and netrw#Open() (#15962)
3334
" }}}
3435
" Former Maintainer: Charles E Campbell
3536
" GetLatestVimScripts: 1075 1 :AutoInstall: netrw.vim
@@ -1195,47 +1196,35 @@ fun! netrw#Lexplore(count,rightside,...)
11951196
" if a netrw window is already on the left-side of the tab
11961197
" and a directory has been specified, explore with that
11971198
" directory.
1198-
" call Decho("case has input argument(s) (a:1<".a:1.">)")
11991199
let a1 = expand(a:1)
1200-
" call Decho("a:1<".a:1."> curwin#".curwin,'~'.expand("<slnum>"))
12011200
exe "1wincmd w"
12021201
if &ft == "netrw"
1203-
" call Decho("exe Explore ".fnameescape(a:1),'~'.expand("<slnum>"))
12041202
exe "Explore ".fnameescape(a1)
12051203
exe curwin."wincmd w"
12061204
let s:lexplore_win= curwin
12071205
let w:lexplore_buf= bufnr("%")
12081206
if exists("t:netrw_lexposn")
1209-
" call Decho("forgetting t:netrw_lexposn",'~'.expand("<slnum>"))
12101207
unlet t:netrw_lexposn
12111208
endif
1212-
" call Dret("netrw#Lexplore")
12131209
return
12141210
endif
12151211
exe curwin."wincmd w"
12161212
else
12171213
let a1= ""
1218-
" call Decho("no input arguments")
12191214
endif
12201215

12211216
if exists("t:netrw_lexbufnr")
12221217
" check if t:netrw_lexbufnr refers to a netrw window
12231218
let lexwinnr = bufwinnr(t:netrw_lexbufnr)
1224-
" call Decho("lexwinnr= bufwinnr(t:netrw_lexbufnr#".t:netrw_lexbufnr.")=".lexwinnr)
12251219
else
12261220
let lexwinnr= 0
1227-
" call Decho("t:netrw_lexbufnr doesn't exist")
12281221
endif
1229-
" call Decho("lexwinnr=".lexwinnr,'~'.expand("<slnum>"))
12301222

12311223
if lexwinnr > 0
12321224
" close down netrw explorer window
1233-
" call Decho("t:netrw_lexbufnr#".t:netrw_lexbufnr.": close down netrw window",'~'.expand("<slnum>"))
12341225
exe lexwinnr."wincmd w"
12351226
let g:netrw_winsize = -winwidth(0)
12361227
let t:netrw_lexposn = winsaveview()
1237-
" call Decho("saving posn to t:netrw_lexposn<".string(t:netrw_lexposn).">",'~'.expand("<slnum>"))
1238-
" call Decho("saving t:netrw_lexposn",'~'.expand("<slnum>"))
12391228
close
12401229
if lexwinnr < curwin
12411230
let curwin= curwin - 1
@@ -1244,11 +1233,9 @@ fun! netrw#Lexplore(count,rightside,...)
12441233
exe curwin."wincmd w"
12451234
endif
12461235
unlet t:netrw_lexbufnr
1247-
" call Decho("unlet t:netrw_lexbufnr")
12481236

12491237
else
12501238
" open netrw explorer window
1251-
" call Decho("t:netrw_lexbufnr<n/a>: open netrw explorer window",'~'.expand("<slnum>"))
12521239
exe "1wincmd w"
12531240
let keep_altv = g:netrw_altv
12541241
let g:netrw_altv = 0
@@ -1257,18 +1244,13 @@ fun! netrw#Lexplore(count,rightside,...)
12571244
let g:netrw_winsize = a:count
12581245
endif
12591246
let curfile= expand("%")
1260-
" call Decho("curfile<".curfile.">",'~'.expand("<slnum>"))
12611247
exe (a:rightside? "botright" : "topleft")." vertical ".((g:netrw_winsize > 0)? (g:netrw_winsize*winwidth(0))/100 : -g:netrw_winsize) . " new"
1262-
" call Decho("new buf#".bufnr("%")." win#".winnr())
12631248
if a:0 > 0 && a1 != ""
1264-
" call Decho("case 1: Explore ".a1,'~'.expand("<slnum>"))
12651249
call netrw#Explore(0,0,0,a1)
12661250
exe "Explore ".fnameescape(a1)
12671251
elseif curfile =~ '^\a\{3,}://'
1268-
" call Decho("case 2: Explore ".substitute(curfile,'[^/\\]*$','',''),'~'.expand("<slnum>"))
12691252
call netrw#Explore(0,0,0,substitute(curfile,'[^/\\]*$','',''))
12701253
else
1271-
" call Decho("case 3: Explore .",'~'.expand("<slnum>"))
12721254
call netrw#Explore(0,0,0,".")
12731255
endif
12741256
if a:count != 0
@@ -1281,11 +1263,7 @@ fun! netrw#Lexplore(count,rightside,...)
12811263
" Since the intended use of :Lexplore is to have an always-present explorer window, the extra
12821264
" effort to prevent mis-use of :Lex is warranted.
12831265
set bh=wipe
1284-
" call Decho("let t:netrw_lexbufnr=".t:netrw_lexbufnr)
1285-
" call Decho("t:netrw_lexposn".(exists("t:netrw_lexposn")? string(t:netrw_lexposn) : " n/a"))
12861266
if exists("t:netrw_lexposn")
1287-
" call Decho("restoring to t:netrw_lexposn",'~'.expand("<slnum>"))
1288-
" call Decho("restoring posn to t:netrw_lexposn<".string(t:netrw_lexposn).">",'~'.expand("<slnum>"))
12891267
call winrestview(t:netrw_lexposn)
12901268
unlet t:netrw_lexposn
12911269
endif
@@ -1298,10 +1276,8 @@ fun! netrw#Lexplore(count,rightside,...)
12981276
else
12991277
let g:netrw_chgwin= 2
13001278
endif
1301-
" call Decho("let g:netrw_chgwin=".g:netrw_chgwin)
13021279
endif
13031280

1304-
" call Dret("netrw#Lexplore")
13051281
endfun
13061282

13071283
" ---------------------------------------------------------------------
@@ -5266,6 +5242,120 @@ fun! s:NetrwBrowseUpDir(islocal)
52665242
" call Dret("s:NetrwBrowseUpDir")
52675243
endfun
52685244

5245+
func s:redir()
5246+
" set up redirection (avoids browser messages)
5247+
" by default if not set, g:netrw_suppress_gx_mesg is true
5248+
if get(g:, 'netrw_suppress_gx_mesg', 1)
5249+
if &srr =~# "%s"
5250+
return printf(&srr, has("win32") ? "nul" : "/dev/null")
5251+
else
5252+
return &srr .. (has("win32") ? "nul" : "/dev/null")
5253+
endif
5254+
endif
5255+
return ''
5256+
endfunc
5257+
5258+
if has('unix')
5259+
if has('win32unix')
5260+
" Cygwin provides cygstart
5261+
if executable('cygstart')
5262+
fun! netrw#Launch(args)
5263+
exe 'silent ! cygstart --hide' a:args s:redir() | redraw!
5264+
endfun
5265+
elseif !empty($MSYSTEM) && executable('start')
5266+
" MSYS2/Git Bash comes by default without cygstart; see
5267+
" https://www.msys2.org/wiki/How-does-MSYS2-differ-from-Cygwin
5268+
" Instead it provides /usr/bin/start script running `cmd.exe //c start`
5269+
" Adding "" //b` sets void title, hides cmd window and blocks path conversion
5270+
" of /b to \b\ " by MSYS2; see https://www.msys2.org/docs/filesystem-paths/
5271+
fun! netrw#Launch(args)
5272+
exe 'silent !start "" //b' a:args s:redir() | redraw!
5273+
endfun
5274+
else
5275+
" imitate /usr/bin/start script for other environments and hope for the best
5276+
fun! netrw#Launch(args)
5277+
exe 'silent !cmd //c start "" //b' a:args s:redir() | redraw!
5278+
endfun
5279+
endif
5280+
elseif exists('$WSL_DISTRO_NAME') " use cmd.exe to start GUI apps in WSL
5281+
fun! netrw#Launch(args)
5282+
let args = a:args
5283+
exe 'silent !' ..
5284+
\ ((args =~? '\v<\f+\.(exe|com|bat|cmd)>') ?
5285+
\ 'cmd.exe /c start "" /b ' .. args :
5286+
\ 'nohup ' .. args .. ' ' .. s:redir() .. ' &')
5287+
\ | redraw!
5288+
endfun
5289+
else
5290+
fun! netrw#Launch(args)
5291+
exe ':silent ! nohup' a:args s:redir() '&' | redraw!
5292+
endfun
5293+
endif
5294+
elseif has('win32')
5295+
fun! netrw#Launch(args)
5296+
exe 'silent !' .. (&shell =~? '\<cmd\.exe\>' ? '' : 'cmd.exe /c')
5297+
\ 'start "" /b' a:args s:redir() | redraw!
5298+
endfun
5299+
else
5300+
fun! netrw#Launch(dummy)
5301+
echom 'No common launcher found'
5302+
endfun
5303+
endif
5304+
5305+
" Git Bash
5306+
if has('win32unix')
5307+
" (cyg)start suffices
5308+
let s:os_viewer = ''
5309+
" Windows / WSL
5310+
elseif executable('explorer.exe')
5311+
let s:os_viewer = 'explorer.exe'
5312+
" Linux / BSD
5313+
elseif executable('xdg-open')
5314+
let s:os_viewer = 'xdg-open'
5315+
" MacOS
5316+
elseif executable('open')
5317+
let s:os_viewer = 'open'
5318+
endif
5319+
5320+
fun! s:viewer()
5321+
if exists('g:netrw_browsex_viewer') && executable(g:netrw_browsex_viewer)
5322+
" extract any viewing options. Assumes that they're set apart by spaces.
5323+
" call Decho("extract any viewing options from g:netrw_browsex_viewer<".g:netrw_browsex_viewer.">",'~'.expand("<slnum>"))
5324+
if g:netrw_browsex_viewer =~ '\s'
5325+
let viewer = substitute(g:netrw_browsex_viewer,'\s.*$','','')
5326+
let viewopt = substitute(g:netrw_browsex_viewer,'^\S\+\s*','','')." "
5327+
let oviewer = ''
5328+
let cnt = 1
5329+
while !executable(viewer) && viewer != oviewer
5330+
let viewer = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\1','')
5331+
let viewopt = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\3','')." "
5332+
let cnt = cnt + 1
5333+
let oviewer = viewer
5334+
" call Decho("!exe: viewer<".viewer."> viewopt<".viewopt.">",'~'.expand("<slnum>"))
5335+
endwhile
5336+
else
5337+
let viewer = g:netrw_browsex_viewer
5338+
let viewopt = ""
5339+
endif
5340+
" call Decho("viewer<".viewer."> viewopt<".viewopt.">",'~'.expand("<slnum>"))
5341+
return viewer .. ' ' .. viewopt
5342+
else
5343+
if !exists('s:os_viewer')
5344+
call netrw#ErrorMsg(s:ERROR,"No program to open this path found. See :help Open for more information.",106)
5345+
else
5346+
return s:os_viewer
5347+
endif
5348+
endif
5349+
endfun
5350+
5351+
fun! netrw#Open(file) abort
5352+
call netrw#Launch(s:viewer() .. ' ' .. shellescape(a:file, 1))
5353+
endf
5354+
5355+
if !exists('g:netrw_regex_url')
5356+
let g:netrw_regex_url = '\%(\%(http\|ftp\|irc\)s\?\|file\)://\S\{-}'
5357+
endif
5358+
52695359
" ---------------------------------------------------------------------
52705360
" netrw#BrowseX: (implements "x" and "gx") executes a special "viewer" script or program for the {{{2
52715361
" given filename; typically this means given their extension.
@@ -5349,31 +5439,8 @@ fun! netrw#BrowseX(fname,remote)
53495439
endif
53505440
endif
53515441

5352-
" extract any viewing options. Assumes that they're set apart by spaces.
5353-
if exists("g:netrw_browsex_viewer")
5354-
if g:netrw_browsex_viewer =~ '\s'
5355-
let viewer = substitute(g:netrw_browsex_viewer,'\s.*$','','')
5356-
let viewopt = substitute(g:netrw_browsex_viewer,'^\S\+\s*','','')." "
5357-
let oviewer = ''
5358-
let cnt = 1
5359-
while !executable(viewer) && viewer != oviewer
5360-
let viewer = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\1','')
5361-
let viewopt = substitute(g:netrw_browsex_viewer,'^\(\(^\S\+\s\+\)\{'.cnt.'}\S\+\)\(.*\)$','\3','')." "
5362-
let cnt = cnt + 1
5363-
let oviewer = viewer
5364-
endwhile
5365-
else
5366-
let viewer = g:netrw_browsex_viewer
5367-
let viewopt = ""
5368-
endif
5369-
endif
5370-
5371-
if exists("g:netrw_browsex_viewer") && executable(viewer)
5372-
exe 'Launch' viewer viewopt shellescape(fname, 1)
5373-
else
5374-
" though shellescape(..., 1) is used in Open, it's insufficient
5375-
exe 'Open' escape(fname, '#%')
5376-
endif
5442+
" although shellescape(..., 1) is used in netrw#Open(), it's insufficient
5443+
call netrw#Open(escape(fname, '#%'))
53775444

53785445
" cleanup: remove temporary file,
53795446
" delete current buffer if success with handler,
@@ -5665,7 +5732,7 @@ fun! s:NetrwGlob(direntry,expr,pare)
56655732
endif
56665733
let w:netrw_liststyle= keep_liststyle
56675734
else
5668-
let path= s:ComposePath(fnameescape(a:direntry),a:expr)
5735+
let path= s:ComposePath(fnameescape(a:direntry), a:expr)
56695736
if has("win32")
56705737
" escape [ so it is not detected as wildcard character, see :h wildcard
56715738
let path= substitute(path, '[', '[[]', 'g')
@@ -5679,7 +5746,6 @@ fun! s:NetrwGlob(direntry,expr,pare)
56795746
let filelist= map(filelist,'substitute(v:val, "^.*/", "", "")')
56805747
endif
56815748
endif
5682-
" call Dret("s:NetrwGlob ".string(filelist))
56835749
return filelist
56845750
endfun
56855751

@@ -8212,7 +8278,7 @@ fun! netrw#Shrink()
82128278
elseif winwidth(bufwinnr(t:netrw_lexbufnr)) >= 0
82138279
exe "vert resize ".t:netrw_winwidth
82148280
" call Decho("vert resize ".t:netrw_winwidth,'~'.expand("<slnum>"))
8215-
else
8281+
else
82168282
call netrw#Lexplore(0,0)
82178283
endif
82188284

@@ -8529,7 +8595,7 @@ fun! s:NetrwPrevWinOpen(islocal)
85298595
" call Decho("COMBAK#11: mod=".&mod)
85308596
" call Decho("wincmd p (now in win#".winnr().") curdir<".curdir.">",'~'.expand("<slnum>"))
85318597
" call Decho("COMBAK#12: mod=".&mod)
8532-
8598+
85338599
if exists("s:lexplore_win") && s:lexplore_win == winnr()
85348600
" whoops -- user trying to open file in the Lexplore window.
85358601
" Use Lexplore's opening-file window instead.
@@ -11944,7 +12010,7 @@ fun! s:NetrwEnew(...)
1194412010
" call Dfunc("s:NetrwEnew() a:0=".a:0." win#".winnr()." winnr($)=".winnr("$")." bufnr($)=".bufnr("$")." expand(%)<".expand("%").">")
1194512011
" call Decho("curdir<".((a:0>0)? a:1 : "")."> buf#".bufnr("%")."<".bufname("%").">",'~'.expand("<slnum>"))
1194612012

11947-
" Clean out the last buffer:
12013+
" Clean out the last buffer:
1194812014
" Check if the last buffer has # > 1, is unlisted, is unnamed, and does not appear in a window
1194912015
" If so, delete it.
1195012016
call s:NetrwBufRemover(bufnr("$"))
@@ -12136,7 +12202,7 @@ fun! s:NetrwHumanReadable(sz)
1213612202
" call Dfunc("s:NetrwHumanReadable(sz=".a:sz.") type=".type(a:sz)." style=".g:netrw_sizestyle )
1213712203

1213812204
if g:netrw_sizestyle == 'h'
12139-
if a:sz >= 1000000000
12205+
if a:sz >= 1000000000
1214012206
let sz = printf("%.1f",a:sz/1000000000.0)."g"
1214112207
elseif a:sz >= 10000000
1214212208
let sz = printf("%d",a:sz/1000000)."m"
@@ -12564,7 +12630,7 @@ endfun
1256412630
fun! s:ShellEscape(s, ...)
1256512631
if has('win32') && $SHELL == '' && &shellslash
1256612632
return printf('"%s"', substitute(a:s, '"', '""', 'g'))
12567-
endif
12633+
endif
1256812634
let f = a:0 > 0 ? a:1 : 0
1256912635
return shellescape(a:s, f)
1257012636
endfun

0 commit comments

Comments
 (0)