mirror of
https://github.com/neovim/neovim.git
synced 2026-02-20 09:19:43 +10:00
Merge #8832 from eraserhd/vim-insert-setline-undo-fixes
This commit is contained in:
@@ -276,7 +276,7 @@ static void insert_enter(InsertState *s)
|
||||
|
||||
set_vim_var_string(VV_INSERTMODE, (char *) s->ptr, 1);
|
||||
set_vim_var_string(VV_CHAR, NULL, -1);
|
||||
apply_autocmds(EVENT_INSERTENTER, NULL, NULL, false, curbuf);
|
||||
ins_apply_autocmds(EVENT_INSERTENTER);
|
||||
|
||||
// Make sure the cursor didn't move. Do call check_cursor_col() in
|
||||
// case the text was modified. Since Insert mode was not started yet
|
||||
@@ -469,7 +469,7 @@ static void insert_enter(InsertState *s)
|
||||
|
||||
foldUpdateAfterInsert();
|
||||
if (s->cmdchar != 'r' && s->cmdchar != 'v') {
|
||||
apply_autocmds(EVENT_INSERTLEAVE, NULL, NULL, false, curbuf);
|
||||
ins_apply_autocmds(EVENT_INSERTLEAVE);
|
||||
}
|
||||
did_cursorhold = false;
|
||||
}
|
||||
@@ -1376,7 +1376,7 @@ ins_redraw (
|
||||
// Make sure curswant is correct, an autocommand may call
|
||||
// getcurpos()
|
||||
update_curswant();
|
||||
apply_autocmds(EVENT_CURSORMOVEDI, NULL, NULL, false, curbuf);
|
||||
ins_apply_autocmds(EVENT_CURSORMOVEDI);
|
||||
}
|
||||
if (curwin->w_p_cole > 0) {
|
||||
conceal_old_cursor_line = last_cursormoved.lnum;
|
||||
@@ -1390,8 +1390,18 @@ ins_redraw (
|
||||
if (ready && has_event(EVENT_TEXTCHANGEDI)
|
||||
&& curbuf->b_last_changedtick != buf_get_changedtick(curbuf)
|
||||
&& !pum_visible()) {
|
||||
aco_save_T aco;
|
||||
varnumber_T tick = buf_get_changedtick(curbuf);
|
||||
|
||||
// save and restore curwin and curbuf, in case the autocmd changes them
|
||||
aucmd_prepbuf(&aco, curbuf);
|
||||
apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, false, curbuf);
|
||||
aucmd_restbuf(&aco);
|
||||
curbuf->b_last_changedtick = buf_get_changedtick(curbuf);
|
||||
if (tick != buf_get_changedtick(curbuf)) { // see ins_apply_autocmds()
|
||||
u_save(curwin->w_cursor.lnum,
|
||||
(linenr_T)(curwin->w_cursor.lnum + 1));
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger TextChangedP if changedtick differs. When the popupmenu closes
|
||||
@@ -1400,8 +1410,18 @@ ins_redraw (
|
||||
if (ready && has_event(EVENT_TEXTCHANGEDP)
|
||||
&& curbuf->b_last_changedtick_pum != buf_get_changedtick(curbuf)
|
||||
&& pum_visible()) {
|
||||
apply_autocmds(EVENT_TEXTCHANGEDP, NULL, NULL, false, curbuf);
|
||||
curbuf->b_last_changedtick_pum = buf_get_changedtick(curbuf);
|
||||
aco_save_T aco;
|
||||
varnumber_T tick = buf_get_changedtick(curbuf);
|
||||
|
||||
// save and restore curwin and curbuf, in case the autocmd changes them
|
||||
aucmd_prepbuf(&aco, curbuf);
|
||||
apply_autocmds(EVENT_TEXTCHANGEDP, NULL, NULL, false, curbuf);
|
||||
aucmd_restbuf(&aco);
|
||||
curbuf->b_last_changedtick_pum = buf_get_changedtick(curbuf);
|
||||
if (tick != buf_get_changedtick(curbuf)) { // see ins_apply_autocmds()
|
||||
u_save(curwin->w_cursor.lnum,
|
||||
(linenr_T)(curwin->w_cursor.lnum + 1));
|
||||
}
|
||||
}
|
||||
|
||||
if (must_redraw)
|
||||
@@ -3392,12 +3412,12 @@ static bool ins_compl_prep(int c)
|
||||
do_c_expr_indent();
|
||||
/* Trigger the CompleteDone event to give scripts a chance to act
|
||||
* upon the completion. */
|
||||
apply_autocmds(EVENT_COMPLETEDONE, NULL, NULL, FALSE, curbuf);
|
||||
ins_apply_autocmds(EVENT_COMPLETEDONE);
|
||||
}
|
||||
} else if (ctrl_x_mode == CTRL_X_LOCAL_MSG)
|
||||
/* Trigger the CompleteDone event to give scripts a chance to act
|
||||
* upon the (possibly failed) completion. */
|
||||
apply_autocmds(EVENT_COMPLETEDONE, NULL, NULL, FALSE, curbuf);
|
||||
ins_apply_autocmds(EVENT_COMPLETEDONE);
|
||||
|
||||
/* reset continue_* if we left expansion-mode, if we stay they'll be
|
||||
* (re)set properly in ins_complete() */
|
||||
@@ -7399,7 +7419,7 @@ static void ins_insert(int replaceState)
|
||||
set_vim_var_string(VV_INSERTMODE, ((State & REPLACE_FLAG) ? "i" :
|
||||
replaceState == VREPLACE ? "v" :
|
||||
"r"), 1);
|
||||
apply_autocmds(EVENT_INSERTCHANGE, NULL, NULL, false, curbuf);
|
||||
ins_apply_autocmds(EVENT_INSERTCHANGE);
|
||||
if (State & REPLACE_FLAG) {
|
||||
State = INSERT | (State & LANGMAP);
|
||||
} else {
|
||||
@@ -8661,12 +8681,13 @@ static char_u *do_insert_char_pre(int c)
|
||||
set_vim_var_string(VV_CHAR, buf, -1);
|
||||
|
||||
char_u *res = NULL;
|
||||
if (apply_autocmds(EVENT_INSERTCHARPRE, NULL, NULL, FALSE, curbuf)) {
|
||||
/* Get the value of v:char. It may be empty or more than one
|
||||
* character. Only use it when changed, otherwise continue with the
|
||||
* original character to avoid breaking autoindent. */
|
||||
if (STRCMP(buf, get_vim_var_str(VV_CHAR)) != 0)
|
||||
if (ins_apply_autocmds(EVENT_INSERTCHARPRE)) {
|
||||
// Get the value of v:char. It may be empty or more than one
|
||||
// character. Only use it when changed, otherwise continue with the
|
||||
// original character to avoid breaking autoindent.
|
||||
if (STRCMP(buf, get_vim_var_str(VV_CHAR)) != 0) {
|
||||
res = vim_strsave(get_vim_var_str(VV_CHAR));
|
||||
}
|
||||
}
|
||||
|
||||
set_vim_var_string(VV_CHAR, NULL, -1);
|
||||
@@ -8675,6 +8696,23 @@ static char_u *do_insert_char_pre(int c)
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Trigger "event" and take care of fixing undo.
|
||||
static int ins_apply_autocmds(event_T event)
|
||||
{
|
||||
varnumber_T tick = buf_get_changedtick(curbuf);
|
||||
int r;
|
||||
|
||||
r = apply_autocmds(event, NULL, NULL, false, curbuf);
|
||||
|
||||
// If u_savesub() was called then we are not prepared to start
|
||||
// a new line. Call u_save() with no contents to fix that.
|
||||
if (tick != buf_get_changedtick(curbuf)) {
|
||||
u_save(curwin->w_cursor.lnum, (linenr_T)(curwin->w_cursor.lnum + 1));
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static void show_pum(int prev_w_wrow, int prev_w_leftcol)
|
||||
{
|
||||
// RedrawingDisabled may be set when invoked through complete().
|
||||
|
||||
@@ -423,7 +423,7 @@ void update_screen(int type)
|
||||
|
||||
/* redraw status line after the window to minimize cursor movement */
|
||||
if (wp->w_redr_status) {
|
||||
win_redr_status(wp);
|
||||
win_redr_status(wp, true); // any popup menu will be redrawn below
|
||||
}
|
||||
}
|
||||
end_search_hl();
|
||||
@@ -589,7 +589,7 @@ void update_debug_sign(const buf_T *const buf, const linenr_T lnum)
|
||||
win_update(wp);
|
||||
}
|
||||
if (wp->w_redr_status) {
|
||||
win_redr_status(wp);
|
||||
win_redr_status(wp, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4542,7 +4542,7 @@ void redraw_statuslines(void)
|
||||
{
|
||||
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
|
||||
if (wp->w_redr_status) {
|
||||
win_redr_status(wp);
|
||||
win_redr_status(wp, false);
|
||||
}
|
||||
}
|
||||
if (redraw_tabline)
|
||||
@@ -4809,7 +4809,9 @@ win_redr_status_matches (
|
||||
/// Redraw the status line of window `wp`.
|
||||
///
|
||||
/// If inversion is possible we use it. Else '=' characters are used.
|
||||
static void win_redr_status(win_T *wp)
|
||||
/// If "ignore_pum" is true, also redraw statusline when the popup menu is
|
||||
/// displayed.
|
||||
static void win_redr_status(win_T *wp, int ignore_pum)
|
||||
{
|
||||
int row;
|
||||
char_u *p;
|
||||
@@ -4832,7 +4834,7 @@ static void win_redr_status(win_T *wp)
|
||||
if (wp->w_status_height == 0) {
|
||||
// no status line, can only be last window
|
||||
redraw_cmdline = true;
|
||||
} else if (!redrawing() || pum_drawn()) {
|
||||
} else if (!redrawing() || (!ignore_pum && pum_drawn())) {
|
||||
// Don't redraw right now, do it later. Don't update status line when
|
||||
// popup menu is visible and may be drawn over it
|
||||
wp->w_redr_status = true;
|
||||
|
||||
@@ -567,7 +567,7 @@ func Test_OptionSet()
|
||||
" Cleanup
|
||||
au! OptionSet
|
||||
for opt in ['nu', 'ai', 'acd', 'ar', 'bs', 'backup', 'cul', 'cp']
|
||||
exe printf(":set %s&vi", opt)
|
||||
exe printf(":set %s&vim", opt)
|
||||
endfor
|
||||
call test_override('starting', 0)
|
||||
delfunc! AutoCommandOptionSet
|
||||
@@ -1221,3 +1221,27 @@ func Test_ChangedP()
|
||||
|
||||
bw!
|
||||
endfunc
|
||||
|
||||
let g:setline_handled = v:false
|
||||
func! SetLineOne()
|
||||
if !g:setline_handled
|
||||
call setline(1, "(x)")
|
||||
let g:setline_handled = v:true
|
||||
endif
|
||||
endfunc
|
||||
|
||||
func Test_TextChangedI_with_setline()
|
||||
throw 'skipped: Nvim does not support test_override()'
|
||||
new
|
||||
call test_override('char_avail', 1)
|
||||
autocmd TextChangedI <buffer> call SetLineOne()
|
||||
call feedkeys("i(\<CR>\<Esc>", 'tx')
|
||||
call assert_equal('(', getline(1))
|
||||
call assert_equal('x)', getline(2))
|
||||
undo
|
||||
call assert_equal('', getline(1))
|
||||
call assert_equal('', getline(2))
|
||||
|
||||
call test_override('starting', 0)
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
Reference in New Issue
Block a user