runtime(netrw): upstream snapshot of v176

relevant commits:
- deprecate!: netrw#Launch, netrw#Open and gx mappings
- refactor: move some utility functions in a private file
- feat: add function to deprecate features
- refactor!: remove NetrwClean command and function
- refactor: use appropriate directories to store temporary files
- refactor: better way to call vim.ui.open
- refactor(Open): prefer lua wrapper function instead of cmdline
- refactor!: drop vim 7 checks
- refactor: use vim.ui.open when using neovim
- refactor: remove s:CheckIfKde
- refactor: balloon functionality
- refactor!: remove netrw#Access function

closes: #16519

Signed-off-by: Luca Saccarola <github.e41mv@aleeas.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/Filelist b/Filelist
index 8e12302..db61ceb 100644
--- a/Filelist
+++ b/Filelist
@@ -812,6 +812,7 @@
 		runtime/pack/dist/opt/netrw/LICENSE.txt \
 		runtime/pack/dist/opt/netrw/README.md \
 		runtime/pack/dist/opt/netrw/autoload/netrw.vim \
+		runtime/pack/dist/opt/netrw/autoload/netrw/own.vim \
 		runtime/pack/dist/opt/netrw/autoload/netrwSettings.vim \
 		runtime/pack/dist/opt/netrw/autoload/netrw_gitignore.vim \
 		runtime/pack/dist/opt/netrw/doc/netrw.txt \
