blob: 6d4079ea36995e953bc6a73244211a7ee8d2fa2d [file] [log] [blame]
Christian Brabandt4f174f02023-11-04 11:16:23 +01001vim9script
2
3# Vim runtime support library
4#
Luca Saccarolac729d6d2025-01-25 16:07:12 +01005# Maintainer: The Vim Project <https://github.com/vim/vim>
Luca Saccarola76680122025-01-29 18:33:46 +01006# Last Change: 2025 Jan 29
Christian Brabandt4f174f02023-11-04 11:16:23 +01007
8export def IsSafeExecutable(filetype: string, executable: string): bool
Luca Saccarolac729d6d2025-01-25 16:07:12 +01009 if empty(exepath(executable))
10 return v:false
11 endif
12 var cwd = getcwd()
13 return get(g:, filetype .. '_exec', get(g:, 'plugin_exec', 0))
14 && (fnamemodify(exepath(executable), ':p:h') !=# cwd
15 || (split($PATH, has('win32') ? ';' : ':')->index(cwd) != -1
16 && cwd != '.'))
17enddef
18
19def Redir(): string
20 if get(g:, 'netrw_suppress_gx_mesg', true)
21 if &srr =~# "%s"
22 return printf(&srr, has("win32") ? "nul" : "/dev/null")
23 elseif &srr =~# '>&\?$'
24 return &srr .. (has("win32") ? "nul" : "/dev/null")
25 else
26 return &srr .. (has("win32") ? "> nul" : "> /dev/null")
Christian Brabandt8e25d912024-08-17 15:52:11 +020027 endif
Luca Saccarolac729d6d2025-01-25 16:07:12 +010028 endif
29 return ''
30enddef
31
32if has('unix')
33 if has('win32unix')
34 # Cygwin provides cygstart
35 if executable('cygstart')
36 export def Launch(args: string)
Luca Saccarola76680122025-01-29 18:33:46 +010037 execute $'silent ! cygstart --hide {args} {Redir()}' | redraw!
Luca Saccarolac729d6d2025-01-25 16:07:12 +010038 enddef
39 elseif !empty($MSYSTEM) && executable('start')
40 # MSYS2/Git Bash comes by default without cygstart; see
41 # https://www.msys2.org/wiki/How-does-MSYS2-differ-from-Cygwin
42 # Instead it provides /usr/bin/start script running `cmd.exe //c start`
43 # Adding "" //b` sets void title, hides cmd window and blocks path conversion
44 # of /b to \b\ " by MSYS2; see https://www.msys2.org/docs/filesystem-paths/
45 export def Launch(args: string)
Luca Saccarola76680122025-01-29 18:33:46 +010046 execute $'silent !start "" //b {args} {Redir()}' | redraw!
Luca Saccarolac729d6d2025-01-25 16:07:12 +010047 enddef
48 else
49 # imitate /usr/bin/start script for other environments and hope for the best
50 export def Launch(args: string)
Luca Saccarola76680122025-01-29 18:33:46 +010051 execute $'silent !cmd /c start "" /b {args} {Redir()}' | redraw!
Luca Saccarolac729d6d2025-01-25 16:07:12 +010052 enddef
53 endif
54 elseif exists('$WSL_DISTRO_NAME') # use cmd.exe to start GUI apps in WSL
55 export def Launch(args: string)
Luca Saccarola76680122025-01-29 18:33:46 +010056 const command = (args =~? '\v<\f+\.(exe|com|bat|cmd)>')
57 ? $'cmd.exe /c start /b {args} {Redir()}'
58 : $'nohup {args} {Redir()} &'
59 execute $'silent ! {command}' | redraw!
Luca Saccarolac729d6d2025-01-25 16:07:12 +010060 enddef
61 else
62 export def Launch(args: string)
Luca Saccarola76680122025-01-29 18:33:46 +010063 const fork = has('gui_running') ? '' : '&'
64 execute $':silent ! nohup {args} {Redir()} {fork}' | redraw!
Luca Saccarolac729d6d2025-01-25 16:07:12 +010065 enddef
66 endif
67elseif has('win32')
68 export def Launch(args: string)
Luca Saccarola76680122025-01-29 18:33:46 +010069 const shell = (&shell =~? '\<cmd\.exe\>') ? '' : 'cmd.exe /c'
70 const quotes = empty(shell) ? '' : '""'
71 execute $'silent ! {shell} start {quotes} /b {args} {Redir()}' | redraw!
Luca Saccarolac729d6d2025-01-25 16:07:12 +010072 enddef
73else
74 export def Launch(dummy: string)
75 echom 'No common launcher found'
76 enddef
77endif
78
79var os_viewer = null_string
80# Git Bash
81if has('win32unix')
82 # (cyg)start suffices
83 os_viewer = ''
84# Windows / WSL
85elseif executable('explorer.exe')
86 os_viewer = 'explorer.exe'
87# Linux / BSD
88elseif executable('xdg-open')
89 os_viewer = 'xdg-open'
90# MacOS
91elseif executable('open')
92 os_viewer = 'open'
93endif
94
95def Viewer(): string
96 # g:Openprg could be a string of program + its arguments, test if first
97 # argument is executable
98 var user_viewer = get(g:, "Openprg", get(g:, "netrw_browsex_viewer", ""))
99
100 # Take care of an off-by-one check for "for" too
101 if executable(trim(user_viewer))
102 return user_viewer
103 endif
104
105 var args = split(user_viewer, '\s\+\zs')
106 var viewer = get(args, 0, '')
107
108 for arg in args[1 :]
109 if executable(trim(viewer))
110 return user_viewer
111 endif
112
113 viewer ..= arg
114 endfor
115
116 if os_viewer == null
117 echoerr "No program to open this path found. See :help Open for more information."
118 endif
119
120 return os_viewer
121enddef
122
123export def Open(file: string)
124 Launch($"{Viewer()} {shellescape(file, 1)}")
Christian Brabandt4f174f02023-11-04 11:16:23 +0100125enddef
126
127# Uncomment this line to check for compilation errors early
128# defcompile
Luca Saccarolac729d6d2025-01-25 16:07:12 +0100129
130# vim: ts=8 sts=2 sw=2 et