aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/autocmd.txt2
-rw-r--r--runtime/doc/eval.txt2
-rw-r--r--runtime/filetype.vim2
-rw-r--r--runtime/lua/vim/lsp/buf.lua5
-rw-r--r--runtime/lua/vim/treesitter/query.lua7
-rw-r--r--src/nvim/api/vim.c5
-rw-r--r--src/nvim/decoration.c4
-rw-r--r--src/nvim/eval/encode.c7
-rw-r--r--src/nvim/ex_cmds.c12
-rw-r--r--src/nvim/ex_docmd.c2
-rw-r--r--src/nvim/extmark.c1
-rw-r--r--src/nvim/file_search.c5
-rw-r--r--src/nvim/marktree.c68
-rw-r--r--src/nvim/testdir/test_filetype.vim2
-rw-r--r--src/nvim/window.c4
-rw-r--r--test/functional/autocmd/dirchanged_spec.lua24
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()