diff --git a/runtime/doc/tags b/runtime/doc/tags
index f1d32d8..378fb83 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -2140,7 +2140,6 @@
 :Man	filetype.txt	/*:Man*
 :MkVimball	pi_vimball.txt	/*:MkVimball*
 :N	editing.txt	/*:N*
-:NetrwClean	pi_netrw.txt	/*:NetrwClean*
 :Nexplore	pi_netrw.txt	/*:Nexplore*
 :Next	editing.txt	/*:Next*
 :NoMatchParen	pi_paren.txt	/*:NoMatchParen*
@@ -7711,7 +7710,6 @@
 g:netrw_ssh_browse_reject	pi_netrw.txt	/*g:netrw_ssh_browse_reject*
 g:netrw_ssh_cmd	pi_netrw.txt	/*g:netrw_ssh_cmd*
 g:netrw_sshport	pi_netrw.txt	/*g:netrw_sshport*
-g:netrw_suppress_gx_mesg	pi_netrw.txt	/*g:netrw_suppress_gx_mesg*
 g:netrw_timefmt	pi_netrw.txt	/*g:netrw_timefmt*
 g:netrw_tmpfile_escape	pi_netrw.txt	/*g:netrw_tmpfile_escape*
 g:netrw_uid	pi_netrw.txt	/*g:netrw_uid*
@@ -8992,7 +8990,6 @@
 netrw-cb	pi_netrw.txt	/*netrw-cb*
 netrw-cd	pi_netrw.txt	/*netrw-cd*
 netrw-chgup	pi_netrw.txt	/*netrw-chgup*
-netrw-clean	pi_netrw.txt	/*netrw-clean*
 netrw-contents	pi_netrw.txt	/*netrw-contents*
 netrw-copyright	pi_netrw.txt	/*netrw-copyright*
 netrw-cr	pi_netrw.txt	/*netrw-cr*
@@ -9002,7 +8999,6 @@
 netrw-ctrl-l	pi_netrw.txt	/*netrw-ctrl-l*
 netrw-ctrl-r	pi_netrw.txt	/*netrw-ctrl-r*
 netrw-ctrl_l	pi_netrw.txt	/*netrw-ctrl_l*
-netrw-curdir	pi_netrw.txt	/*netrw-curdir*
 netrw-d	pi_netrw.txt	/*netrw-d*
 netrw-del	pi_netrw.txt	/*netrw-del*
 netrw-delete	pi_netrw.txt	/*netrw-delete*
diff --git a/runtime/pack/dist/opt/netrw/autoload/netrw.vim b/runtime/pack/dist/opt/netrw/autoload/netrw.vim
index df157e4..7d7ff15 100644
--- a/runtime/pack/dist/opt/netrw/autoload/netrw.vim
+++ b/runtime/pack/dist/opt/netrw/autoload/netrw.vim
@@ -19,23 +19,7 @@
   finish
 endif
 
-" Check that vim has patches that netrw requires.
-" Patches needed for v7.4: 1557, and 213.
-" (netrw will benefit from vim's having patch#656, too)
-let s:needspatches=[1557,213]
-if exists("s:needspatches")
-  for ptch in s:needspatches
-    if v:version < 704 || (v:version == 704 && !has("patch".ptch))
-      if !exists("s:needpatch{ptch}")
-        unsilent echomsg "***sorry*** this version of netrw requires vim v7.4 with patch#".ptch
-      endif
-      let s:needpatch{ptch}= 1
-      finish
-    endif
-  endfor
-endif
-
-let g:loaded_netrw = "v175"
+let g:loaded_netrw = "v176"
 
 let s:keepcpo= &cpo
 setl cpo&vim
@@ -194,6 +178,12 @@
 let s:ERROR   = 2
 call s:NetrwInit("g:netrw_errorlvl", s:NOTE)
 
+let s:has_balloon = !has('nvim') &&
+            \ has("balloon_eval") &&
+            \ has("syntax") &&
+            \ exists("g:syntax_on") &&
+            \ !exists("g:netrw_nobeval")
+
 " ---------------------------------------------------------------------
 " Default option values: {{{2
 let g:netrw_localcopycmdopt    = ""
@@ -456,10 +446,12 @@
   call s:NetrwInit("g:netrw_localmkdir","mkdir")
 endif
 call s:NetrwInit("g:netrw_remote_mkdir","mkdir")
+
 if exists("g:netrw_local_movecmd")
   let g:netrw_localmovecmd= g:netrw_local_movecmd
   call netrw#ErrorMsg(s:NOTE,"g:netrw_local_movecmd is deprecated in favor of g:netrw_localmovecmd",88)
 endif
+
 if !exists("g:netrw_localmovecmd")
   if has("win32")
     if g:netrw_cygwin
@@ -474,9 +466,7 @@
     let g:netrw_localmovecmd= ""
   endif
 endif
-" following serves as an example for how to insert a version&patch specific test
-"if v:version < 704 || (v:version == 704 && !has("patch1107"))
-"endif
+
 call s:NetrwInit("g:netrw_liststyle"  , s:THINLIST)
 " sanity checks
 if g:netrw_liststyle < 0 || g:netrw_liststyle >= s:MAXLIST
@@ -581,22 +571,14 @@
 " ======================
 "  Netrw Initialization: {{{1
 " ======================
-if v:version >= 700 && has("balloon_eval") && !exists("s:initbeval") && !exists("g:netrw_nobeval") && has("syntax") && exists("g:syntax_on")
-  " call Decho("installed beval events",'~'.expand("<slnum>"))
+if s:has_balloon
   let &l:bexpr = "netrw#BalloonHelp()"
-  " call Decho("&l:bexpr<".&l:bexpr."> buf#".bufnr())
-  au FileType netrw      setl beval
-  au WinLeave *          if &ft == "netrw" && exists("s:initbeval")|let &beval= s:initbeval|endif
-  au VimEnter *          let s:initbeval= &beval
-  "else " Decho
-  " if v:version < 700           | call Decho("did not install beval events: v:version=".v:version." < 700","~".expand("<slnum>"))     | endif
-  " if !has("balloon_eval")      | call Decho("did not install beval events: does not have balloon_eval","~".expand("<slnum>"))        | endif
-  " if exists("s:initbeval")     | call Decho("did not install beval events: s:initbeval exists","~".expand("<slnum>"))                | endif
-  " if exists("g:netrw_nobeval") | call Decho("did not install beval events: g:netrw_nobeval exists","~".expand("<slnum>"))            | endif
-  " if !has("syntax")            | call Decho("did not install beval events: does not have syntax highlighting","~".expand("<slnum>")) | endif
-  " if exists("g:syntax_on")     | call Decho("did not install beval events: g:syntax_on exists","~".expand("<slnum>"))                | endif
+  au FileType netrw setl beval
+  au WinLeave * if &ft == "netrw" && exists("s:initbeval") | let &beval = s:initbeval | endif
+  au VimEnter * let s:initbeval = &beval
 endif
-au WinEnter *   if &ft == "netrw"|call s:NetrwInsureWinVars()|endif
+
+au WinEnter * if &ft == "netrw" | call s:NetrwInsureWinVars() | endif
 
 if g:netrw_keepj =~# "keepj"
   com! -nargs=*  NetrwKeepj      keepj <args>
@@ -611,50 +593,46 @@
 
 " ---------------------------------------------------------------------
 " netrw#BalloonHelp: {{{2
-if v:version >= 700 && has("balloon_eval") && has("syntax") && exists("g:syntax_on") && !exists("g:netrw_nobeval")
-  " call Decho("loading netrw#BalloonHelp()",'~'.expand("<slnum>"))
-  fun! netrw#BalloonHelp()
-    if &ft != "netrw"
-      return ""
-    endif
-    if exists("s:popuperr_id") && popup_getpos(s:popuperr_id) != {}
-      " popup error window is still showing
-      " s:pouperr_id and s:popuperr_text are set up in netrw#ErrorMsg()
-      if exists("s:popuperr_text") && s:popuperr_text != "" && v:beval_text != s:popuperr_text
-        " text under mouse hasn't changed; only close window when it changes
-        call popup_close(s:popuperr_id)
-        unlet s:popuperr_text
-      else
-        let s:popuperr_text= v:beval_text
-      endif
-      let mesg= ""
-    elseif !exists("w:netrw_bannercnt") || v:beval_lnum >= w:netrw_bannercnt || (exists("g:netrw_nobeval") && g:netrw_nobeval)
-      let mesg= ""
-    elseif     v:beval_text == "Netrw" || v:beval_text == "Directory" || v:beval_text == "Listing"
-      let mesg = "i: thin-long-wide-tree  gh: quick hide/unhide of dot-files   qf: quick file info  %:open new file"
-    elseif     getline(v:beval_lnum) =~ '^"\s*/'
-      let mesg = "<cr>: edit/enter   o: edit/enter in horiz window   t: edit/enter in new tab   v:edit/enter in vert window"
-    elseif     v:beval_text == "Sorted" || v:beval_text == "by"
-      let mesg = 's: sort by name, time, file size, extension   r: reverse sorting order   mt: mark target'
-    elseif v:beval_text == "Sort"   || v:beval_text == "sequence"
-      let mesg = "S: edit sorting sequence"
-    elseif v:beval_text == "Hiding" || v:beval_text == "Showing"
-      let mesg = "a: hiding-showing-all   ctrl-h: editing hiding list   mh: hide/show by suffix"
-    elseif v:beval_text == "Quick" || v:beval_text == "Help"
-      let mesg = "Help: press <F1>"
-    elseif v:beval_text == "Copy/Move" || v:beval_text == "Tgt"
-      let mesg = "mt: mark target   mc: copy marked file to target   mm: move marked file to target"
-    else
-      let mesg= ""
-    endif
-    return mesg
-  endfun
-  "else " Decho
-  " if v:version < 700            |call Decho("did not load netrw#BalloonHelp(): vim version ".v:version." < 700 -","~".expand("<slnum>"))|endif
-  " if !has("balloon_eval")       |call Decho("did not load netrw#BalloonHelp(): does not have balloon eval","~".expand("<slnum>"))       |endif
-  " if !has("syntax")             |call Decho("did not load netrw#BalloonHelp(): syntax disabled","~".expand("<slnum>"))                  |endif
-  " if !exists("g:syntax_on")     |call Decho("did not load netrw#BalloonHelp(): g:syntax_on n/a","~".expand("<slnum>"))                  |endif
-  " if  exists("g:netrw_nobeval") |call Decho("did not load netrw#BalloonHelp(): g:netrw_nobeval exists","~".expand("<slnum>"))           |endif
+
+if s:has_balloon
+    function! netrw#BalloonHelp()
+        " popup error window is still showing
+        " s:pouperr_id and s:popuperr_text are set up in netrw#ErrorMsg()
+        if exists("s:popuperr_id") && popup_getpos(s:popuperr_id) != {}
+            if exists("s:popuperr_text") && s:popuperr_text != "" && v:beval_text != s:popuperr_text
+                " text under mouse hasn't changed; only close window when it changes
+                call popup_close(s:popuperr_id)
+                unlet s:popuperr_text
+            else
+                let s:popuperr_text= v:beval_text
+            endif
+            return ""
+
+        elseif v:beval_text == "Netrw" || v:beval_text == "Directory" || v:beval_text == "Listing"
+            return "i: thin-long-wide-tree  gh: quick hide/unhide of dot-files   qf: quick file info  %:open new file"
+
+        elseif getline(v:beval_lnum) =~ '^"\s*/'
+            return "<cr>: edit/enter   o: edit/enter in horiz window   t: edit/enter in new tab   v:edit/enter in vert window"
+
+        elseif v:beval_text == "Sorted" || v:beval_text == "by"
+            return 's: sort by name, time, file size, extension   r: reverse sorting order   mt: mark target'
+
+        elseif v:beval_text == "Sort"   || v:beval_text == "sequence"
+            return "S: edit sorting sequence"
+
+        elseif v:beval_text == "Hiding" || v:beval_text == "Showing"
+            return "a: hiding-showing-all   ctrl-h: editing hiding list   mh: hide/show by suffix"
+
+        elseif v:beval_text == "Quick" || v:beval_text == "Help"
+            return "Help: press <F1>"
+
+        elseif v:beval_text == "Copy/Move" || v:beval_text == "Tgt"
+            return "mt: mark target   mc: copy marked file to target   mm: move marked file to target"
+
+        endif
+
+        return ""
+    endfunction
 endif
 
 " ------------------------------------------------------------------------
