1
0
forked from aniani/vim

patch 9.1.0359: MS-Windows: relative import in a script sourced from a buffer doesn't work

Problem:  MS-Windows: Relative import in a script sourced from a buffer
          doesn't work (Ernie Rael)
Solution: Set a filename, so that we are not trying to use
          script-relative filename (Yegappan Lakshmanan)

When a script is sourced from a buffer, the file name is set to ":source
buffer=". In MS-Windows, the ":" is a path separator character (used
after a drive letter). This results in the code trying to use the ":"
prefix to import the script on MS-Windows. To fix this, when importing a
script from a script sourced from a buffer with nofile, don't use
a script relative path name.

fixes #14588
closes: #14603

Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Yegappan Lakshmanan 2024-04-20 18:31:21 +02:00 committed by Christian Brabandt
parent 8927c9b720
commit f135fa28e4
No known key found for this signature in database
GPG Key ID: F3F92DA383FDDE09
4 changed files with 62 additions and 16 deletions

View File

@ -1430,8 +1430,13 @@ do_source_buffer_init(source_cookie_T *sp, exarg_T *eap)
return NULL;
// Use ":source buffer=<num>" as the script name
vim_snprintf((char *)IObuff, IOSIZE, ":source buffer=%d", curbuf->b_fnum);
fname = vim_strsave(IObuff);
if (curbuf->b_ffname != NULL)
fname = vim_strsave(curbuf->b_ffname);
else
{
vim_snprintf((char *)IObuff, IOSIZE, ":source buffer=%d", curbuf->b_fnum);
fname = vim_strsave(IObuff);
}
if (fname == NULL)
return NULL;

View File

@ -1140,13 +1140,9 @@ def Test_autoload_import_relative()
v9.CheckScriptFailure(lines, 'E484:')
enddef
" autoload relative, access from compiled function.
" Github issues: #14565, #14579
def Test_autoload_import_relative_compiled_buffer()
if !has('unix')
# temporary, until it's discovered why the test fails on Windows.
CheckUnix
return
endif
# autoload relative, access from compiled function. #14565, #14579
var lines =<< trim END
vim9script
@ -1168,6 +1164,40 @@ def Test_autoload_import_relative_compiled_buffer()
new
setline(1, lines)
:source
# source one more time to detect issues with clearing the script state and
# variables
:source
:bw!
enddef
" Test for relative import when sourcing a buffer in another directory
def Test_autoload_import_relative_from_buffer_in_dir()
mkdir('Ximportrelative/dir1/dir2', 'pR')
var lines =<< trim END
vim9script
export def F1(): string
return 'InFile.vim'
enddef
END
writefile(lines, 'Ximportrelative/dir1/dir2/Ximport.vim')
lines =<< trim END
vim9script
import autoload './Ximport.vim' as xfile
def F(): string
return xfile.F1()
enddef
assert_equal('InFile.vim', F())
END
writefile(lines, 'Ximportrelative/dir1/dir2/Xrelative.vim')
split Ximportrelative/dir1/dir2/Xrelative.vim
:source
# source one more time to detect issues with clearing the script state and
# variables
:source
:bw!
enddef

View File

@ -704,6 +704,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
359,
/**/
358,
/**/

View File

@ -456,15 +456,24 @@ handle_import(
scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
char_u *tail = gettail(si->sn_name);
char_u *from_name;
int sourced_from_nofile_buf = FALSE;
// Relative to current script: "./name.vim", "../../name.vim".
len = STRLEN(si->sn_name) - STRLEN(tail) + STRLEN(tv.vval.v_string) + 2;
from_name = alloc((int)len);
if (from_name == NULL)
goto erret;
vim_strncpy(from_name, si->sn_name, tail - si->sn_name);
add_pathsep(from_name);
STRCAT(from_name, tv.vval.v_string);
if (STRNCMP(si->sn_name, ":source buffer=", 15) == 0)
sourced_from_nofile_buf = TRUE;
if (!sourced_from_nofile_buf)
{
// Relative to current script: "./name.vim", "../../name.vim".
len = STRLEN(si->sn_name) - STRLEN(tail) + STRLEN(tv.vval.v_string) + 2;
from_name = alloc((int)len);
if (from_name == NULL)
goto erret;
vim_strncpy(from_name, si->sn_name, tail - si->sn_name);
add_pathsep(from_name);
STRCAT(from_name, tv.vval.v_string);
}
else
from_name = vim_strsave(tv.vval.v_string);
simplify_filename(from_name);
res = handle_import_fname(from_name, is_autoload, &sid);