To: vim_dev@googlegroups.com Subject: Patch 8.0.0736 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.0736 Problem: The OptionSet autocommand event is not triggered when entering diff mode. Solution: use set_option_value() instead of setting the option directly. Change the tests from old to new style. (Christian Brabandt) Files: src/diff.c, src/testdir/Make_all.mak, src/Makefile, src/testdir/test_autocmd.vim, src/testdir/test_autocmd_option.in, src/testdir/test_autocmd_option.ok, *** ../vim-8.0.0735/src/diff.c 2017-05-16 13:14:58.434591726 +0200 --- src/diff.c 2017-07-19 17:22:29.684100737 +0200 *************** *** 1137,1142 **** --- 1137,1156 ---- diff_win_options(curwin, TRUE); } + static void + set_diff_option(win_T *wp, int value) + { + win_T *old_curwin = curwin; + + curwin = wp; + curbuf = curwin->w_buffer; + ++curbuf_lock; + set_option_value((char_u *)"diff", (long)value, NULL, OPT_LOCAL); + --curbuf_lock; + curwin = old_curwin; + curbuf = curwin->w_buffer; + } + /* * Set options in window "wp" for diff mode. */ *************** *** 1198,1207 **** if (vim_strchr(p_sbo, 'h') == NULL) do_cmdline_cmd((char_u *)"set sbo+=hor"); #endif ! /* Saved the current values, to be restored in ex_diffoff(). */ wp->w_p_diff_saved = TRUE; ! wp->w_p_diff = TRUE; if (addbuf) diff_buf_add(wp->w_buffer); --- 1212,1221 ---- if (vim_strchr(p_sbo, 'h') == NULL) do_cmdline_cmd((char_u *)"set sbo+=hor"); #endif ! /* Save the current values, to be restored in ex_diffoff(). */ wp->w_p_diff_saved = TRUE; ! set_diff_option(wp, TRUE); if (addbuf) diff_buf_add(wp->w_buffer); *************** *** 1227,1233 **** /* Set 'diff' off. If option values were saved in * diff_win_options(), restore the ones whose settings seem to have * been left over from diff mode. */ ! wp->w_p_diff = FALSE; if (wp->w_p_diff_saved) { --- 1241,1247 ---- /* Set 'diff' off. If option values were saved in * diff_win_options(), restore the ones whose settings seem to have * been left over from diff mode. */ ! set_diff_option(wp, FALSE); if (wp->w_p_diff_saved) { *** ../vim-8.0.0735/src/testdir/Make_all.mak 2017-07-16 17:55:53.325531419 +0200 --- src/testdir/Make_all.mak 2017-07-19 17:13:31.779932605 +0200 *************** *** 66,72 **** test104.out \ test107.out \ test108.out \ - test_autocmd_option.out \ test_autoformat_join.out \ test_changelist.out \ test_close_count.out \ --- 66,71 ---- *** ../vim-8.0.0735/src/Makefile 2017-07-16 17:55:53.325531419 +0200 --- src/Makefile 2017-07-19 18:16:20.829038852 +0200 *************** *** 2088,2094 **** # Run individual OLD style test, assuming that Vim was already compiled. test1 \ - test_autocmd_option \ test_autoformat_join \ test_changelist \ test_close_count \ --- 2088,2093 ---- *** ../vim-8.0.0735/src/testdir/test_autocmd.vim 2017-07-09 11:07:11.716971364 +0200 --- src/testdir/test_autocmd.vim 2017-07-19 17:19:46.653266060 +0200 *************** *** 2,14 **** set belloff=all ! function! s:cleanup_buffers() abort for bnr in range(1, bufnr('$')) if bufloaded(bnr) && bufnr('%') != bnr execute 'bd! ' . bnr endif endfor ! endfunction func Test_vim_did_enter() call assert_false(v:vim_did_enter) --- 2,14 ---- set belloff=all ! func! s:cleanup_buffers() abort for bnr in range(1, bufnr('$')) if bufloaded(bnr) && bufnr('%') != bnr execute 'bd! ' . bnr endif endfor ! endfunc func Test_vim_did_enter() call assert_false(v:vim_did_enter) *************** *** 49,55 **** endfunc endif ! function Test_bufunload() augroup test_bufunload_group autocmd! autocmd BufUnload * call add(s:li, "bufunload") --- 49,55 ---- endfunc endif ! func Test_bufunload() augroup test_bufunload_group autocmd! autocmd BufUnload * call add(s:li, "bufunload") *************** *** 80,86 **** endfunc " SEGV occurs in older versions. (At least 7.4.2005 or older) ! function Test_autocmd_bufunload_with_tabnext() tabedit tabfirst --- 80,86 ---- endfunc " SEGV occurs in older versions. (At least 7.4.2005 or older) ! func Test_autocmd_bufunload_with_tabnext() tabedit tabfirst *************** *** 98,104 **** quit endfunc ! function Test_autocmd_bufwinleave_with_tabfirst() tabedit augroup sample autocmd! --- 98,104 ---- quit endfunc ! func Test_autocmd_bufwinleave_with_tabfirst() tabedit augroup sample autocmd! *************** *** 110,116 **** endfunc " SEGV occurs in older versions. (At least 7.4.2321 or older) ! function Test_autocmd_bufunload_avoiding_SEGV_01() split aa.txt let lastbuf = bufnr('$') --- 110,116 ---- endfunc " SEGV occurs in older versions. (At least 7.4.2321 or older) ! func Test_autocmd_bufunload_avoiding_SEGV_01() split aa.txt let lastbuf = bufnr('$') *************** *** 128,134 **** endfunc " SEGV occurs in older versions. (At least 7.4.2321 or older) ! function Test_autocmd_bufunload_avoiding_SEGV_02() setlocal buftype=nowrite let lastbuf = bufnr('$') --- 128,134 ---- endfunc " SEGV occurs in older versions. (At least 7.4.2321 or older) ! func Test_autocmd_bufunload_avoiding_SEGV_02() setlocal buftype=nowrite let lastbuf = bufnr('$') *************** *** 351,357 **** " Closing a window might cause an endless loop " E814 for older Vims ! function Test_autocmd_bufwipe_in_SessLoadPost() tabnew set noswapfile mksession! --- 351,357 ---- " Closing a window might cause an endless loop " E814 for older Vims ! func Test_autocmd_bufwipe_in_SessLoadPost() tabnew set noswapfile mksession! *************** *** 380,386 **** endfunc " SEGV occurs in older versions. ! function Test_autocmd_bufwipe_in_SessLoadPost2() tabnew set noswapfile mksession! --- 380,386 ---- endfunc " SEGV occurs in older versions. ! func Test_autocmd_bufwipe_in_SessLoadPost2() tabnew set noswapfile mksession! *************** *** 422,424 **** --- 422,615 ---- func Test_empty_doau() doau \| endfunc + + func s:AutoCommandOptionSet(match) + let item = remove(g:options, 0) + let expected = printf("Option: <%s>, Oldval: <%s>, NewVal: <%s>, Scope: <%s>\n", item[0], item[1], item[2], item[3]) + let actual = printf("Option: <%s>, Oldval: <%s>, NewVal: <%s>, Scope: <%s>\n", a:match, v:option_old, v:option_new, v:option_type) + let g:opt = [expected, actual] + "call assert_equal(expected, actual) + endfunc + + func Test_OptionSet() + if !has("eval") || !has("autocmd") || !exists("+autochdir") + return + endif + + call test_override('starting', 1) + set nocp + au OptionSet * :call s:AutoCommandOptionSet(expand("")) + + " 1: Setting number option" + let g:options=[['number', 0, 1, 'global']] + set nu + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 2: Setting local number option" + let g:options=[['number', 1, 0, 'local']] + setlocal nonu + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 3: Setting global number option" + let g:options=[['number', 1, 0, 'global']] + setglobal nonu + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 4: Setting local autoindent option" + let g:options=[['autoindent', 0, 1, 'local']] + setlocal ai + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 5: Setting global autoindent option" + let g:options=[['autoindent', 0, 1, 'global']] + setglobal ai + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 6: Setting global autoindent option" + let g:options=[['autoindent', 1, 0, 'global']] + set ai! + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " Should not print anything, use :noa + " 7: don't trigger OptionSet" + let g:options=[['invalid', 1, 1, 'invalid']] + noa set nonu + call assert_equal([['invalid', 1, 1, 'invalid']], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 8: Setting several global list and number option" + let g:options=[['list', 0, 1, 'global'], ['number', 0, 1, 'global']] + set list nu + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 9: don't trigger OptionSet" + let g:options=[['invalid', 1, 1, 'invalid'], ['invalid', 1, 1, 'invalid']] + noa set nolist nonu + call assert_equal([['invalid', 1, 1, 'invalid'], ['invalid', 1, 1, 'invalid']], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 10: Setting global acd" + let g:options=[['autochdir', 0, 1, 'local']] + setlocal acd + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 11: Setting global autoread (also sets local value)" + let g:options=[['autoread', 0, 1, 'global']] + set ar + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 12: Setting local autoread" + let g:options=[['autoread', 1, 1, 'local']] + setlocal ar + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 13: Setting global autoread" + let g:options=[['autoread', 1, 0, 'global']] + setglobal invar + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 14: Setting option backspace through :let" + let g:options=[['backspace', '', 'eol,indent,start', 'global']] + let &bs="eol,indent,start" + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 15: Setting option backspace through setbufvar()" + let g:options=[['backup', 0, 1, 'local']] + " try twice, first time, shouldn't trigger because option name is invalid, + " second time, it should trigger + call assert_fails("call setbufvar(1, '&l:bk', 1)", "E355") + " should trigger, use correct option name + call setbufvar(1, '&backup', 1) + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 16: Setting number option using setwinvar" + let g:options=[['number', 0, 1, 'local']] + call setwinvar(0, '&number', 1) + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 17: Setting key option, shouldn't trigger" + let g:options=[['key', 'invalid', 'invalid1', 'invalid']] + setlocal key=blah + setlocal key= + call assert_equal([['key', 'invalid', 'invalid1', 'invalid']], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " Cleanup + au! OptionSet + for opt in ['nu', 'ai', 'acd', 'ar', 'bs', 'backup', 'cul', 'cp'] + exe printf(":set %s&vi", opt) + endfor + call test_override('starting', 0) + delfunc! AutoCommandOptionSet + endfunc + + func Test_OptionSet_diffmode() + call test_override('starting', 1) + " 18: Changing an option when enetering diff mode + new + au OptionSet diff :let &l:cul=v:option_new + + call setline(1, ['buffer 1', 'line2', 'line3', 'line4']) + call assert_equal(0, &l:cul) + diffthis + call assert_equal(1, &l:cul) + + vnew + call setline(1, ['buffer 2', 'line 2', 'line 3', 'line4']) + call assert_equal(0, &l:cul) + diffthis + call assert_equal(1, &l:cul) + + diffoff + call assert_equal(0, &l:cul) + call assert_equal(1, getwinvar(2, '&l:cul')) + bw! + + call assert_equal(1, &l:cul) + diffoff! + call assert_equal(0, &l:cul) + call assert_equal(0, getwinvar(1, '&l:cul')) + bw! + + " Cleanup + au! OptionSet + call test_override('starting', 0) + endfunc + + func Test_OptionSet_diffmode_close() + call test_override('starting', 1) + " 19: Try to close the current window when entering diff mode + " should not segfault + new + au OptionSet diff close + + call setline(1, ['buffer 1', 'line2', 'line3', 'line4']) + call assert_fails(':diffthis', 'E788') + call assert_equal(1, &diff) + vnew + call setline(1, ['buffer 2', 'line 2', 'line 3', 'line4']) + call assert_fails(':diffthis', 'E788') + call assert_equal(1, &diff) + bw! + call assert_fails(':diffoff!', 'E788') + bw! + + " Cleanup + au! OptionSet + call test_override('starting', 0) + "delfunc! AutoCommandOptionSet + endfunc *** ../vim-8.0.0735/src/testdir/test_autocmd_option.in 2015-09-29 18:03:38.000000000 +0200 --- src/testdir/test_autocmd_option.in 1970-01-01 01:00:00.000000000 +0100 *************** *** 1,77 **** - Test for option autocommand - - STARTTEST - :so small.vim - :if !has("eval") || !has("autocmd") || !exists("+autochdir") | e! test.ok | w! test.out | qa! | endif - :fu! AutoCommand(match) - : let c=g:testcase - : let item=remove(g:options, 0) - : let c.=printf("Expected: Name: <%s>, Oldval: <%s>, NewVal: <%s>, Scope: <%s>\n", item[0], item[1], item[2], item[3]) - : let c.=printf("Autocmd Option: <%s>,", a:match) - : let c.=printf(" OldVal: <%s>,", v:option_old) - : let c.=printf(" NewVal: <%s>,", v:option_new) - : let c.=printf(" Scope: <%s>\n", v:option_type) - : call setreg('r', printf("%s\n%s", getreg('r'), c)) - :endfu - :au OptionSet * :call AutoCommand(expand("")) - :let g:testcase="1: Setting number option\n" - :let g:options=[['number', 0, 1, 'global']] - :set nu - :let g:testcase="2: Setting local number option\n" - :let g:options=[['number', 1, 0, 'local']] - :setlocal nonu - :let g:testcase="3: Setting global number option\n" - :let g:options=[['number', 1, 0, 'global']] - :setglobal nonu - :let g:testcase="4: Setting local autoindent option\n" - :let g:options=[['autoindent', 0, 1, 'local']] - :setlocal ai - :let g:testcase="5: Setting global autoindent option\n" - :let g:options=[['autoindent', 0, 1, 'global']] - :setglobal ai - :let g:testcase="6: Setting global autoindent option\n" - :let g:options=[['autoindent', 1, 0, 'global']] - :set ai! - : Should not print anything, use :noa - :noa :set nonu - :let g:testcase="7: Setting several global list and number option\n" - :let g:options=[['list', 0, 1, 'global'], ['number', 0, 1, 'global']] - :set list nu - :noa set nolist nonu - :let g:testcase="8: Setting global acd\n" - :let g:options=[['autochdir', 0, 1, 'global']] - :setlocal acd - :let g:testcase="9: Setting global autoread\n" - :let g:options=[['autoread', 0, 1, 'global']] - :set ar - :let g:testcase="10: Setting local autoread\n" - :let g:options=[['autoread', 0, 1, 'local']] - :setlocal ar - :let g:testcase="11: Setting global autoread\n" - :let g:options=[['autoread', 1, 0, 'global']] - :setglobal invar - :let g:testcase="12: Setting option backspace through :let\n" - :let g:options=[['backspace', '', 'eol,indent,start', 'global']] - :let &bs="eol,indent,start" - :let g:testcase="13: Setting option backspace through setbufvar()\n" - :let g:options=[['backup', '', '1', 'local']] - : "try twice, first time, shouldn't trigger because option name is invalid, second time, it should trigger - :call setbufvar(1, '&l:bk', 1) - : "should trigger, use correct option name - :call setbufvar(1, '&backup', 1) - :let g:testcase="14: Setting number option using setwinvar\n" - :let g:options=[['number', 0, 1, 'local']] - :call setwinvar(0, '&number', 1) - :" Write register now, because next test shouldn't output anything. - :$put r - :let @r='' - :let g:testcase="\n15: Setting key option, shouldn't trigger\n" - :let g:options=[['key', 'invalid', 'invalid1', 'invalid']] - :setlocal key=blah - :setlocal key= - :$put =g:testcase - :$put r - :/^dummy text/,$w! test.out - :qa! - ENDTEST - dummy text --- 0 ---- *** ../vim-8.0.0735/src/testdir/test_autocmd_option.ok 2015-09-29 18:03:38.000000000 +0200 --- src/testdir/test_autocmd_option.ok 1970-01-01 01:00:00.000000000 +0100 *************** *** 1,64 **** - dummy text - - 1: Setting number option - Expected: Name: , Oldval: <0>, NewVal: <1>, Scope: - Autocmd Option: , OldVal: <0>, NewVal: <1>, Scope: - - 2: Setting local number option - Expected: Name: , Oldval: <1>, NewVal: <0>, Scope: - Autocmd Option: , OldVal: <1>, NewVal: <0>, Scope: - - 3: Setting global number option - Expected: Name: , Oldval: <1>, NewVal: <0>, Scope: - Autocmd Option: , OldVal: <1>, NewVal: <0>, Scope: - - 4: Setting local autoindent option - Expected: Name: , Oldval: <0>, NewVal: <1>, Scope: - Autocmd Option: , OldVal: <0>, NewVal: <1>, Scope: - - 5: Setting global autoindent option - Expected: Name: , Oldval: <0>, NewVal: <1>, Scope: - Autocmd Option: , OldVal: <0>, NewVal: <1>, Scope: - - 6: Setting global autoindent option - Expected: Name: , Oldval: <1>, NewVal: <0>, Scope: - Autocmd Option: , OldVal: <1>, NewVal: <0>, Scope: - - 7: Setting several global list and number option - Expected: Name: , Oldval: <0>, NewVal: <1>, Scope: - Autocmd Option: , OldVal: <0>, NewVal: <1>, Scope: - - 7: Setting several global list and number option - Expected: Name: , Oldval: <0>, NewVal: <1>, Scope: - Autocmd Option: , OldVal: <0>, NewVal: <1>, Scope: - - 8: Setting global acd - Expected: Name: , Oldval: <0>, NewVal: <1>, Scope: - Autocmd Option: , OldVal: <0>, NewVal: <1>, Scope: - - 9: Setting global autoread - Expected: Name: , Oldval: <0>, NewVal: <1>, Scope: - Autocmd Option: , OldVal: <0>, NewVal: <1>, Scope: - - 10: Setting local autoread - Expected: Name: , Oldval: <0>, NewVal: <1>, Scope: - Autocmd Option: , OldVal: <1>, NewVal: <1>, Scope: - - 11: Setting global autoread - Expected: Name: , Oldval: <1>, NewVal: <0>, Scope: - Autocmd Option: , OldVal: <1>, NewVal: <0>, Scope: - - 12: Setting option backspace through :let - Expected: Name: , Oldval: <>, NewVal: , Scope: - Autocmd Option: , OldVal: <>, NewVal: , Scope: - - 13: Setting option backspace through setbufvar() - Expected: Name: , Oldval: <>, NewVal: <1>, Scope: - Autocmd Option: , OldVal: <0>, NewVal: <1>, Scope: - - 14: Setting number option using setwinvar - Expected: Name: , Oldval: <0>, NewVal: <1>, Scope: - Autocmd Option: , OldVal: <0>, NewVal: <1>, Scope: - - 15: Setting key option, shouldn't trigger - --- 0 ---- *** ../vim-8.0.0735/src/version.c 2017-07-19 17:05:55.183185953 +0200 --- src/version.c 2017-07-19 18:14:26.945848611 +0200 *************** *** 771,772 **** --- 771,774 ---- { /* Add new patch number below this line */ + /**/ + 736, /**/ -- hundred-and-one symptoms of being an internet addict: 187. You promise yourself that you'll only stay online for another 15 minutes...at least once every hour. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///