@@ -1176,52 +1154,6 @@
 endfun
 
 " ---------------------------------------------------------------------
-" netrw#Clean: remove netrw {{{2
-" supports :NetrwClean  -- remove netrw from first directory on runtimepath
-"          :NetrwClean! -- remove netrw from all directories on runtimepath
-fun! netrw#Clean(sys)
-  "  call Dfunc("netrw#Clean(sys=".a:sys.")")
-
-  if a:sys
-    let choice= confirm("Remove personal and system copies of netrw?","&Yes\n&No")
-  else
-    let choice= confirm("Remove personal copy of netrw?","&Yes\n&No")
-  endif
-  "  call Decho("choice=".choice,'~'.expand("<slnum>"))
-  let diddel= 0
-  let diddir= ""
-
-  if choice == 1
-    for dir in split(&rtp,',')
-      if filereadable(dir."/plugin/netrwPlugin.vim")
-        "     call Decho("removing netrw-related files from ".dir,'~'.expand("<slnum>"))
-        if s:NetrwDelete(dir."/plugin/netrwPlugin.vim")        |call netrw#ErrorMsg(1,"unable to remove ".dir."/plugin/netrwPlugin.vim",55)        |endif
-        if s:NetrwDelete(dir."/autoload/netrwFileHandlers.vim")|call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrwFileHandlers.vim",55)|endif
-        if s:NetrwDelete(dir."/autoload/netrwSettings.vim")    |call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrwSettings.vim",55)    |endif
-        if s:NetrwDelete(dir."/autoload/netrw.vim")            |call netrw#ErrorMsg(1,"unable to remove ".dir."/autoload/netrw.vim",55)            |endif
-        if s:NetrwDelete(dir."/syntax/netrw.vim")              |call netrw#ErrorMsg(1,"unable to remove ".dir."/syntax/netrw.vim",55)              |endif
-        if s:NetrwDelete(dir."/syntax/netrwlist.vim")          |call netrw#ErrorMsg(1,"unable to remove ".dir."/syntax/netrwlist.vim",55)          |endif
-        let diddir= dir
-        let diddel= diddel + 1
-        if !a:sys|break|endif
-      endif
-    endfor
-  endif
-
-  echohl WarningMsg
-  if diddel == 0
-    echomsg "netrw is either not installed or not removable"
-  elseif diddel == 1
-    echomsg "removed one copy of netrw from <".diddir.">"
-  else
-    echomsg "removed ".diddel." copies of netrw"
-  endif
-  echohl None
-
-  "  call Dret("netrw#Clean")
-endfun
-
-" ---------------------------------------------------------------------
 " netrw#MakeTgt: make a target out of the directory name provided {{{2
 fun! netrw#MakeTgt(dname)
   "  call Dfunc("netrw#MakeTgt(dname<".a:dname.">)")
