[vim/vim] Fix netrw remote uri parse (PR #18611)

2 views
Skip to first unread message

Václav Kobera

unread,
Oct 20, 2025, 2:45:56 PM (15 hours ago) Oct 20
to vim/vim, Subscribed

Netrw remote parsing username bug

please let me know if i have to setup mail subscription i wasnt sure

Problem overview:

current implementation doesnt support remote usernames containing chars like -, ~, ... in netrw dir listing such as:

  • scp://user-01@remote/file.txt

netrw puts @ in front of the username

Example of problem:

vim scp://user-01@localost:2222/
netrw log:

...
continuing in <SNR>15_NetrwBookHistRead
No matching autocommands: FileType netrw
Calling shell to execute: "(ssh -p 2222 @user-01@localhost ls -FLa)>/var/folders/tm/3b4nbt4s0njcv3by50zsd7r00000gn/T/vcYg8jp/1 2>&1"

shell returned 255

Solution:

The problem was in parsing netrw remote uri in function RemotePathAnalysis

in regexp for user is \w+ which refers to 1+ word characters

i replaced this with [^@]+ which refers to 1+ anyhthing thats not @

i think this was same issue (#1222) and solution

i provided tests aswell but dont know if this is correct way to implement them - i couldnt get to netrw local variables so i made copy of netrw

also tested compiling vim and testing if it works with the change - for me it does
(testing against docker img running shh and 2 users 'root' and 'user-01')

i dont undestand what if @ does (what it solves) in RemotePathAnalysis so maybe im missing something

  • so i keep it there

  • decoded regexps with example below

i had this tests failing on my machine:

  • Test_cmdwin_restore_3.dump
  • Test_colorcolumn_2.dump
  • Test_colorcolumn_3.dump
  • Test_popupwin_04a.dump
  • Test_pum_completeitemalign_07.dump
  • Test_pum_maxwidth_05.dump

Problem Workaround:

make .ssh/config

Host u1
  HostName <host> 
  User user-01
vim scp://u1/dir/file.txt #will work file 

Example diff and what if @ does

here is what i used for quick testing just :source the file

" s:RemotePathAnalysis: {{{2


function s:RemotePathAnalysis(dirname)

    "                method   ://    user  @      machine      :port            /path
    let dirpat  = '^\(\w\{-}\)://\(\(\w\+\)@\)\=\([^/:#]\+\)\%([:#]\(\d\+\)\)\=/\(.*\)$'
    let s:method  = substitute(a:dirname,dirpat,'\1','')
    let s:user    = substitute(a:dirname,dirpat,'\3','')
    let s:machine = substitute(a:dirname,dirpat,'\4','')
    let s:port    = substitute(a:dirname,dirpat,'\5','')
    let s:path    = substitute(a:dirname,dirpat,'\6','')
    let s:fname   = substitute(s:path,'^.*/\ze.','','')

    echo 'user:' s:user
    echo 'machine:' s:machine
    echo 'method:' s:method
    echo 'port:' s:port
    echo 'path:' s:path
    echo 'fname:' s:fname

    if s:machine =~ '@' "machine contains @"
        echo '==> machine contains @'
        let dirpat    = '^\(.*\)@\(.\{-}\)$' "split machine by @"
        let s:user    = s:user.'@'.substitute(s:machine,dirpat,'\1','') "makes user@<machine_part1>"
        let s:machine = substitute(s:machine,dirpat,'\2','')  "makes user@<machine_part2>"

        echo 'user:' s:user
        echo 'machine:' s:machine
        echo 'method:' s:method
        echo 'port:' s:port
        echo 'path:' s:path
        echo 'fname:' s:fname
    endif
endfunction

function s:RemotePathAnalysisNew(dirname)

    "                method   ://    user  @      machine      :port            /path
    let dirpat  = '^\(\w\{-}\)://\(\([^@]\+\)@\)\=\([^/:#]\+\)\%([:#]\(\d\+\)\)\=/\(.*\)$'
    let s:method  = substitute(a:dirname,dirpat,'\1','')
    let s:user    = substitute(a:dirname,dirpat,'\3','')
    let s:machine = substitute(a:dirname,dirpat,'\4','')
    let s:port    = substitute(a:dirname,dirpat,'\5','')
    let s:path    = substitute(a:dirname,dirpat,'\6','')
    let s:fname   = substitute(s:path,'^.*/\ze.','','')

    echo 'user:' s:user
    echo 'machine:' s:machine
    echo 'method:' s:method
    echo 'port:' s:port
    echo 'path:' s:path
    echo 'fname:' s:fname

    if s:machine =~ '@' "machine contains @"
        echo '==========='
        let dirpat    = '^\(.*\)@\(.\{-}\)$' "split by @"
        let s:user    = s:user.'@'.substitute(s:machine,dirpat,'\1','')  "makes user@<machine_part1>"
        let s:machine = substitute(s:machine,dirpat,'\2','') "makes user@<machine_part2>"

        echo 'user:' s:user
        echo 'machine:' s:machine
        echo 'method:' s:method
        echo 'port:' s:port
        echo 'path:' s:path
        echo 'fname:' s:fname
    endif
endfunction


echo '============='
echo '===OLD ONE==='
echo '============='
call s:RemotePathAnalysis('scp://user-01@localhost:2222//home/user-01/test.txt')
echo '============='
echo '===NEW ONE==='
echo '============='
call s:RemotePathAnalysisNew('scp://user-01@localhost:2222//home/user-01/test.txt')
echo '============='
echo '===IF CASE==='
echo '============='
call s:RemotePathAnalysis('scp://why@is_thre@if/test.txt')

output:

=============
===OLD ONE===
=============
user: 
machine: user-01@localhost
method: scp
port: 2222
path: /home/user-01/test.txt
fname: test.txt
==> machine contains @
user: @user-01
machine: localhost
method: scp
port: 2222
path: /home/user-01/test.txt
fname: test.txt
=============
===NEW ONE===
=============
user: user-01
machine: localhost
method: scp
port: 2222
path: /home/user-01/test.txt
fname: test.txt
=============
===IF CASE===
=============
user: why                                                                                                            
machine: is_thre@if                                                                                                   
method: scp                                                                                                          
port:                                                                                                                
path: test.txt                                                                                                       
fname: test.txt                                                                                                      
==> machine contains @                                                                                               
user: why@is_thre                                                                                                    
machine: if                                                                                                           
method: scp                                                                                                          
port:                                                                                                                
path: test.txt                                                                                                       
fname: test.txt 

You can view, comment on, or merge this pull request online at:

  https://github.com/vim/vim/pull/18611

Commit Summary

  • 8076bd8 netrw: tests for parsing remote bug
  • aeec020 netrw: fix remote user parsing
  • d165053 remove double '_'

File Changes

(3 files)

Patch Links:


Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/18611@github.com>

Václav Kobera

unread,
Oct 20, 2025, 3:47:32 PM (14 hours ago) Oct 20
to vim/vim, Push

@Swantosaurus pushed 1 commit.

  • 775da7f remove trailing whitespaces


View it on GitHub or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/18611/before/d1650531bb0383b9eef33c4a98bb92db332cf50b/after/775da7f1b9d58d87ce56f2093bf4b2bf1b0c96fb@github.com>

Reply all
Reply to author
Forward
0 new messages