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")
13051281endfun
13061282
13071283" ---------------------------------------------------------------------
@@ -5266,6 +5242,120 @@ fun! s:NetrwBrowseUpDir(islocal)
52665242" call Dret("s:NetrwBrowseUpDir")
52675243endfun
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
56845750endfun
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
1256412630fun! 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)
1257012636endfun
0 commit comments