@@ -3830,7 +3762,8 @@
   else
     NetrwKeepj call s:SetRexDir(a:islocal,b:netrw_curdir)
   endif
-  if v:version >= 700 && has("balloon_eval") && &beval == 0 && &l:bexpr == "" && !exists("g:netrw_nobeval")
+
+  if s:has_balloon && &beval == 0 && &l:bexpr == ""
     let &l:bexpr= "netrw#BalloonHelp()"
     setl beval
   endif
@@ -4467,16 +4400,16 @@
     let i = 1
     while i <= a:0
       if islocal
-        if v:version > 704 || (v:version == 704 && has("patch656"))
-          let mbfiles= glob(fnameescape(a:{i}),0,1,1)
-        else
-          let mbfiles= glob(fnameescape(a:{i}),0,1)
-        endif
+        let mbfiles = glob(fnameescape(a:{i}), 0, 1, 1)
       else
-        let mbfiles= [a:{i}]
+        let mbfiles = [a:{i}]
       endif
       for mbfile in mbfiles
-        if a:del|call s:DeleteBookmark(mbfile)|else|call s:MakeBookmark(mbfile)|endif
+        if a:del
+            call s:DeleteBookmark(mbfile)
+        else
+            call s:MakeBookmark(mbfile)
+        endif
       endfor
       let i= i + 1
     endwhile
