# HG changeset patch # User Bram Moolenaar # Date 1609700403 -3600 # Node ID f8382c4e6551f227258dd29991ca4c6478076dcc # Parent 27c9e319653bbba04786dde45c31259c19d91102 patch 8.2.2289: Vim9: 'cpo' can become empty Commit: https://github.com/vim/vim/commit/e5a2dc87fd9d63dfd0d9c379e363ee8b8c05b14c Author: Bram Moolenaar Date: Sun Jan 3 19:52:05 2021 +0100 patch 8.2.2289: Vim9: 'cpo' can become empty Problem: Vim9: 'cpo' can become empty. Solution: Use empty_option instead of an empty string. Update quickfix buffer after restoring 'cpo'. (closes #7608) diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -1940,7 +1940,7 @@ pattern_match(char_u *pat, char_u *text, // avoid 'l' flag in 'cpoptions' save_cpo = p_cpo; - p_cpo = (char_u *)""; + p_cpo = empty_option; regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); if (regmatch.regprog != NULL) { @@ -6200,8 +6200,14 @@ do_string_sub( if (p_cpo == empty_option) p_cpo = save_cpo; else + { // Darn, evaluating {sub} expression or {expr} changed the value. + // If it's still empty it was changed and restored, need to restore in + // the complicated way. + if (*p_cpo == NUL) + set_option_value((char_u *)"cpo", 0L, save_cpo, 0); free_string_option(save_cpo); + } return ret; } diff --git a/src/evalbuffer.c b/src/evalbuffer.c --- a/src/evalbuffer.c +++ b/src/evalbuffer.c @@ -68,7 +68,7 @@ buflist_find_by_name(char_u *name, int c save_magic = p_magic; p_magic = TRUE; save_cpo = p_cpo; - p_cpo = (char_u *)""; + p_cpo = empty_option; buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name), TRUE, FALSE, curtab_only)); diff --git a/src/evalfunc.c b/src/evalfunc.c --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -6316,7 +6316,7 @@ find_some_match(typval_T *argvars, typva // Make 'cpoptions' empty, the 'l' flag should not be used here. save_cpo = p_cpo; - p_cpo = (char_u *)""; + p_cpo = empty_option; rettv->vval.v_number = -1; if (type == MATCH_LIST || type == MATCH_POS) @@ -8024,8 +8024,14 @@ theend: if (p_cpo == empty_option) p_cpo = save_cpo; else + { // Darn, evaluating the {skip} expression changed the value. + // If it's still empty it was changed and restored, need to restore in + // the complicated way. + if (*p_cpo == NUL) + set_option_value((char_u *)"cpo", 0L, save_cpo, 0); free_string_option(save_cpo); + } return retval; } @@ -8723,7 +8729,7 @@ f_split(typval_T *argvars, typval_T *ret // Make 'cpoptions' empty, the 'l' flag should not be used here. save_cpo = p_cpo; - p_cpo = (char_u *)""; + p_cpo = empty_option; str = tv_get_string(&argvars[0]); if (argvars[1].v_type != VAR_UNKNOWN) diff --git a/src/ex_eval.c b/src/ex_eval.c --- a/src/ex_eval.c +++ b/src/ex_eval.c @@ -1695,7 +1695,7 @@ ex_catch(exarg_T *eap) *end = NUL; } save_cpo = p_cpo; - p_cpo = (char_u *)""; + p_cpo = empty_option; // Disable error messages, it will make current_exception // invalid. ++emsg_off; diff --git a/src/gui_motif.c b/src/gui_motif.c --- a/src/gui_motif.c +++ b/src/gui_motif.c @@ -3525,7 +3525,7 @@ find_replace_callback( char_u *save_cpo = p_cpo; // No need to be Vi compatible here. - p_cpo = (char_u *)""; + p_cpo = empty_options; u_undo(1); p_cpo = save_cpo; gui_update_screen(); diff --git a/src/map.c b/src/map.c --- a/src/map.c +++ b/src/map.c @@ -2475,7 +2475,7 @@ add_map(char_u *map, int mode) char_u *s; char_u *cpo_save = p_cpo; - p_cpo = (char_u *)""; // Allow <> notation + p_cpo = empty_option; // Allow <> notation s = vim_strsave(map); if (s != NULL) { diff --git a/src/quickfix.c b/src/quickfix.c --- a/src/quickfix.c +++ b/src/quickfix.c @@ -8099,6 +8099,7 @@ ex_helpgrep(exarg_T *eap) int new_qi = FALSE; char_u *au_name = NULL; char_u *lang = NULL; + int updated = FALSE; switch (eap->cmdidx) { @@ -8150,14 +8151,24 @@ ex_helpgrep(exarg_T *eap) qfl->qf_ptr = qfl->qf_start; qfl->qf_index = 1; qf_list_changed(qfl); - qf_update_buffer(qi, NULL); + updated = TRUE; } if (p_cpo == empty_option) p_cpo = save_cpo; else - // Darn, some plugin changed the value. + { + // Darn, some plugin changed the value. If it's still empty it was + // changed and restored, need to restore in the complicated way. + if (*p_cpo == NUL) + set_option_value((char_u *)"cpo", 0L, save_cpo, 0); free_string_option(save_cpo); + } + + if (updated) + // This may open a window and source scripts, do this after 'cpo' was + // restored. + qf_update_buffer(qi, NULL); if (au_name != NULL) { diff --git a/src/syntax.c b/src/syntax.c --- a/src/syntax.c +++ b/src/syntax.c @@ -5670,7 +5670,7 @@ get_syn_pattern(char_u *arg, synpat_T *c // Make 'cpoptions' empty, to avoid the 'l' flag cpo_save = p_cpo; - p_cpo = (char_u *)""; + p_cpo = empty_option; ci->sp_prog = vim_regcomp(ci->sp_pattern, RE_MAGIC); p_cpo = cpo_save; @@ -5858,7 +5858,7 @@ syn_cmd_sync(exarg_T *eap, int syncing U // Make 'cpoptions' empty, to avoid the 'l' flag cpo_save = p_cpo; - p_cpo = (char_u *)""; + p_cpo = empty_option; curwin->w_s->b_syn_linecont_prog = vim_regcomp(curwin->w_s->b_syn_linecont_pat, RE_MAGIC); p_cpo = cpo_save; diff --git a/src/testdir/test_quickfix.vim b/src/testdir/test_quickfix.vim --- a/src/testdir/test_quickfix.vim +++ b/src/testdir/test_quickfix.vim @@ -702,6 +702,26 @@ func Test_helpgrep() call s:test_xhelpgrep('l') endfunc +def Test_helpgrep_vim9_restore_cpo() + assert_equal('aABceFs', &cpo) + + var rtp_save = &rtp + var dir = 'Xruntime/after' + &rtp ..= ',' .. dir + mkdir(dir .. '/ftplugin', 'p') + writefile(['vim9'], dir .. '/ftplugin/qf.vim') + filetype plugin on + silent helpgrep grail + cwindow + silent helpgrep grail + + assert_equal('aABceFs', &cpo) + delete(dir, 'rf') + &rtp = rtp_save + cclose + helpclose +enddef + func Test_errortitle() augroup QfBufWinEnter au! diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 2289, +/**/ 2288, /**/ 2287,