diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/api/vim.c | 5 | ||||
-rw-r--r-- | src/nvim/auevents.lua | 2 | ||||
-rw-r--r-- | src/nvim/buffer_defs.h | 3 | ||||
-rw-r--r-- | src/nvim/change.c | 2 | ||||
-rw-r--r-- | src/nvim/decoration.c | 4 | ||||
-rw-r--r-- | src/nvim/edit.c | 8 | ||||
-rw-r--r-- | src/nvim/eval/encode.c | 7 | ||||
-rw-r--r-- | src/nvim/ex_cmds.c | 12 | ||||
-rw-r--r-- | src/nvim/extmark.c | 1 | ||||
-rw-r--r-- | src/nvim/marktree.c | 68 | ||||
-rw-r--r-- | src/nvim/normal.c | 11 |
11 files changed, 78 insertions, 45 deletions
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/auevents.lua b/src/nvim/auevents.lua index 9c28398f5b..6be51c504c 100644 --- a/src/nvim/auevents.lua +++ b/src/nvim/auevents.lua @@ -7,6 +7,7 @@ return { 'BufFilePre', -- before renaming a buffer 'BufHidden', -- just after buffer becomes hidden 'BufLeave', -- before leaving a buffer + 'BufModifiedSet', -- after the 'modified' state of a buffer changes 'BufNew', -- after creating any buffer 'BufNewFile', -- when creating a buffer for a new file 'BufReadCmd', -- read buffer using command @@ -124,6 +125,7 @@ return { -- List of nvim-specific events or aliases for the purpose of generating -- syntax file nvim_specific = { + BufModifiedSet=true, DirChanged=true, Signal=true, TabClosed=true, diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 0b89dff92f..93fe37b585 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -541,6 +541,9 @@ struct file_buffer { int b_changed; // 'modified': Set to true if something in the // file has been changed and not written out. + bool b_changed_invalid; // Set if BufModified autocmd has not been + // triggered since the last time b_changed was + // modified. /// Change-identifier incremented for each change, including undo. /// diff --git a/src/nvim/change.c b/src/nvim/change.c index 9ee987b45d..271d350967 100644 --- a/src/nvim/change.c +++ b/src/nvim/change.c @@ -129,6 +129,7 @@ void changed(void) void changed_internal(void) { curbuf->b_changed = true; + curbuf->b_changed_invalid = true; ml_setflags(curbuf); check_status(curbuf); redraw_tabline = true; @@ -502,6 +503,7 @@ void unchanged(buf_T *buf, int ff, bool always_inc_changedtick) { if (buf->b_changed || (ff && file_ff_differs(buf, false))) { buf->b_changed = false; + buf->b_changed_invalid = true; ml_setflags(buf); if (ff) { save_file_ff(buf); 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/edit.c b/src/nvim/edit.c index d7cca9ba36..9c8d64a6b2 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -1488,6 +1488,14 @@ static void ins_redraw( do_autocmd_winscrolled(curwin); } + // Trigger BufModified if b_changed_invalid is set. + if (ready && has_event(EVENT_BUFMODIFIEDSET) + && curbuf->b_changed_invalid == true + && !pum_visible()) { + apply_autocmds(EVENT_BUFMODIFIEDSET, NULL, NULL, false, curbuf); + curbuf->b_changed_invalid = false; + } + if (curwin->w_p_cole > 0 && conceal_cursor_line(curwin) && conceal_cursor_moved) { redrawWinline(curwin, curwin->w_cursor.lnum); 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/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/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/normal.c b/src/nvim/normal.c index 771ca732f4..2805a7d74e 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -1229,6 +1229,16 @@ static void normal_check_text_changed(NormalState *s) } } +static void normal_check_buffer_modified(NormalState *s) +{ + // Trigger BufModified if b_modified changed + if (!finish_op && has_event(EVENT_BUFMODIFIEDSET) + && curbuf->b_changed_invalid == true) { + apply_autocmds(EVENT_BUFMODIFIEDSET, NULL, NULL, false, curbuf); + curbuf->b_changed_invalid = false; + } +} + static void normal_check_folds(NormalState *s) { // Include a closed fold completely in the Visual area. @@ -1336,6 +1346,7 @@ static int normal_check(VimState *state) normal_check_cursor_moved(s); normal_check_text_changed(s); normal_check_window_scrolled(s); + normal_check_buffer_modified(s); // Updating diffs from changed() does not always work properly, // esp. updating folds. Do an update just before redrawing if |