@@ -4954,122 +4887,6 @@
   endif
 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() (has('gui_running') ? '' : '&') | 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()
-  " g:netrw_browsex_viewer could be a string of program + its arguments,
-  " test if first argument is executable
-  if exists('g:netrw_browsex_viewer') && executable(split(g:netrw_browsex_viewer)[0])
-    " 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))
-endfun
-
-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
 "              given filename; typically this means given their extension.
@@ -5150,7 +4967,7 @@
     endif
   endif
 
-  call netrw#Open(fname)
+  call netrw#own#Open(fname)
 
   " cleanup: remove temporary file,
   "          delete current buffer if success with handler,
@@ -5174,46 +4991,6 @@
 endfun
 
 " ---------------------------------------------------------------------
-" netrw#GX: gets word under cursor for gx support {{{2
-"           See also: netrw#BrowseXVis
-"                     netrw#BrowseX
-fun! netrw#GX()
-  "  call Dfunc("netrw#GX()")
-  if &ft == "netrw"
-    let fname= s:NetrwGetWord()
-  else
-    let fname= exists("g:netrw_gx")? expand(g:netrw_gx) : s:GetURL()
-  endif
-  "  call Dret("netrw#GX <".fname.">")
-  return fname
-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
 fun! netrw#BrowseXVis()
   let dict={}
@@ -5299,31 +5076,6 @@
 endfun
 
 " ---------------------------------------------------------------------
-" s:CheckIfKde: checks if kdeinit is running {{{2
-"    Returns 0: kdeinit not running
-"            1: kdeinit is  running
-fun! s:CheckIfKde()
-  "  call Dfunc("s:CheckIfKde()")
-  " seems kde systems often have gnome-open due to dependencies, even though
-  " gnome-open's subsidiary display tools are largely absent.  Kde systems
-  " usually have "kdeinit" running, though...  (tnx Mikolaj Machowski)
-  if !exists("s:haskdeinit")
-    if has("unix") && executable("ps") && !has("win32unix")
-      let s:haskdeinit= system("ps -e") =~ '\<kdeinit'
-      if v:shell_error
-        let s:haskdeinit = 0
-      endif
-    else
-      let s:haskdeinit= 0
-    endif
-    "   call Decho("setting s:haskdeinit=".s:haskdeinit,'~'.expand("<slnum>"))
-  endif
-
-  "  call Dret("s:CheckIfKde ".s:haskdeinit)
-  return s:haskdeinit
-endfun
-
-" ---------------------------------------------------------------------
 " s:NetrwClearExplore: clear explore variables (if any) {{{2
 fun! s:NetrwClearExplore()
   "  call Dfunc("s:NetrwClearExplore()")
@@ -5437,11 +5189,7 @@
       " escape [ so it is not detected as wildcard character, see :h wildcard
       let path= substitute(path, '[', '[[]', 'g')
     endif
-    if v:version > 704 || (v:version == 704 && has("patch656"))
-      let filelist= glob(path,0,1,1)
-    else
-      let filelist= glob(path,0,1)
-    endif
+    let filelist = glob(path, 0, 1, 1)
     if a:pare
       let filelist= map(filelist,'substitute(v:val, "^.*/", "", "")')
     endif
@@ -5561,41 +5309,32 @@
 
 " ---------------------------------------------------------------------
 "  s:NetrwHome: this function determines a "home" for saving bookmarks and history {{{2
-fun! s:NetrwHome()
-  if exists("g:netrw_home")
-    let home= expand(g:netrw_home)
+function! s:NetrwHome()
+  if has('nvim')
+    let home = netrw#own#JoinPath(stdpath('state'), 'netrw')
+  elseif exists("g:netrw_home")
+    let home = expand(g:netrw_home)
   else
-    " go to vim plugin home
-    for home in split(&rtp,',') + ['']
-      if isdirectory(s:NetrwFile(home)) && filewritable(s:NetrwFile(home)) | break | endif
-      let basehome= substitute(home,'[/\\]\.vim$','','')
-      if isdirectory(s:NetrwFile(basehome)) && filewritable(s:NetrwFile(basehome))
-        let home= basehome."/.vim"
-        break
-      endif
-    endfor
-    if home == ""
-      " just pick the first directory
-      let home= substitute(&rtp,',.*$','','')
-    endif
-    if has("win32")
-      let home= substitute(home,'/','\\','g')
-    endif
+    let home = expand("$MYVIMDIR")->substitute("/$", "", "")
   endif
