diff options
| -rw-r--r-- | src/nvim/eval.c | 74 | ||||
| -rw-r--r-- | src/nvim/version.c | 2 | ||||
| -rw-r--r-- | test/functional/legacy/autocmd_option_spec.lua | 43 | 
3 files changed, 86 insertions, 33 deletions
| diff --git a/src/nvim/eval.c b/src/nvim/eval.c index ec085efc07..837e19ab98 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -10698,11 +10698,11 @@ getwinvar (      int off                    /* 1 for gettabwinvar() */  )  { -  win_T       *win, *oldcurwin; -  char_u      *varname; -  dictitem_T  *v; -  tabpage_T   *tp = NULL; -  tabpage_T   *oldtabpage = NULL; +  win_T *win, *oldcurwin; +  char_u *varname; +  dictitem_T *v; +  tabpage_T *tp = NULL; +  tabpage_T *oldtabpage = NULL;    bool done = false;    if (off == 1) @@ -10717,12 +10717,16 @@ getwinvar (    rettv->vval.v_string = NULL;    if (win != NULL && varname != NULL) { -    /* Set curwin to be our win, temporarily.  Also set the tabpage, -     * otherwise the window is not valid. */ -    if (switch_win(&oldcurwin, &oldtabpage, win, tp, TRUE) == OK) { -      if (*varname == '&') {      /* window-local-option */ -        if (get_option_tv(&varname, rettv, 1) == OK) +    // Set curwin to be our win, temporarily.  Also set the tabpage, +    // otherwise the window is not valid. Only do this when needed, +    // autocommands get blocked. +    bool need_switch_win = tp != curtab || win != curwin; +    if (!need_switch_win +        || switch_win(&oldcurwin, &oldtabpage, win, tp, true) == OK) { +      if (*varname == '&') {  // window-local-option +        if (get_option_tv(&varname, rettv, 1) == OK) {            done = true; +        }        } else {          // Look up the variable.          // Let getwinvar({nr}, "") return the "w:" dictionary. @@ -10734,8 +10738,10 @@ getwinvar (        }      } -    /* restore previous notion of curwin */ -    restore_win(oldcurwin, oldtabpage, TRUE); +    if (need_switch_win) { +      // restore previous notion of curwin +      restore_win(oldcurwin, oldtabpage, true); +    }    }    if (!done && argvars[off + 2].v_type != VAR_UNKNOWN) @@ -15560,26 +15566,32 @@ static void setwinvar(typval_T *argvars, typval_T *rettv, int off)    varname = get_tv_string_chk(&argvars[off + 1]);    varp = &argvars[off + 2]; -  if (win != NULL && varname != NULL && varp != NULL -      && switch_win(&save_curwin, &save_curtab, win, tp, TRUE) == OK) { -    if (*varname == '&') { -      long numval; -      char_u      *strval; -      int error = FALSE; - -      ++varname; -      numval = get_tv_number_chk(varp, &error); -      strval = get_tv_string_buf_chk(varp, nbuf); -      if (!error && strval != NULL) -        set_option_value(varname, numval, strval, OPT_LOCAL); -    } else { -      winvarname = xmalloc(STRLEN(varname) + 3); -      STRCPY(winvarname, "w:"); -      STRCPY(winvarname + 2, varname); -      set_var(winvarname, varp, TRUE); -      xfree(winvarname); +  if (win != NULL && varname != NULL && varp != NULL) { +    bool need_switch_win = tp != curtab || win != curwin; +    if (!need_switch_win +        || switch_win(&save_curwin, &save_curtab, win, tp, true) == OK) { +      if (*varname == '&') { +        long numval; +        char_u *strval; +        int error = false; + +        ++varname; +        numval = get_tv_number_chk(varp, &error); +        strval = get_tv_string_buf_chk(varp, nbuf); +        if (!error && strval != NULL) { +          set_option_value(varname, numval, strval, OPT_LOCAL); +        } +      } else { +        winvarname = xmalloc(STRLEN(varname) + 3); +        STRCPY(winvarname, "w:"); +        STRCPY(winvarname + 2, varname); +        set_var(winvarname, varp, true); +        xfree(winvarname); +      } +    } +    if (need_switch_win) { +      restore_win(save_curwin, save_curtab, true);      } -    restore_win(save_curwin, save_curtab, TRUE);    }  } diff --git a/src/nvim/version.c b/src/nvim/version.c index 39b8e3db84..940107ee66 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -400,7 +400,7 @@ static int included_patches[] = {    // 891,    // 890 NA    // 889, -  // 888, +  888,    887,    // 886 NA    885, diff --git a/test/functional/legacy/autocmd_option_spec.lua b/test/functional/legacy/autocmd_option_spec.lua index 855e9c6271..6349371808 100644 --- a/test/functional/legacy/autocmd_option_spec.lua +++ b/test/functional/legacy/autocmd_option_spec.lua @@ -2,6 +2,8 @@ local helpers = require('test.functional.helpers')  local nvim = helpers.meths  local clear, eq, neq = helpers.clear, helpers.eq, helpers.neq  local curbuf, buf = helpers.curbuf, helpers.bufmeths +local curwin = helpers.curwin +local redir_exec = helpers.redir_exec  local source, execute = helpers.source, helpers.execute  local function declare_hook_function() @@ -86,7 +88,7 @@ end  local function make_buffer()    local old_buf = curbuf() -  execute('new') +  execute('botright new')    local new_buf = curbuf()    execute('wincmd p') -- move previous window @@ -96,6 +98,19 @@ local function make_buffer()    return new_buf  end +local function get_new_window_number() +  local old_win = curwin() +  execute('botright new') +  local new_win = curwin() +  local new_winnr = redir_exec('echo winnr()') +  execute('wincmd p') -- move previous window + +  neq(old_win, new_win) +  eq(old_win, curwin()) + +  return new_winnr:gsub('\n', '') +end +  describe('au OptionSet', function()    describe('with any opton (*)', function() @@ -248,6 +263,32 @@ describe('au OptionSet', function()        end)      end) +    describe('being set by setwinvar()', function() +      it('should not trigger because option name does not match with backup', function() +        set_hook('backup') + +        execute('call setwinvar(1, "&l:bk", 1)') +        expected_empty() +      end) + +      it('should trigger, use correct option name backup', function() +        set_hook('backup') + +        execute('call setwinvar(1, "&backup", 1)') +        expected_combination({'backup', 0, 1, 'local'}) +      end) + +      it('should not trigger if the current window is different from the targetted window', function() +        set_hook('cursorcolumn') + +        local new_winnr = get_new_window_number() + +        execute('call setwinvar(' .. new_winnr .. ', "&cursorcolumn", 1)') +        -- expected_combination({'cursorcolumn', 0, 1, 'local', {winnr = new_winnr}}) +        expected_empty() +      end) +    end) +      describe('being set by neovim api', function()        it('should trigger if a boolean option be set globally', function()          set_hook('autochdir') | 
