diff options
-rw-r--r-- | runtime/doc/autocmd.txt | 2 | ||||
-rw-r--r-- | runtime/doc/eval.txt | 2 | ||||
-rw-r--r-- | runtime/filetype.vim | 2 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/buf.lua | 5 | ||||
-rw-r--r-- | runtime/lua/vim/treesitter/query.lua | 7 | ||||
-rw-r--r-- | src/nvim/api/vim.c | 5 | ||||
-rw-r--r-- | src/nvim/decoration.c | 4 | ||||
-rw-r--r-- | src/nvim/eval/encode.c | 7 | ||||
-rw-r--r-- | src/nvim/ex_cmds.c | 12 | ||||
-rw-r--r-- | src/nvim/ex_docmd.c | 2 | ||||
-rw-r--r-- | src/nvim/extmark.c | 1 | ||||
-rw-r--r-- | src/nvim/file_search.c | 5 | ||||
-rw-r--r-- | src/nvim/marktree.c | 68 | ||||
-rw-r--r-- | src/nvim/testdir/test_filetype.vim | 2 | ||||
-rw-r--r-- | src/nvim/window.c | 4 | ||||
-rw-r--r-- | test/functional/autocmd/dirchanged_spec.lua | 24 |
16 files changed, 83 insertions, 69 deletions
diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt index dd9ab74a94..01b21aa085 100644 --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -518,6 +518,8 @@ DirChanged After the |current-directory| was changed. Sets these |v:event| keys: cwd: current working directory scope: "global", "tab", "window" + changed_window: v:true if we fired the event + switching window (or tab) Non-recursive (event cannot trigger itself). *FileAppendCmd* FileAppendCmd Before appending to a file. Should do the diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 800de63a55..6da89f5491 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1614,6 +1614,8 @@ v:event Dictionary of event data for the current |autocommand|. Valid |CompleteChanged|. scrollbar Is |v:true| if popup menu have scrollbar, or |v:false| if not. + changed_window Is |v:true| if the the event fired + while changing window (or tab) on |DirChanged|. *v:exception* *exception-variable* v:exception The value of the exception most recently caught and not diff --git a/runtime/filetype.vim b/runtime/filetype.vim index 7accc22b3d..8eb26046da 100644 --- a/runtime/filetype.vim +++ b/runtime/filetype.vim @@ -1723,7 +1723,7 @@ au BufNewFile,BufRead *.latex,*.sty,*.dtx,*.ltx,*.bbl setf tex au BufNewFile,BufRead *.tex call dist#ft#FTtex() " ConTeXt -au BufNewFile,BufRead *.mkii,*.mkiv,*.mkvi setf context +au BufNewFile,BufRead *.mkii,*.mkiv,*.mkvi,*.mkxl,*.mklx setf context " Texinfo au BufNewFile,BufRead *.texinfo,*.texi,*.txi setf texinfo diff --git a/runtime/lua/vim/lsp/buf.lua b/runtime/lua/vim/lsp/buf.lua index c015884f5b..0b8e08f36c 100644 --- a/runtime/lua/vim/lsp/buf.lua +++ b/runtime/lua/vim/lsp/buf.lua @@ -138,8 +138,9 @@ end function M.formatting_sync(options, timeout_ms) local params = util.make_formatting_params(options) local result = vim.lsp.buf_request_sync(0, "textDocument/formatting", params, timeout_ms) - if not result then return end - result = result[1].result + if not result or vim.tbl_isempty(result) then return end + local _, formatting_result = next(result) + result = formatting_result.result if not result then return end vim.lsp.util.apply_text_edits(result) end diff --git a/runtime/lua/vim/treesitter/query.lua b/runtime/lua/vim/treesitter/query.lua index cc7dc2656d..3537ba78f5 100644 --- a/runtime/lua/vim/treesitter/query.lua +++ b/runtime/lua/vim/treesitter/query.lua @@ -38,9 +38,8 @@ end local function get_query_files(lang, query_name, is_included) local lang_files = filtered_runtime_queries(lang, query_name) - local query_files = lang_files - if #query_files == 0 then return {} end + if #lang_files == 0 then return {} end local base_langs = {} @@ -51,7 +50,7 @@ local function get_query_files(lang, query_name, is_included) -- {language} ::= {lang} | ({lang}) local MODELINE_FORMAT = "^;+%s*inherits%s*:?%s*([a-z_,()]+)%s*$" - for _, file in ipairs(query_files) do + for _, file in ipairs(lang_files) do local modeline = vim.fn.readfile(file, "", 1) if #modeline == 1 then @@ -73,10 +72,12 @@ local function get_query_files(lang, query_name, is_included) end end + local query_files = {} for _, base_lang in ipairs(base_langs) do local base_files = get_query_files(base_lang, query_name, true) vim.list_extend(query_files, base_files) end + vim.list_extend(query_files, lang_files) return query_files end diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 5050f1842d..cf822782d8 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -805,7 +805,7 @@ ArrayOf(String) nvim_get_runtime_file(String name, Boolean all, Error *err) } int flags = DIP_START | (all ? DIP_ALL : 0); - do_in_runtimepath(name.size ? (char_u *)name.data : NULL, + do_in_runtimepath((char_u *)name.data, flags, find_runtime_cb, &rv); return rv; } @@ -2687,6 +2687,9 @@ void nvim__screenshot(String path) static void clear_provider(DecorProvider *p) { + if (p == NULL) { + return; + } NLUA_CLEAR_REF(p->redraw_start); NLUA_CLEAR_REF(p->redraw_buf); NLUA_CLEAR_REF(p->redraw_win); diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c index d411f22e7a..0721c0c57b 100644 --- a/src/nvim/decoration.c +++ b/src/nvim/decoration.c @@ -182,7 +182,7 @@ bool decor_redraw_start(buf_T *buf, int top_row, DecorState *state) Decoration *decor = item->decor; if ((!(mark.id&MARKTREE_END_FLAG) && altpos.row < top_row - && item && !kv_size(decor->virt_text)) + && !kv_size(decor->virt_text)) || ((mark.id&MARKTREE_END_FLAG) && altpos.row >= top_row)) { goto next_mark; } @@ -251,7 +251,7 @@ int decor_redraw_col(buf_T *buf, int col, DecorState *state) if (endpos.row < mark.row || (endpos.row == mark.row && endpos.col <= mark.col)) { - if (item && !kv_size(decor->virt_text)) { + if (!kv_size(decor->virt_text)) { goto next_mark; } } diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c index 137f099df6..9a9f2e4287 100644 --- a/src/nvim/eval/encode.c +++ b/src/nvim/eval/encode.c @@ -159,8 +159,11 @@ static int conv_error(const char *const msg, const MPConvStack *const mpstack, vim_snprintf((char *)IObuff, IOSIZE, idx_msg, idx); ga_concat(&msg_ga, IObuff); } else { - typval_T key_tv = *TV_LIST_ITEM_TV( - tv_list_first(TV_LIST_ITEM_TV(li)->vval.v_list)); + assert(li != NULL); + listitem_T *const first_item = + tv_list_first(TV_LIST_ITEM_TV(li)->vval.v_list); + assert(first_item != NULL); + typval_T key_tv = *TV_LIST_ITEM_TV(first_item); char *const key = encode_tv2echo(&key_tv, NULL); vim_snprintf((char *) IObuff, IOSIZE, key_pair_msg, key, idx); xfree(key); diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 3e49d7845d..55366842b0 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -3451,13 +3451,13 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, sub_firstline = NULL; - /* - * ~ in the substitute pattern is replaced with the old pattern. - * We do it here once to avoid it to be replaced over and over again. - * But don't do it when it starts with "\=", then it's an expression. - */ - if (!(sub[0] == '\\' && sub[1] == '=')) + // ~ in the substitute pattern is replaced with the old pattern. + // We do it here once to avoid it to be replaced over and over again. + // But don't do it when it starts with "\=", then it's an expression. + assert(sub != NULL); + if (!(sub[0] == '\\' && sub[1] == '=')) { sub = regtilde(sub, p_magic); + } // Check for a match on each line. // If preview: limit to max('cmdwinheight', viewport). diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index d7ed2fe97d..60963f5411 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -7506,7 +7506,7 @@ void post_chdir(CdScope scope, bool trigger_dirchanged) shorten_fnames(true); if (trigger_dirchanged) { - do_autocmd_dirchanged(cwd, scope); + do_autocmd_dirchanged(cwd, scope, false); } } diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c index 413ea4116a..ba685b158e 100644 --- a/src/nvim/extmark.c +++ b/src/nvim/extmark.c @@ -74,6 +74,7 @@ uint64_t extmark_set(buf_T *buf, uint64_t ns_id, uint64_t id, Decoration *decor, ExtmarkOp op) { ExtmarkNs *ns = buf_ns_ref(buf, ns_id, true); + assert(ns != NULL); mtpos_t old_pos; uint64_t mark = 0; diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c index 47272df2f0..b1fa0b6779 100644 --- a/src/nvim/file_search.c +++ b/src/nvim/file_search.c @@ -1565,7 +1565,7 @@ theend: return file_name; } -void do_autocmd_dirchanged(char *new_dir, CdScope scope) +void do_autocmd_dirchanged(char *new_dir, CdScope scope, bool changed_window) { static bool recursive = false; @@ -1601,6 +1601,7 @@ void do_autocmd_dirchanged(char *new_dir, CdScope scope) tv_dict_add_str(dict, S_LEN("scope"), buf); // -V614 tv_dict_add_str(dict, S_LEN("cwd"), new_dir); + tv_dict_add_bool(dict, S_LEN("changed_window"), changed_window); tv_dict_set_keys_readonly(dict); apply_autocmds(EVENT_DIRCHANGED, (char_u *)buf, (char_u *)new_dir, false, @@ -1633,7 +1634,7 @@ int vim_chdirfile(char_u *fname) slash_adjust((char_u *)dir); #endif if (!strequal(dir, (char *)NameBuff)) { - do_autocmd_dirchanged(dir, kCdScopeWindow); + do_autocmd_dirchanged(dir, kCdScopeWindow, false); } return OK; diff --git a/src/nvim/marktree.c b/src/nvim/marktree.c index 6dd452b5af..e9ea2cbba9 100644 --- a/src/nvim/marktree.c +++ b/src/nvim/marktree.c @@ -326,38 +326,37 @@ void marktree_del_itr(MarkTree *b, MarkTreeIter *itr, bool rev) x->n--; // 4. - if (adjustment) { - if (adjustment == 1) { - abort(); - } else { // adjustment == -1 - int ilvl = itr->lvl-1; - mtnode_t *lnode = x; - do { - mtnode_t *p = lnode->parent; - if (ilvl < 0) { - abort(); - } - int i = itr->s[ilvl].i; - assert(p->ptr[i] == lnode); - if (i > 0) { - unrelative(p->key[i-1].pos, &intkey.pos); - } - lnode = p; - ilvl--; - } while (lnode != cur); - - mtkey_t deleted = cur->key[curi]; - cur->key[curi] = intkey; - refkey(b, cur, curi); - relative(intkey.pos, &deleted.pos); - mtnode_t *y = cur->ptr[curi+1]; - if (deleted.pos.row || deleted.pos.col) { - while (y) { - for (int k = 0; k < y->n; k++) { - unrelative(deleted.pos, &y->key[k].pos); - } - y = y->level ? y->ptr[0] : NULL; + // if (adjustment == 1) { + // abort(); + // } + if (adjustment == -1) { + int ilvl = itr->lvl-1; + const mtnode_t *lnode = x; + do { + const mtnode_t *const p = lnode->parent; + if (ilvl < 0) { + abort(); + } + const int i = itr->s[ilvl].i; + assert(p->ptr[i] == lnode); + if (i > 0) { + unrelative(p->key[i-1].pos, &intkey.pos); + } + lnode = p; + ilvl--; + } while (lnode != cur); + + mtkey_t deleted = cur->key[curi]; + cur->key[curi] = intkey; + refkey(b, cur, curi); + relative(intkey.pos, &deleted.pos); + mtnode_t *y = cur->ptr[curi+1]; + if (deleted.pos.row || deleted.pos.col) { + while (y) { + for (int k = 0; k < y->n; k++) { + unrelative(deleted.pos, &y->key[k].pos); } + y = y->level ? y->ptr[0] : NULL; } } } @@ -435,9 +434,10 @@ void marktree_del_itr(MarkTree *b, MarkTreeIter *itr, bool rev) // BONUS STEP: fix the iterator, so that it points to the key afterwards // TODO(bfredl): with "rev" should point before - if (adjustment == 1) { - abort(); - } else if (adjustment == -1) { + // if (adjustment == 1) { + // abort(); + // } + if (adjustment == -1) { // tricky: we stand at the deleted space in the previous leaf node. // But the inner key is now the previous key we stole, so we need // to skip that one as well. diff --git a/src/nvim/testdir/test_filetype.vim b/src/nvim/testdir/test_filetype.vim index 9f79c1b545..9f7e153955 100644 --- a/src/nvim/testdir/test_filetype.vim +++ b/src/nvim/testdir/test_filetype.vim @@ -109,7 +109,7 @@ let s:filename_checks = { \ 'conaryrecipe': ['file.recipe'], \ 'conf': ['auto.master'], \ 'config': ['configure.in', 'configure.ac', 'Pipfile'], - \ 'context': ['tex/context/any/file.tex', 'file.mkii', 'file.mkiv', 'file.mkvi'], + \ 'context': ['tex/context/any/file.tex', 'file.mkii', 'file.mkiv', 'file.mkvi', 'file.mkxl', 'file.mklx'], \ 'cpp': ['file.cxx', 'file.c++', 'file.hh', 'file.hxx', 'file.hpp', 'file.ipp', 'file.moc', 'file.tcc', 'file.inl', 'file.tlh'], \ 'crm': ['file.crm'], \ 'cs': ['file.cs'], diff --git a/src/nvim/window.c b/src/nvim/window.c index 9d918ebeb0..3429e3df70 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -4567,7 +4567,7 @@ static void win_enter_ext(win_T *wp, bool undo_sync, int curwin_invalid, if (os_chdir(new_dir) == 0) { if (!p_acd && !strequal(new_dir, cwd)) { do_autocmd_dirchanged(new_dir, curwin->w_localdir - ? kCdScopeWindow : kCdScopeTab); + ? kCdScopeWindow : kCdScopeTab, true); } shorten_fnames(true); } @@ -4576,7 +4576,7 @@ static void win_enter_ext(win_T *wp, bool undo_sync, int curwin_invalid, // directory: Change to the global directory. if (os_chdir((char *)globaldir) == 0) { if (!p_acd && !strequal((char *)globaldir, cwd)) { - do_autocmd_dirchanged((char *)globaldir, kCdScopeGlobal); + do_autocmd_dirchanged((char *)globaldir, kCdScopeGlobal, true); } } XFREE_CLEAR(globaldir); diff --git a/test/functional/autocmd/dirchanged_spec.lua b/test/functional/autocmd/dirchanged_spec.lua index 7979e91a4c..6f2da24cf2 100644 --- a/test/functional/autocmd/dirchanged_spec.lua +++ b/test/functional/autocmd/dirchanged_spec.lua @@ -29,15 +29,15 @@ describe('autocmd DirChanged', function() it('sets v:event', function() command('lcd '..dirs[1]) - eq({cwd=dirs[1], scope='window'}, eval('g:ev')) + eq({cwd=dirs[1], scope='window', changed_window=false}, eval('g:ev')) eq(1, eval('g:cdcount')) command('tcd '..dirs[2]) - eq({cwd=dirs[2], scope='tab'}, eval('g:ev')) + eq({cwd=dirs[2], scope='tab', changed_window=false}, eval('g:ev')) eq(2, eval('g:cdcount')) command('cd '..dirs[3]) - eq({cwd=dirs[3], scope='global'}, eval('g:ev')) + eq({cwd=dirs[3], scope='global', changed_window=false}, eval('g:ev')) eq(3, eval('g:cdcount')) end) @@ -57,7 +57,7 @@ describe('autocmd DirChanged', function() -- Set up a _nested_ handler. command('autocmd DirChanged * nested lcd '..dirs[3]) command('lcd '..dirs[1]) - eq({cwd=dirs[1], scope='window'}, eval('g:ev')) + eq({cwd=dirs[1], scope='window', changed_window=false}, eval('g:ev')) eq(1, eval('g:cdcount')) -- autocmd changed to dirs[3], but did NOT trigger another DirChanged. eq(dirs[3], eval('getcwd()')) @@ -105,10 +105,10 @@ describe('autocmd DirChanged', function() command('set autochdir') command('split '..dirs[1]..'/foo') - eq({cwd=dirs[1], scope='window'}, eval('g:ev')) + eq({cwd=dirs[1], scope='window', changed_window=false}, eval('g:ev')) command('split '..dirs[2]..'/bar') - eq({cwd=dirs[2], scope='window'}, eval('g:ev')) + eq({cwd=dirs[2], scope='window', changed_window=false}, eval('g:ev')) eq(2, eval('g:cdcount')) end) @@ -121,16 +121,16 @@ describe('autocmd DirChanged', function() command('lcd '..dirs[1]) command('2wincmd w') -- window 2 - eq({cwd=dirs[2], scope='window'}, eval('g:ev')) + eq({cwd=dirs[2], scope='window', changed_window=true}, eval('g:ev')) eq(4, eval('g:cdcount')) command('tabnew') -- tab 2 (tab-local CWD) eq(4, eval('g:cdcount')) -- same CWD, no DirChanged event command('tcd '..dirs[3]) command('tabnext') -- tab 1 (no tab-local CWD) - eq({cwd=dirs[2], scope='window'}, eval('g:ev')) + eq({cwd=dirs[2], scope='window', changed_window=true}, eval('g:ev')) command('tabnext') -- tab 2 - eq({cwd=dirs[3], scope='tab'}, eval('g:ev')) + eq({cwd=dirs[3], scope='tab', changed_window=true}, eval('g:ev')) eq(7, eval('g:cdcount')) command('tabnext') -- tab 1 @@ -142,17 +142,17 @@ describe('autocmd DirChanged', function() it('is triggered by nvim_set_current_dir()', function() request('nvim_set_current_dir', dirs[1]) - eq({cwd=dirs[1], scope='global'}, eval('g:ev')) + eq({cwd=dirs[1], scope='global', changed_window=false}, eval('g:ev')) request('nvim_set_current_dir', dirs[2]) - eq({cwd=dirs[2], scope='global'}, eval('g:ev')) + eq({cwd=dirs[2], scope='global', changed_window=false}, eval('g:ev')) local status, err = pcall(function() request('nvim_set_current_dir', '/doesnotexist') end) eq(false, status) eq('Failed to change directory', string.match(err, ': (.*)')) - eq({cwd=dirs[2], scope='global'}, eval('g:ev')) + eq({cwd=dirs[2], scope='global', changed_window=false}, eval('g:ev')) end) it('works when local to buffer', function() |