+
   " insure that the home directory exists
   if g:netrw_dirhistmax > 0 && !isdirectory(s:NetrwFile(home))
-    "   call Decho("insure that the home<".home."> directory exists")
     if exists("g:netrw_mkdir")
-      "    call Decho("call system(".g:netrw_mkdir." ".s:ShellEscape(s:NetrwFile(home)).")")
       call system(g:netrw_mkdir." ".s:ShellEscape(s:NetrwFile(home)))
     else
-      "    call Decho("mkdir(".home.")")
       call mkdir(home)
     endif
   endif
-  let g:netrw_home= home
+
+  " Normalize directory if on Windows
+  if has("win32")
+    let home = substitute(home, '/', '\\', 'g')
+  endif
+
+  let g:netrw_home = home
   return home
-endfun
+endfunction
 
 " ---------------------------------------------------------------------
 " s:NetrwLeftmouse: handles the <leftmouse> when in a netrw browsing window {{{2
@@ -6297,11 +6036,7 @@
   let i      = 1
   while i <= a:0
     if a:islocal
-      if v:version > 704 || (v:version == 704 && has("patch656"))
-        let mffiles= glob(a:{i},0,1,1)
-      else
-        let mffiles= glob(a:{i},0,1)
-      endif
+      let mffiles= glob(a:{i}, 0, 1, 1)
     else
       let mffiles= [a:{i}]
     endif
@@ -7407,12 +7142,7 @@
     " get the matching list of files using local glob()
     "   call Decho("handle local regexp",'~'.expand("<slnum>"))
     let dirname = escape(b:netrw_curdir,g:netrw_glob_escape)
-    if v:version > 704 || (v:version == 704 && has("patch656"))
-      let filelist= glob(s:ComposePath(dirname,regexp),0,1,1)
-    else
-      let files   = glob(s:ComposePath(dirname,regexp),0,0)
-      let filelist= split(files,"\n")
-    endif
+    let filelist= glob(s:ComposePath(dirname,regexp),0,1,1)
     "   call Decho("files<".string(filelist).">",'~'.expand("<slnum>"))
 
     " mark the list of files
@@ -10632,22 +10362,6 @@
 " Support Functions: {{{1
 
 " ---------------------------------------------------------------------
-" netrw#Access: intended to provide access to variable values for netrw's test suite {{{2
-"   0: marked file list of current buffer
-"   1: marked file target
-fun! netrw#Access(ilist)
-  if     a:ilist == 0
-    if exists("s:netrwmarkfilelist_".bufnr('%'))
-      return s:netrwmarkfilelist_{bufnr('%')}
-    else
-      return "no-list-buf#".bufnr('%')
-    endif
-  elseif a:ilist == 1
-    return s:netrwmftgt
-  endif
-endfun
-
-" ---------------------------------------------------------------------
 " netrw#Call: allows user-specified mappings to call internal netrw functions {{{2
 fun! netrw#Call(funcname,...)
   return call("s:".a:funcname,a:000)
@@ -11275,7 +10989,8 @@
       endif
     endif
   endif
-  if v:version >= 700 && has("balloon_eval") && !exists("s:initbeval") && !exists("g:netrw_nobeval") && has("syntax") && exists("g:syntax_on")
+
+  if s:has_balloon
     let &l:bexpr = "netrw#BalloonHelp()"
   endif
 
@@ -11774,8 +11489,8 @@
 fun! s:Strlen(x)
   "  "" call Dfunc("s:Strlen(x<".a:x."> g:Align_xstrlen=".g:Align_xstrlen.")")
 
-  if v:version >= 703 && exists("*strdisplaywidth")
-    let ret= strdisplaywidth(a:x)
+  if exists("*strdisplaywidth")
+    let ret = strdisplaywidth(a:x)
 
   elseif type(g:Align_xstrlen) == 1
     " allow user to specify a function to compute the string length  (ie. let g:Align_xstrlen="mystrlenfunc")
@@ -11784,13 +11499,13 @@
   elseif g:Align_xstrlen == 1
     " number of codepoints (Latin a + combining circumflex is two codepoints)
     " (comment from TM, solution from NW)
-    let ret= strlen(substitute(a:x,'.','c','g'))
+    let ret = strlen(substitute(a:x,'.','c','g'))
 
   elseif g:Align_xstrlen == 2
     " number of spacing codepoints (Latin a + combining circumflex is one spacing
     " codepoint; a hard tab is one; wide and narrow CJK are one each; etc.)
     " (comment from TM, solution from TM)
