# HG changeset patch # User Bram Moolenaar # Date 1559223005 -7200 # Node ID 28303712656029a891d5cab8bfd4d5f1f3585a92 # Parent a3555dcb63cd45651fdb3141151d4f4492fa7b52 patch 8.1.1423: popup windows use options from current window and buffer commit https://github.com/vim/vim/commit/cacc6a5c986fbc716bf53b6916f076dd7b388142 Author: Bram Moolenaar Date: Thu May 30 15:22:43 2019 +0200 patch 8.1.1423: popup windows use options from current window and buffer Problem: Popup windows use options from current window and buffer. Solution: Clear all local options when creating a popup window. diff --git a/src/option.c b/src/option.c --- a/src/option.c +++ b/src/option.c @@ -3269,7 +3269,7 @@ static void check_redraw(long_u flags); static int findoption(char_u *); static int find_key_option(char_u *arg_arg, int has_lt); static void showoptions(int all, int opt_flags); -static int optval_default(struct vimoption *, char_u *varp); +static int optval_default(struct vimoption *, char_u *varp, int compatible); static void showoneopt(struct vimoption *, int opt_flags); static int put_setstring(FILE *fd, char *cmd, char *name, char_u **valuep, long_u flags); static int put_setnum(FILE *fd, char *cmd, char *name, long *valuep); @@ -3893,6 +3893,36 @@ set_number_default(char *name, long val) options[opt_idx].def_val[VI_DEFAULT] = (char_u *)(long_i)val; } +/* + * Set all window-local and buffer-local options to the Vim default. + * local-global options will use the global value. + */ + void +set_local_options_default(win_T *wp) +{ + win_T *save_curwin = curwin; + int i; + + curwin = wp; + curbuf = curwin->w_buffer; + block_autocmds(); + + for (i = 0; !istermoption(&options[i]); i++) + { + struct vimoption *p = &(options[i]); + char_u *varp = get_varp_scope(p, OPT_LOCAL); + + if (p->indir != PV_NONE + && !(options[i].flags & P_NODEFAULT) + && !optval_default(p, varp, FALSE)) + set_option_default(i, OPT_LOCAL, FALSE); + } + + unblock_autocmds(); + curwin = save_curwin; + curbuf = curwin->w_buffer; +} + #if defined(EXITFREE) || defined(PROTO) /* * Free all options. @@ -10149,7 +10179,7 @@ showoptions( if (varp != NULL && ((all == 2 && isterm) || (all == 1 && !isterm) - || (all == 0 && !optval_default(p, varp)))) + || (all == 0 && !optval_default(p, varp, p_cp)))) { if (p->flags & P_BOOL) len = 1; /* a toggle option fits always */ @@ -10199,13 +10229,13 @@ showoptions( * Return TRUE if option "p" has its default value. */ static int -optval_default(struct vimoption *p, char_u *varp) +optval_default(struct vimoption *p, char_u *varp, int compatible) { int dvi; if (varp == NULL) return TRUE; /* hidden option is always at default */ - dvi = ((p->flags & P_VI_DEF) || p_cp) ? VI_DEFAULT : VIM_DEFAULT; + dvi = ((p->flags & P_VI_DEF) || compatible) ? VI_DEFAULT : VIM_DEFAULT; if (p->flags & P_NUM) return (*(long *)varp == (long)(long_i)p->def_val[dvi]); if (p->flags & P_BOOL) @@ -10311,7 +10341,7 @@ makeset(FILE *fd, int opt_flags, int loc /* Global values are only written when not at the default value. */ varp = get_varp_scope(p, opt_flags); - if ((opt_flags & OPT_GLOBAL) && optval_default(p, varp)) + if ((opt_flags & OPT_GLOBAL) && optval_default(p, varp, p_cp)) continue; round = 2; @@ -10327,7 +10357,7 @@ makeset(FILE *fd, int opt_flags, int loc if (!(opt_flags & OPT_GLOBAL) && !local_only) { varp_fresh = get_varp_scope(p, OPT_GLOBAL); - if (!optval_default(p, varp_fresh)) + if (!optval_default(p, varp_fresh, p_cp)) { round = 1; varp_local = varp; diff --git a/src/popupwin.c b/src/popupwin.c --- a/src/popupwin.c +++ b/src/popupwin.c @@ -253,6 +253,10 @@ f_popup_create(typval_T *argvars, typval if (buf == NULL) return; ml_open(buf); + + win_init_popup_win(wp, buf); + + set_local_options_default(wp); set_string_option_direct_in_buf(buf, (char_u *)"buftype", -1, (char_u *)"popup", OPT_FREE|OPT_LOCAL, 0); set_string_option_direct_in_buf(buf, (char_u *)"bufhidden", -1, @@ -262,8 +266,6 @@ f_popup_create(typval_T *argvars, typval buf->b_p_bl = FALSE; // unlisted buffer buf->b_locked = TRUE; - win_init_popup_win(wp, buf); - nr = (int)dict_get_number(d, (char_u *)"tab"); if (nr == 0) { diff --git a/src/proto/option.pro b/src/proto/option.pro --- a/src/proto/option.pro +++ b/src/proto/option.pro @@ -2,6 +2,7 @@ void set_init_1(int clean_arg); void set_string_default(char *name, char_u *val); void set_number_default(char *name, long val); +void set_local_options_default(win_T *wp); void free_all_options(void); void set_init_2(void); void set_init_3(void); diff --git a/src/testdir/test_popupwin.vim b/src/testdir/test_popupwin.vim --- a/src/testdir/test_popupwin.vim +++ b/src/testdir/test_popupwin.vim @@ -264,3 +264,26 @@ func Test_popup_getoptions() call popup_close(winid) call assert_equal({}, popup_getoptions(winid)) endfunc + +func Test_popup_option_values() + new + " window-local + setlocal number + setlocal nowrap + " buffer-local + setlocal omnifunc=Something + " global/buffer-local + setlocal path=/there + " global/window-local + setlocal scrolloff=9 + + let winid = popup_create('hello', {}) + call assert_equal(0, getwinvar(winid, '&number')) + call assert_equal(1, getwinvar(winid, '&wrap')) + call assert_equal('', getwinvar(winid, '&omnifunc')) + call assert_equal(&g:path, getwinvar(winid, '&path')) + call assert_equal(&g:scrolloff, getwinvar(winid, '&scrolloff')) + + call popup_close(winid) + bwipe +endfunc diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -768,6 +768,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1423, +/**/ 1422, /**/ 1421,