Skip to content

Commit

Permalink
patch 8.2.3901: Vim9: Cannot set 'cpo' in main .vimrc if using Vim9 s…
Browse files Browse the repository at this point in the history
…cript

Problem:    Vim9: Cannot set 'cpo' in main .vimrc if using Vim9 script.
Solution:   Do not restore 'cpo' at the end of the main .vimrc.
  • Loading branch information
brammool committed Dec 26, 2021
1 parent 8bb65f2 commit 71eb3ad
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 3 deletions.
10 changes: 10 additions & 0 deletions runtime/doc/options.txt
Expand Up @@ -2133,8 +2133,18 @@ A jump table for the options with a short description can be found at |Q_op|.
Commas can be added for readability.
To avoid problems with flags that are added in the future, use the
"+=" and "-=" feature of ":set" |add-option-flags|.

NOTE: This option is set to the Vi default value when 'compatible' is
set and to the Vim default value when 'compatible' is reset.

NOTE: In a |Vim9| script, when `vim9script` is encountered, the value
is saved, 'cpoptions' is set to the Vim default, and the saved value
is restored at the end of the script. Changes to the value of
'cpoptions' will be applied to the saved value, but keep in mind that
removing a flag that is not present when 'cpoptions' is changed has no
effect. In the |.vimrc| file the value is not restored, thus using
`vim9script` in the |.vimrc| file results in using the Vim default.

NOTE: This option is set to the POSIX default value at startup when
the Vi default value would be used and the $VIM_POSIX environment
variable exists |posix|. This means Vim tries to behave like the
Expand Down
1 change: 1 addition & 0 deletions runtime/doc/vim9.txt
Expand Up @@ -1402,6 +1402,7 @@ One of the effects is that |line-continuation| is always enabled.
The original value of 'cpoptions' is restored at the end of the script, while
flags added or removed in the script are also added to or removed from the
original value to get the same effect. The order of flags may change.
In the |vimrc| file sourced on startup this does not happen.

*vim9-mix*
There is one way to use both legacy and Vim9 syntax in one script file: >
Expand Down
9 changes: 7 additions & 2 deletions src/scriptfile.c
Expand Up @@ -1372,6 +1372,9 @@ do_source(
if (ret_sid != NULL)
*ret_sid = current_sctx.sc_sid;

// Remember the "is_vimrc" flag for when the file is sourced again.
si->sn_is_vimrc = is_vimrc;

// Used to check script variable index is still valid.
si->sn_script_seq = current_sctx.sc_seq;
}
Expand Down Expand Up @@ -1471,9 +1474,11 @@ do_source(

#ifdef FEAT_EVAL
almosttheend:
// If "sn_save_cpo" is set that means we encountered "vim9script": restore
// 'cpoptions', unless in the main .vimrc file.
// Get "si" again, "script_items" may have been reallocated.
si = SCRIPT_ITEM(current_sctx.sc_sid);
if (si->sn_save_cpo != NULL)
if (si->sn_save_cpo != NULL && si->sn_is_vimrc == DOSO_NONE)
{
if (STRCMP(p_cpo, CPO_VIM) != 0)
{
Expand Down Expand Up @@ -1503,8 +1508,8 @@ do_source(
}
}
set_option_value((char_u *)"cpo", 0L, si->sn_save_cpo, OPT_NO_REDRAW);
VIM_CLEAR(si->sn_save_cpo);
}
VIM_CLEAR(si->sn_save_cpo);

restore_funccal();
# ifdef FEAT_PROFILE
Expand Down
1 change: 1 addition & 0 deletions src/structs.h
Expand Up @@ -1866,6 +1866,7 @@ typedef struct
int sn_version; // :scriptversion
int sn_state; // SN_STATE_ values
char_u *sn_save_cpo; // 'cpo' value when :vim9script found
char sn_is_vimrc; // .vimrc file, do not restore 'cpo'

# ifdef FEAT_PROFILE
int sn_prof_on; // TRUE when script is/was profiled
Expand Down
48 changes: 47 additions & 1 deletion src/testdir/test_vim9_script.vim
Expand Up @@ -4270,18 +4270,64 @@ def Test_restoring_cpo()
delete('Xclose')
delete('Xdone')

writefile(['vim9script'], 'XanotherScript')
writefile(['vim9script', 'g:cpoval = &cpo'], 'XanotherScript')
set cpo=aABceFsMny>
edit XanotherScript
so %
assert_equal('aABceFsMny>', &cpo)
assert_equal('aABceFs', g:cpoval)
:1del
setline(1, 'let g:cpoval = &cpo')
w
so %
assert_equal('aABceFsMny>', &cpo)
assert_equal('aABceFsMny>', g:cpoval)

delete('XanotherScript')
set cpo&vim
unlet g:cpoval

if has('unix')
# 'cpo' is not restored in main vimrc
var save_HOME = $HOME
$HOME = getcwd() .. '/Xhome'
mkdir('Xhome')
var lines =<< trim END
vim9script
writefile(['before: ' .. &cpo], 'Xresult')
set cpo+=M
writefile(['after: ' .. &cpo], 'Xresult', 'a')
END
writefile(lines, 'Xhome/.vimrc')

lines =<< trim END
call writefile(['later: ' .. &cpo], 'Xresult', 'a')
END
writefile(lines, 'Xlegacy')

lines =<< trim END
vim9script
call writefile(['vim9: ' .. &cpo], 'Xresult', 'a')
qa
END
writefile(lines, 'Xvim9')

var cmd = GetVimCommand() .. " -S Xlegacy -S Xvim9"
cmd = substitute(cmd, '-u NONE', '', '')
exe "silent !" .. cmd

assert_equal([
'before: aABceFs',
'after: aABceFsM',
'later: aABceFsM',
'vim9: aABceFs'], readfile('Xresult'))

$HOME = save_HOME
delete('Xhome', 'rf')
delete('Xlegacy')
delete('Xvim9')
delete('Xresult')
endif
enddef

" Use :function so we can use Check commands
Expand Down
2 changes: 2 additions & 0 deletions src/version.c
Expand Up @@ -749,6 +749,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
3901,
/**/
3900,
/**/
Expand Down

0 comments on commit 71eb3ad

Please sign in to comment.