-    let ret=strlen(substitute(a:x, '.\Z', 'x', 'g'))
+    let ret = strlen(substitute(a:x, '.\Z', 'x', 'g'))
 
   elseif g:Align_xstrlen == 3
     " virtual length (counting, for instance, tabs as anything between 1 and
@@ -11800,14 +11515,14 @@
     let modkeep= &l:mod
     exe "norm! o\<esc>"
     call setline(line("."),a:x)
-    let ret= virtcol("$") - 1
+    let ret = virtcol("$") - 1
     d
     NetrwKeepj norm! k
-    let &l:mod= modkeep
+    let &l:mod = modkeep
 
   else
     " at least give a decent default
-    let ret= strlen(a:x)
+    let ret = strlen(a:x)
   endif
   "  "" call Dret("s:Strlen ".ret)
   return ret
@@ -11930,6 +11645,21 @@
   endif
 endfun
 
+" Deprecated: {{{
+
+function! netrw#Launch(args)
+    call netrw#own#Deprecate('netrw#Launch', 'v180', {'vim': 'dist#vim9#Launch', 'nvim': 'vim.system'})
+    if !has('nvim')
+        call dist#vim9#Launch(args)
+    endif
+endfunction
+
+function! netrw#Open(file)
+    call netrw#own#Deprecate('netrw#Open', 'v180', {'vim': 'dist#vim9#Open', 'nvim': 'vim.ui.open'})
+    call netrw#own#Open(a:file)
+endfunction
+
+" }}}
 " ==========================
 " Settings Restoration: {{{1
 " ==========================
@@ -11939,4 +11669,5 @@
 " ===============
 " Modelines: {{{1
 " ===============
-" vim:ts=8 sts=2 sw=2 et fdm=marker
+
+" vim:ts=8 sts=4 sw=4 et fdm=marker
diff --git a/runtime/pack/dist/opt/netrw/autoload/netrw/own.vim b/runtime/pack/dist/opt/netrw/autoload/netrw/own.vim
new file mode 100644
index 0000000..8f05b6a
--- /dev/null
+++ b/runtime/pack/dist/opt/netrw/autoload/netrw/own.vim
@@ -0,0 +1,53 @@
+" FUNCTIONS IN THIS FILES ARE MENT TO BE USE BY NETRW.VIM AND NETRW.VIM ONLY.
+" THIS FUNCTIONS DON'T COMMIT TO ANY BACKWARDS COMPATABILITY. SO CHANGES AND
+" BREAKAGES IF USED OUTSIDE OF NETRW.VIM ARE EXPECTED.
+
+let s:deprecation_msgs = []
+function! netrw#own#Deprecate(name, version, alternatives)
+    " If running on neovim use vim.deprecate
+    if has('nvim')
+        let s:alternative = a:alternatives->get('nvim', v:null)
+        call luaeval('vim.deprecate(unpack(_A)) and nil', [a:name, s:alternative, a:version, "netrw", v:false])
+        return
+    endif
+
+    " If we did notify for something only do it once
+    if s:deprecation_msgs->index(a:name) >= 0
+        return
+    endif
+
+    let s:alternative = a:alternatives->get('vim', v:null)
+    echohl WarningMsg
+    echomsg s:alternative != v:null
+                \ ? printf('%s is deprecated, use %s instead.', a:name, s:alternative)
+                \ : printf('%s is deprecated.', a:name)
+    echomsg printf('Feature will be removed in netrw %s', a:version)
+    echohl None
+
+    call add(s:deprecation_msgs, a:name)
+endfunction
+
+let s:slash = &shellslash ? '/' : '\'
+function! netrw#own#JoinPath(...)
+    let path = ""
+
+    for arg in a:000
+        if empty(path)
+            let path = arg
+        else
+            let path .= s:slash . arg
+        endif
+    endfor
+
+    return path
+endfunction
+
+function! netrw#own#Open(file) abort
+    if has('nvim')
+        call luaeval('vim.ui.open(_A[1]) and nil', [a:file])
+    else
+        call dist#vim9#Open(a:file)
+    endif
+endfunction
+
+" vim:ts=8 sts=4 sw=4 et fdm=marker
diff --git a/runtime/pack/dist/opt/netrw/autoload/netrwSettings.vim b/runtime/pack/dist/opt/netrw/autoload/netrwSettings.vim
index 884d9ce..2d1787f 100644
--- a/runtime/pack/dist/opt/netrw/autoload/netrwSettings.vim
+++ b/runtime/pack/dist/opt/netrw/autoload/netrwSettings.vim
@@ -15,13 +15,7 @@
     finish
 endif
 
