summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-12-26 12:07:30 +0000
committerBram Moolenaar <Bram@vim.org>2021-12-26 12:07:30 +0000
commit71eb3ad5790ef3d16369e2fceb040980d75539cf (patch)
treec24a97c4c6a2de224fcebafd5cc9a34b205e9748
parent8bb65f230d3025037f34021a72616038da0601ee (diff)
patch 8.2.3901: Vim9: Cannot set 'cpo' in main .vimrc if using Vim9 scriptv8.2.3901
Problem: Vim9: Cannot set 'cpo' in main .vimrc if using Vim9 script. Solution: Do not restore 'cpo' at the end of the main .vimrc.
-rw-r--r--runtime/doc/options.txt10
-rw-r--r--runtime/doc/vim9.txt1
-rw-r--r--src/scriptfile.c9
-rw-r--r--src/structs.h1
-rw-r--r--src/testdir/test_vim9_script.vim48
-rw-r--r--src/version.c2
6 files changed, 68 insertions, 3 deletions
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index f0939e61bb..e8773d9275 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -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
diff --git a/runtime/doc/vim9.txt b/runtime/doc/vim9.txt
index 6c142a4b12..ced0c7d930 100644
--- a/runtime/doc/vim9.txt
+++ b/runtime/doc/vim9.txt
@@ -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: >
diff --git a/src/scriptfile.c b/src/scriptfile.c
index 7ff9672f29..129d4d66de 100644
--- a/src/scriptfile.c
+++ b/src/scriptfile.c
@@ -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;
}
@@ -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)
{
@@ -1503,8 +1508,8 @@ almosttheend:
}
}
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
diff --git a/src/structs.h b/src/structs.h
index 41604537fe..4e770f1187 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -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
diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim
index 8975e1bf38..f79112ea9b 100644
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -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
diff --git a/src/version.c b/src/version.c
index 1ada85606a..9a5ef2cc99 100644
--- a/src/version.c
+++ b/src/version.c
@@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 3901,
+/**/
3900,
/**/
3899,