# Vim runtime support library
#
-# Maintainer: The Vim Project <https://github.com/vim/vim>
-# Last Change: 2023 Oct 25
+# Maintainer: The Vim Project <https://github.com/vim/vim>
+# Last Change: 2025 Jan 24
export def IsSafeExecutable(filetype: string, executable: string): bool
- if empty(exepath(executable))
- return v:false
+ if empty(exepath(executable))
+ return v:false
+ endif
+ var cwd = getcwd()
+ return get(g:, filetype .. '_exec', get(g:, 'plugin_exec', 0))
+ && (fnamemodify(exepath(executable), ':p:h') !=# cwd
+ || (split($PATH, has('win32') ? ';' : ':')->index(cwd) != -1
+ && cwd != '.'))
+enddef
+
+def Redir(): string
+ if get(g:, 'netrw_suppress_gx_mesg', true)
+ if &srr =~# "%s"
+ return printf(&srr, has("win32") ? "nul" : "/dev/null")
+ elseif &srr =~# '>&\?$'
+ return &srr .. (has("win32") ? "nul" : "/dev/null")
+ else
+ return &srr .. (has("win32") ? "> nul" : "> /dev/null")
endif
- var cwd = getcwd()
- return get(g:, filetype .. '_exec', get(g:, 'plugin_exec', 0))
- && (fnamemodify(exepath(executable), ':p:h') !=# cwd
- || (split($PATH, has('win32') ? ';' : ':')->index(cwd) != -1
- && cwd != '.'))
+ endif
+ return ''
+enddef
+
+if has('unix')
+ if has('win32unix')
+ # Cygwin provides cygstart
+ if executable('cygstart')
+ export def Launch(args: string)
+ execute 'silent ! cygstart --hide' args Redir() | redraw!
+ enddef
+ 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/
+ export def Launch(args: string)
+ execute 'silent !start "" //b' args Redir() | redraw!
+ enddef
+ else
+ # imitate /usr/bin/start script for other environments and hope for the best
+ export def Launch(args: string)
+ execute 'silent !cmd //c start "" //b' args Redir() | redraw!
+ enddef
+ endif
+ elseif exists('$WSL_DISTRO_NAME') # use cmd.exe to start GUI apps in WSL
+ export def Launch(args: string)
+ execute 'silent !' ..
+ ((args =~? '\v<\f+\.(exe|com|bat|cmd)>') ?
+ $'cmd.exe /c start /b {args} {Redir()}' :
+ $'nohup {args} {Redir()} &')
+ | redraw!
+ enddef
+ else
+ export def Launch(args: string)
+ execute ':silent ! nohup' args Redir() (has('gui_running') ? '' : '&') | redraw!
+ enddef
+ endif
+elseif has('win32')
+ export def Launch(args: string)
+ execute 'silent !' .. (&shell =~? '\<cmd\.exe\>' ? '' : 'cmd.exe /c')
+ 'start "" /b' args Redir() | redraw!
+ enddef
+else
+ export def Launch(dummy: string)
+ echom 'No common launcher found'
+ enddef
+endif
+
+var os_viewer = null_string
+# Git Bash
+if has('win32unix')
+ # (cyg)start suffices
+ os_viewer = ''
+# Windows / WSL
+elseif executable('explorer.exe')
+ os_viewer = 'explorer.exe'
+# Linux / BSD
+elseif executable('xdg-open')
+ os_viewer = 'xdg-open'
+# MacOS
+elseif executable('open')
+ os_viewer = 'open'
+endif
+
+def Viewer(): string
+ # g:Openprg could be a string of program + its arguments, test if first
+ # argument is executable
+ var user_viewer = get(g:, "Openprg", get(g:, "netrw_browsex_viewer", ""))
+
+ # Take care of an off-by-one check for "for" too
+ if executable(trim(user_viewer))
+ return user_viewer
+ endif
+
+ var args = split(user_viewer, '\s\+\zs')
+ var viewer = get(args, 0, '')
+
+ for arg in args[1 :]
+ if executable(trim(viewer))
+ return user_viewer
+ endif
+
+ viewer ..= arg
+ endfor
+
+ if os_viewer == null
+ echoerr "No program to open this path found. See :help Open for more information."
+ endif
+
+ return os_viewer
+enddef
+
+export def Open(file: string)
+ Launch($"{Viewer()} {shellescape(file, 1)}")
enddef
# Uncomment this line to check for compilation errors early
# defcompile
+
+# vim: ts=8 sts=2 sw=2 et
-*eval.txt* For Vim version 9.1. Last change: 2025 Jan 02
+*eval.txt* For Vim version 9.1. Last change: 2025 Jan 25
VIM REFERENCE MANUAL by Bram Moolenaar
filetype string
executable string
+ *dist#vim9#Open()* *:Open*
+ *g:Openprg*
+dist#vim9#Open(file: string) ~
+
+Opens `path` with the system default handler (macOS `open`, Windows
+`explorer.exe`, Linux `xdg-open`, …). If the variable |g:Openprg| exists the
+string specified in the variable is used instead.
+
+NOTE: Escaping of the path is automatically applied.
+
+Usage: >vim
+ :call dist#vim9#Open(<path>)
+ :Open <path>
+<
+
+ *dist#vim9#Launch()* *:Launch*
+dist#vim9#Launch(file: string) ~
+
+Launches <args> with the appropriate system programs. Intended for launching
+GUI programs within Vim.
+
+NOTE: escaping of <args> is left to the user
+
+Examples: >vim
+ vim9script
+
+ import autoload 'dist/vim9.vim'
+ # Execute 'makeprg' into another xterm window
+ vim9.Launch('xterm ' .. expandcmd(&makeprg))
+<
+
+Usage: >vim
+ :call dist#vim9#Launch(<args>)
+ :Launch <app> <args>.
+<
vim:tw=78:ts=8:noet:ft=help:norl:
|gu| gu{motion} 2 make Nmove text lowercase
|gv| gv reselect the previous Visual area
|gw| gw{motion} 2 format Nmove text and keep cursor
-|netrw-gx| gx execute application for file name under the
- cursor (only with |netrw| plugin)
|g@| g@{motion} call 'operatorfunc'
|g~| g~{motion} 2 swap case for Nmove text
|g<Down>| g<Down> 1 same as "gj"
:LP pi_logipat.txt /*:LP*
:LPE pi_logipat.txt /*:LPE*
:LPF pi_logipat.txt /*:LPF*
-:Launch pi_netrw.txt /*:Launch*
+:Launch eval.txt /*:Launch*
:Lexplore pi_netrw.txt /*:Lexplore*
:Lfilter quickfix.txt /*:Lfilter*
:LogiPat pi_logipat.txt /*:LogiPat*
:Ntree pi_netrw.txt /*:Ntree*
:Nw pi_netrw.txt /*:Nw*
:Nwrite pi_netrw.txt /*:Nwrite*
-:Open pi_netrw.txt /*:Open*
+:Open eval.txt /*:Open*
:Over terminal.txt /*:Over*
:P various.txt /*:P*
:Pexplore pi_netrw.txt /*:Pexplore*
discard editing.txt /*discard*
dist#vim eval.txt /*dist#vim*
dist#vim9 eval.txt /*dist#vim9*
+dist#vim9#Launch() eval.txt /*dist#vim9#Launch()*
+dist#vim9#Open() eval.txt /*dist#vim9#Open()*
distribute-script usr_51.txt /*distribute-script*
distributed-plugins usr_05.txt /*distributed-plugins*
distribution intro.txt /*distribution*
g:Netrw_UserMaps pi_netrw.txt /*g:Netrw_UserMaps*
g:Netrw_corehandler pi_netrw.txt /*g:Netrw_corehandler*
g:Netrw_funcref pi_netrw.txt /*g:Netrw_funcref*
+g:Openprg eval.txt /*g:Openprg*
g:actual_curbuf options.txt /*g:actual_curbuf*
g:actual_curwin options.txt /*g:actual_curwin*
g:ada#Comment ft_ada.txt /*g:ada#Comment*
g:netrw_banner pi_netrw.txt /*g:netrw_banner*
g:netrw_bannerbackslash pi_netrw.txt /*g:netrw_bannerbackslash*
g:netrw_browse_split pi_netrw.txt /*g:netrw_browse_split*
-g:netrw_browsex_support_remote pi_netrw.txt /*g:netrw_browsex_support_remote*
-g:netrw_browsex_viewer pi_netrw.txt /*g:netrw_browsex_viewer*
g:netrw_bufsettings pi_netrw.txt /*g:netrw_bufsettings*
g:netrw_chgperm pi_netrw.txt /*g:netrw_chgperm*
g:netrw_chgwin pi_netrw.txt /*g:netrw_chgwin*
g:netrw_ftpextracmd pi_netrw.txt /*g:netrw_ftpextracmd*
g:netrw_ftpmode pi_netrw.txt /*g:netrw_ftpmode*
g:netrw_glob_escape pi_netrw.txt /*g:netrw_glob_escape*
-g:netrw_gx pi_netrw.txt /*g:netrw_gx*
g:netrw_hide pi_netrw.txt /*g:netrw_hide*
g:netrw_home pi_netrw.txt /*g:netrw_home*
g:netrw_http_cmd pi_netrw.txt /*g:netrw_http_cmd*
g:netrw_mkdir_cmd pi_netrw.txt /*g:netrw_mkdir_cmd*
g:netrw_mousemaps pi_netrw.txt /*g:netrw_mousemaps*
g:netrw_nobeval pi_netrw.txt /*g:netrw_nobeval*
-g:netrw_nogx pi_netrw.txt /*g:netrw_nogx*
g:netrw_preview pi_netrw.txt /*g:netrw_preview*
g:netrw_rcp_cmd pi_netrw.txt /*g:netrw_rcp_cmd*
g:netrw_remote_mkdir pi_netrw.txt /*g:netrw_remote_mkdir*
netrw-gn pi_netrw.txt /*netrw-gn*
netrw-gp pi_netrw.txt /*netrw-gp*
netrw-grep pi_netrw.txt /*netrw-grep*
-netrw-gx pi_netrw.txt /*netrw-gx*
-netrw-handler pi_netrw.txt /*netrw-handler*
netrw-help pi_netrw.txt /*netrw-help*
netrw-hexplore pi_netrw.txt /*netrw-hexplore*
netrw-hide pi_netrw.txt /*netrw-hide*
netrw-windows-netrc pi_netrw.txt /*netrw-windows-netrc*
netrw-windows-s pi_netrw.txt /*netrw-windows-s*
netrw-write pi_netrw.txt /*netrw-write*
-netrw-x pi_netrw.txt /*netrw-x*
netrw-xfer pi_netrw.txt /*netrw-xfer*
netrw.txt pi_netrw.txt /*netrw.txt*
netrw.vim pi_netrw.txt /*netrw.vim*
-*version9.txt* For Vim version 9.1. Last change: 2025 Jan 23
+*version9.txt* For Vim version 9.1. Last change: 2025 Jan 25
VIM REFERENCE MANUAL by Bram Moolenaar
- |v:stacktrace| The stack trace of the exception most recently caught and
not finished
- New option value "nosort" for 'completeopt'
+- add |dist#vim9#Launch()| and |dist#vim9#Open()| to the |vim-script-library|
+ and decouple it from |netrw|
*added-9.2*
Added ~
*g:netrw_menu* =0 disable netrw's menu
=1 (default) netrw's menu enabled
- *g:netrw_nogx* if this variable exists, then the "gx" map will not
- be available (see |netrw-gx|)
-
*g:netrw_uid* (ftp) user-id, retained on a per-vim-session basis
*s:netrw_passwd* (ftp) password, retained on a per-vim-session basis
U Change to subsequently-visited directory |netrw-U|
v Enter the file/directory under the cursor in a new |netrw-v|
browser window. A vertical split is used.
- x View file with an associated program |netrw-x|
+ x View file with an associated program. (see |:Open|)
X Execute filename under cursor via |system()| |netrw-X|
% Open a new file in netrw's current directory |netrw-%|
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.
-CUSTOMIZING BROWSING WITH A SPECIAL HANDLER *netrw-x* *netrw-handler* {{{2
-
-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
-operating system). Netrw allows one to invoke such special handlers by:
-
- * hitting gx with the cursor atop the file path or alternatively x
- in a netrw buffer; the former can be disabled by defining the
- |g:netrw_nogx| variable
- * when in command line, typing :Open <path>, see |:Open| below.
-
-One may also use visual mode (see |visual-start|) to select the text that the
-special handler will use. Normally gx checks for a close-by URL or file name
-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
-expand("<cfile>") depends on the |'isfname'| setting. Alternatively, one may
-select the text to be used by gx by making a visual selection (see
-|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
- return ''
- finally
- call winrestview(save_view)
- 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
- return ''
- finally
- call winrestview(save_view)
- 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:
- |g:netrw_gx| control how gx picks up the text under the cursor
- |g:netrw_nogx| prevent gx map while editing
- |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.
- 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*
DELETING BOOKMARKS *netrw-mB* {{{2
|netrw-C| |netrw-cr|
|netrw-ctrl-r|
- *g:netrw_browsex_viewer* specify user's preference for a viewer: >
- "kfmclient exec"
- "gnome-open"
-<
- *g:netrw_browsex_support_remote*
- specify if the specified viewer supports a
- remote URL. (see |netrw-handler|).
-
*g:netrw_chgperm* Unix/Linux: "chmod PERM FILENAME"
Windows: "cacls FILENAME /e /p PERM"
Used to change access permission for a file.
*g:Netrw_corehandler* Allows one to specify something additional
to do when handling <core> files via netrw's
- browser's "x" command (see |netrw-x|). If
- present, g:Netrw_corehandler specifies
- either one or more function references
- (see |Funcref|). (the capital g:Netrw...
- is required its holding a function reference)
-
+ browser's "x" command. If present,
+ g:Netrw_corehandler specifies either one or
+ more function references (see |Funcref|).
+ (the capital g:Netrw... is required its
+ holding a function reference)
*g:netrw_ctags* ="ctags"
The default external program used to create
These characters in directory names are
escaped before applying glob()
- *g:netrw_gx* ="<cfile>"
- This option controls how gx (|netrw-gx|) picks
- up the text under the cursor. See |expand()|
- for possibilities.
-
*g:netrw_hide* Controlled by the "a" map (see |netrw-a|)
=0 : show all
=1 : show not-hidden files
let s:keepcpo = &cpo
set cpo&vim
-" Commands Launch/URL: {{{
-
-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: {{{
augroup FileExplorer
" }}}
" Maps: {{{
-if !exists("g:netrw_nogx")
- if maparg('gx','n') == ""
- if !hasmapto('<Plug>NetrwBrowseX')
- nmap <unique> gx <Plug>NetrwBrowseX
- endif
- nno <silent> <Plug>NetrwBrowseX :call netrw#BrowseX(netrw#GX(),netrw#CheckIfRemote(netrw#GX()))<cr>
- endif
- if maparg('gx','x') == ""
- if !hasmapto('<Plug>NetrwBrowseXVis')
- xmap <unique> gx <Plug>NetrwBrowseXVis
- endif
- xno <silent> <Plug>NetrwBrowseXVis :<c-u>call netrw#BrowseXVis()<cr>
- endif
-endif
-
if exists("g:netrw_usetab") && g:netrw_usetab
if maparg('<c-tab>','n') == ""
nmap <unique> <c-tab> <Plug>NetrwShrink
--- /dev/null
+vim9script
+
+# Vim runtime support library
+#
+# Maintainer: The Vim Project <https://github.com/vim/vim>
+# Last Change: 2025 Jan 24
+
+import autoload 'dist/vim9.vim'
+
+command -complete=shellcmd -nargs=1 Launch vim9.Launch(trim(<q-args>))
+command -complete=file -nargs=1 Open vim9.Open(trim(<q-args>))
+
+const no_gx = get(g:, "nogx", get(g:, "netrw_nogx", false))
+if !no_gx
+ if maparg('gx', 'n') == ""
+ const file = get(g:, 'netrw_gx', '<cfile>')
+ nnoremap <unique> gx <scriptcmd>vim9.Open(expand(file))<CR>
+ endif
+ if maparg('gx', 'x') == ""
+ xnoremap <unique> gx <scriptcmd>vim9.Open(getregion(getpos('v'), getpos('.'), { type: mode() })->join())<CR>
+ endif
+endif
+
+# vim: ts=8 sts=2 sw=2 et