-let g:loaded_netrwSettings = "v175"
-if v:version < 700
- echohl WarningMsg
- echo "***warning*** this version of netrwSettings needs vim 7.0"
- echohl Normal
- finish
-endif
+let g:loaded_netrwSettings = "v176"
 
 " NetrwSettings: {{{
 
diff --git a/runtime/pack/dist/opt/netrw/doc/netrw.txt b/runtime/pack/dist/opt/netrw/doc/netrw.txt
index 4afe538..1c291a5 100644
--- a/runtime/pack/dist/opt/netrw/doc/netrw.txt
+++ b/runtime/pack/dist/opt/netrw/doc/netrw.txt
@@ -59,7 +59,6 @@
       Changing local-only File Permission.................|netrw-gp|
       Changing To A Predecessor Directory.................|netrw-u|
       Changing To A Successor Directory...................|netrw-U|
-      Customizing Browsing With A Special Handler.........|netrw-x|
       Deleting Bookmarks..................................|netrw-mB|
       Deleting Files Or Directories.......................|netrw-D|
       Directory Exploring Commands........................|netrw-explore|
@@ -1110,7 +1109,7 @@
 	   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. (see |:Open|)
+	   x	View file with an associated program                 |:Open|
 	   X	Execute filename under cursor via |system()|           |netrw-X|
 
 	   %	Open a new file in netrw's current directory         |netrw-%|
@@ -1137,7 +1136,6 @@
 
 				*netrw-quickcom* *netrw-quickcoms*
 QUICK REFERENCE: COMMANDS	*netrw-explore-cmds* *netrw-browse-cmds* {{{2
-     :NetrwClean[!]............................................|netrw-clean|
      :NetrwSettings............................................|netrw-settings|
      :Ntree....................................................|netrw-ntree|
      :Explore[!]  [dir] Explore directory of current file......|netrw-explore|
@@ -1450,20 +1448,6 @@
 changing the top of the tree listing.
 
 
-NETRW CLEAN					*netrw-clean* *:NetrwClean* {{{2
-
-With :NetrwClean one may easily remove netrw from one's home directory;
-more precisely, from the first directory on your |'runtimepath'|.
-
-With :NetrwClean!, netrw will attempt to remove netrw from all directories on
-your |'runtimepath'|.  Of course, you have to have write/delete permissions
-correct to do this.
-
-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
-permission to remove a file, it will issue an error message.
-
-							*netrw-curdir*
 DELETING BOOKMARKS					*netrw-mB* {{{2
 
 To delete a bookmark, use >
@@ -2510,6 +2494,7 @@
 				(the capital g:Netrw... is required its
 				holding a function reference)
 
+
   *g:netrw_ctags*		="ctags"
 				The default external program used to create
 				tags
@@ -2913,14 +2898,6 @@
 				such as listing, file removal, etc.
 				 default: ssh
 
- *g:netrw_suppress_gx_mesg*	=1 : browsers sometimes produce messages
-				which are normally unwanted intermixed
-				with the page.
-				However, when using links, for example,
-				those messages are what the browser produces.
-				By setting this option to 0, netrw will not
-				suppress browser messages.
-
   *g:netrw_tmpfile_escape*	=' &;'
 				escape() is applied to all temporary files
 				to escape these characters.
diff --git a/runtime/pack/dist/opt/netrw/plugin/netrwPlugin.vim b/runtime/pack/dist/opt/netrw/plugin/netrwPlugin.vim
index 388a7f2..ec133d0 100644
--- a/runtime/pack/dist/opt/netrw/plugin/netrwPlugin.vim
+++ b/runtime/pack/dist/opt/netrw/plugin/netrwPlugin.vim
@@ -15,7 +15,7 @@
     finish
 endif
 
-let g:loaded_netrwPlugin = "v175"
+let g:loaded_netrwPlugin = "v176"
 
 let s:keepcpo = &cpo
 set cpo&vim
diff --git a/runtime/plugin/netrwPlugin.vim b/runtime/plugin/netrwPlugin.vim
index 6d7a866..f3684bb 100644
--- a/runtime/plugin/netrwPlugin.vim
+++ b/runtime/plugin/netrwPlugin.vim
@@ -1,5 +1,10 @@
 " Load the netrw package.
 
+if !has("patch-9.1.1054") || !has('nvim')
+  echoerr 'netrw needs vim v9.1.1054'
+  finish
+endif
+
 if &cp || exists("g:loaded_netrw") || exists("g:loaded_netrwPlugin")
   finish
 endif