aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/edit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/edit.c')
-rw-r--r--src/nvim/edit.c269
1 files changed, 183 insertions, 86 deletions
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index d505b40935..47d491033b 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -26,6 +26,7 @@
#include "nvim/fileio.h"
#include "nvim/fold.h"
#include "nvim/getchar.h"
+#include "nvim/highlight_group.h"
#include "nvim/indent.h"
#include "nvim/indent_c.h"
#include "nvim/keymap.h"
@@ -35,7 +36,6 @@
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
-#include "nvim/misc1.h"
#include "nvim/mouse.h"
#include "nvim/move.h"
#include "nvim/normal.h"
@@ -227,6 +227,7 @@ typedef struct insert_state {
cmdarg_T *ca;
int mincol;
int cmdchar;
+ int cmdchar_todo; // cmdchar to handle once in init_prompt
int startln;
long count;
int c;
@@ -260,7 +261,7 @@ static colnr_T Insstart_blank_vcol; // vcol for first inserted blank
static bool update_Insstart_orig = true; // set Insstart_orig to Insstart
static char_u *last_insert = NULL; // the text of the previous insert,
- // K_SPECIAL and CSI are escaped
+ // K_SPECIAL is escaped
static int last_insert_skip; // nr of chars in front of previous insert
static int new_insert_skip; // nr of chars in front of current insert
static int did_restart_edit; // "restart_edit" when calling edit()
@@ -290,6 +291,7 @@ static void insert_enter(InsertState *s)
s->did_backspace = true;
s->old_topfill = -1;
s->replaceState = REPLACE;
+ s->cmdchar_todo = s->cmdchar;
// Remember whether editing was restarted after CTRL-O
did_restart_edit = restart_edit;
// sleep before redrawing, needed for "CTRL-O :" that results in an
@@ -385,11 +387,13 @@ static void insert_enter(InsertState *s)
State = INSERT;
}
+ may_trigger_modechanged();
stop_insert_mode = false;
- // Need to recompute the cursor position, it might move when the cursor is
- // on a TAB or special character.
- curs_columns(curwin, true);
+ // need to position cursor again when on a TAB
+ if (gchar_cursor() == TAB) {
+ curwin->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL);
+ }
// Enable langmap or IME, indicated by 'iminsert'.
// Note that IME may enabled/disabled without us noticing here, thus the
@@ -584,7 +588,8 @@ static int insert_check(VimState *state)
}
if (bt_prompt(curbuf)) {
- init_prompt(s->cmdchar);
+ init_prompt(s->cmdchar_todo);
+ s->cmdchar_todo = NUL;
}
// If we inserted a character at the last position of the last line in the
@@ -640,7 +645,10 @@ static int insert_check(VimState *state)
update_curswant();
s->old_topline = curwin->w_topline;
s->old_topfill = curwin->w_topfill;
- s->lastc = s->c; // remember previous char for CTRL-D
+
+ if (s->c != K_EVENT) {
+ s->lastc = s->c; // remember previous char for CTRL-D
+ }
// After using CTRL-G U the next cursor key will not break undo.
if (dont_sync_undo == kNone) {
@@ -654,10 +662,21 @@ static int insert_check(VimState *state)
static int insert_execute(VimState *state, int key)
{
+ InsertState *const s = (InsertState *)state;
+ if (stop_insert_mode) {
+ // Insert mode ended, possibly from a callback.
+ if (key != K_IGNORE && key != K_NOP) {
+ vungetc(key);
+ }
+ s->count = 0;
+ s->nomove = true;
+ ins_compl_prep(ESC);
+ return 0;
+ }
+
if (key == K_IGNORE || key == K_NOP) {
return -1; // get another key
}
- InsertState *s = (InsertState *)state;
s->c = key;
// Don't want K_EVENT with cursorhold for the second key, e.g., after CTRL-V.
@@ -821,6 +840,16 @@ static int insert_execute(VimState *state, int key)
return insert_handle_key(s);
}
+
+/// Return true when need to go to Insert mode because of 'insertmode'.
+///
+/// Don't do this when still processing a command or a mapping.
+/// Don't do this when inside a ":normal" command.
+bool goto_im(void)
+{
+ return p_im && stuff_empty() && typebuf_typed();
+}
+
static int insert_handle_key(InsertState *s)
{
// The big switch to handle a character in insert mode.
@@ -886,7 +915,7 @@ static int insert_handle_key(InsertState *s)
ins_ctrl_o();
// don't move the cursor left when 'virtualedit' has "onemore".
- if (ve_flags & VE_ONEMORE) {
+ if (get_ve_flags() & VE_ONEMORE) {
ins_at_eol = false;
s->nomove = true;
}
@@ -983,6 +1012,15 @@ static int insert_handle_key(InsertState *s)
break;
case Ctrl_W: // delete word before the cursor
+ if (bt_prompt(curbuf) && (mod_mask & MOD_MASK_SHIFT) == 0) {
+ // In a prompt window CTRL-W is used for window commands.
+ // Use Shift-CTRL-W to delete a word.
+ stuffcharReadbuff(Ctrl_W);
+ restart_edit = 'A';
+ s->nomove = true;
+ s->count = 0;
+ return 0;
+ }
s->did_backspace = ins_bs(s->c, BACKSPACE_WORD, &s->inserted_space);
auto_format(false, true);
break;
@@ -1044,13 +1082,21 @@ static int insert_handle_key(InsertState *s)
case K_COMMAND: // some command
do_cmdline(NULL, getcmdkeycmd, NULL, 0);
+ goto check_pum;
+
+ case K_LUA:
+ map_execute_lua();
check_pum:
+ // nvim_select_popupmenu_item() can be called from the handling of
+ // K_EVENT, K_COMMAND, or K_LUA.
// TODO(bfredl): Not entirely sure this indirection is necessary
// but doing like this ensures using nvim_select_popupmenu_item is
// equivalent to selecting the item with a typed key.
if (pum_want.active) {
if (pum_visible()) {
+ // Set this to NULL so that ins_complete() will update the message.
+ edit_submode_extra = NULL;
insert_do_complete(s);
if (pum_want.finish) {
// accept the item and stop completion
@@ -1347,6 +1393,7 @@ static void insert_do_complete(InsertState *s)
compl_cont_status = 0;
}
compl_busy = false;
+ can_si = true; // allow smartindenting
}
static void insert_do_cindent(InsertState *s)
@@ -1435,15 +1482,13 @@ bool edit(int cmdchar, bool startln, long count)
/// @param ready not busy with something
static void ins_redraw(bool ready)
{
- bool conceal_cursor_moved = false;
-
if (char_avail()) {
return;
}
// Trigger CursorMoved if the cursor moved. Not when the popup menu is
// visible, the command might delete it.
- if (ready && (has_event(EVENT_CURSORMOVEDI) || curwin->w_p_cole > 0)
+ if (ready && has_event(EVENT_CURSORMOVEDI)
&& !equalpos(curwin->w_last_cursormoved, curwin->w_cursor)
&& !pum_visible()) {
// Need to update the screen first, to make sure syntax
@@ -1453,13 +1498,10 @@ static void ins_redraw(bool ready)
if (syntax_present(curwin) && must_redraw) {
update_screen(0);
}
- if (has_event(EVENT_CURSORMOVEDI)) {
- // Make sure curswant is correct, an autocommand may call
- // getcurpos()
- update_curswant();
- ins_apply_autocmds(EVENT_CURSORMOVEDI);
- }
- conceal_cursor_moved = true;
+ // Make sure curswant is correct, an autocommand may call
+ // getcurpos()
+ update_curswant();
+ ins_apply_autocmds(EVENT_CURSORMOVEDI);
curwin->w_last_cursormoved = curwin->w_cursor;
}
@@ -1501,10 +1543,9 @@ static void ins_redraw(bool ready)
}
}
- // Trigger Scroll if viewport changed.
- if (ready && has_event(EVENT_WINSCROLLED)
- && win_did_scroll(curwin)) {
- do_autocmd_winscrolled(curwin);
+ if (ready) {
+ // Trigger Scroll if viewport changed.
+ may_trigger_winscrolled();
}
// Trigger BufModified if b_changed_invalid is set.
@@ -1515,11 +1556,6 @@ static void ins_redraw(bool ready)
curbuf->b_changed_invalid = false;
}
- if (curwin->w_p_cole > 0 && conceal_cursor_line(curwin)
- && conceal_cursor_moved) {
- redrawWinline(curwin, curwin->w_cursor.lnum);
- }
-
pum_check_clear();
if (must_redraw) {
update_screen(0);
@@ -1568,8 +1604,8 @@ static void ins_ctrl_v(void)
*/
static int pc_status;
#define PC_STATUS_UNSET 0 // pc_bytes was not set
-#define PC_STATUS_RIGHT 1 // right halve of double-wide char
-#define PC_STATUS_LEFT 2 // left halve of double-wide char
+#define PC_STATUS_RIGHT 1 // right half of double-wide char
+#define PC_STATUS_LEFT 2 // left half of double-wide char
#define PC_STATUS_SET 3 // pc_bytes was filled
static char_u pc_bytes[MB_MAXBYTES + 1]; // saved bytes
static int pc_attr;
@@ -1652,11 +1688,22 @@ static void init_prompt(int cmdchar_todo)
coladvance(MAXCOL);
changed_bytes(curbuf->b_ml.ml_line_count, 0);
}
+
+ // Insert always starts after the prompt, allow editing text after it.
+ if (Insstart_orig.lnum != curwin->w_cursor.lnum || Insstart_orig.col != (colnr_T)STRLEN(prompt)) {
+ Insstart.lnum = curwin->w_cursor.lnum;
+ Insstart.col = (colnr_T)STRLEN(prompt);
+ Insstart_orig = Insstart;
+ Insstart_textlen = Insstart.col;
+ Insstart_blank_vcol = MAXCOL;
+ arrow_used = false;
+ }
+
if (cmdchar_todo == 'A') {
coladvance(MAXCOL);
}
- if (cmdchar_todo == 'I' || curwin->w_cursor.col <= (int)STRLEN(prompt)) {
- curwin->w_cursor.col = STRLEN(prompt);
+ if (curwin->w_cursor.col < (colnr_T)STRLEN(prompt)) {
+ curwin->w_cursor.col = (colnr_T)STRLEN(prompt);
}
// Make sure the cursor is in a valid position.
check_cursor();
@@ -2048,6 +2095,8 @@ static void ins_ctrl_x(void)
// CTRL-V look like CTRL-N
ctrl_x_mode = CTRL_X_CMDLINE_CTRL_X;
}
+
+ may_trigger_modechanged();
}
// Whether other than default completion has been selected.
@@ -2660,6 +2709,7 @@ void set_completion(colnr_T startcol, list_T *list)
show_pum(save_w_wrow, save_w_leftcol);
}
+ may_trigger_modechanged();
ui_flush();
}
@@ -2715,12 +2765,13 @@ static bool pum_enough_matches(void)
static void trigger_complete_changed_event(int cur)
{
static bool recursive = false;
+ save_v_event_T save_v_event;
if (recursive) {
return;
}
- dict_T *v_event = get_vim_var_dict(VV_EVENT);
+ dict_T *v_event = get_v_event(&save_v_event);
if (cur < 0) {
tv_dict_add_dict(v_event, S_LEN("completed_item"), tv_dict_alloc());
} else {
@@ -2736,7 +2787,7 @@ static void trigger_complete_changed_event(int cur)
textlock--;
recursive = false;
- tv_dict_clear(v_event);
+ restore_v_event(v_event, &save_v_event);
}
/// Show the popup menu for the list of matches.
@@ -3569,7 +3620,7 @@ static bool ins_compl_prep(int c)
// Ignore end of Select mode mapping and mouse scroll buttons.
if (c == K_SELECT || c == K_MOUSEDOWN || c == K_MOUSEUP
|| c == K_MOUSELEFT || c == K_MOUSERIGHT || c == K_EVENT
- || c == K_COMMAND) {
+ || c == K_COMMAND || c == K_LUA) {
return retval;
}
@@ -3838,6 +3889,8 @@ static bool ins_compl_prep(int c)
ins_apply_autocmds(EVENT_COMPLETEDONE);
}
+ may_trigger_modechanged();
+
/* reset continue_* if we left expansion-mode, if we stay they'll be
* (re)set properly in ins_complete() */
if (!vim_is_ctrl_x_key(c)) {
@@ -3919,7 +3972,8 @@ static buf_T *ins_compl_next_buf(buf_T *buf, int flag)
/// Get the user-defined completion function name for completion 'type'
-static char_u *get_complete_funcname(int type) {
+static char_u *get_complete_funcname(int type)
+{
switch (type) {
case CTRL_X_FUNCTION:
return curbuf->b_p_cfu;
@@ -4586,6 +4640,8 @@ static int ins_compl_get_exp(pos_T *ini)
compl_curr_match = compl_old_match;
}
}
+ may_trigger_modechanged();
+
return i;
}
@@ -4930,7 +4986,7 @@ void ins_compl_check_keys(int frequency, int in_compl_func)
*/
static int ins_compl_key2dir(int c)
{
- if (c == K_EVENT || c == K_COMMAND) {
+ if (c == K_EVENT || c == K_COMMAND || c == K_LUA) {
return pum_want.item < pum_selected_item ? BACKWARD : FORWARD;
}
if (c == Ctrl_P || c == Ctrl_L
@@ -4960,7 +5016,7 @@ static int ins_compl_key2count(int c)
{
int h;
- if (c == K_EVENT || c == K_COMMAND) {
+ if (c == K_EVENT || c == K_COMMAND || c == K_LUA) {
int offset = pum_want.item - pum_selected_item;
return abs(offset);
}
@@ -4994,6 +5050,7 @@ static bool ins_compl_use_match(int c)
return false;
case K_EVENT:
case K_COMMAND:
+ case K_LUA:
return pum_want.active && pum_want.insert;
}
return true;
@@ -5051,10 +5108,10 @@ static int ins_complete(int c, bool enable_pum)
|| ctrl_x_mode == CTRL_X_PATH_PATTERNS
|| ctrl_x_mode == CTRL_X_PATH_DEFINES) {
if (compl_startpos.lnum != curwin->w_cursor.lnum) {
- /* line (probably) wrapped, set compl_startpos to the
- * first non_blank in the line, if it is not a wordchar
- * include it to get a better pattern, but then we don't
- * want the "\\<" prefix, check it bellow */
+ // line (probably) wrapped, set compl_startpos to the
+ // first non_blank in the line, if it is not a wordchar
+ // include it to get a better pattern, but then we don't
+ // want the "\\<" prefix, check it below.
compl_col = (colnr_T)getwhitecols(line);
compl_startpos.col = compl_col;
compl_startpos.lnum = curwin->w_cursor.lnum;
@@ -5231,7 +5288,7 @@ static int ins_complete(int c, bool enable_pum)
funcname = get_complete_funcname(ctrl_x_mode);
if (*funcname == NUL) {
semsg(_(e_notset), ctrl_x_mode == CTRL_X_FUNCTION
- ? "completefunc" : "omnifunc");
+ ? "completefunc" : "omnifunc");
// restore did_ai, so that adding comment leader works
did_ai = save_did_ai;
return FAIL;
@@ -5572,8 +5629,12 @@ int get_literal(void)
i = 0;
for (;;) {
nc = plain_vgetc();
- if (!(State & CMDLINE)
- && MB_BYTE2LEN_CHECK(nc) == 1) {
+ if ((mod_mask & ~MOD_MASK_SHIFT) != 0) {
+ // A character with non-Shift modifiers should not be a valid
+ // character for i_CTRL-V_digit.
+ break;
+ }
+ if (!(State & CMDLINE) && MB_BYTE2LEN_CHECK(nc) == 1) {
add_to_showcmd(nc);
}
if (nc == 'x' || nc == 'X') {
@@ -5639,6 +5700,8 @@ int get_literal(void)
--no_mapping;
if (nc) {
vungetc(nc);
+ // A character typed with i_CTRL-V_digit cannot have modifiers.
+ mod_mask = 0;
}
got_int = false; // CTRL-C typed after CTRL-V is not an interrupt
return cc;
@@ -5950,6 +6013,7 @@ static void internal_format(int textwidth, int second_indent, int flags, int for
char_u *saved_text = NULL;
colnr_T col;
colnr_T end_col;
+ bool did_do_comment = false;
virtcol = get_nolist_virtcol()
+ char2cells(c != NUL ? c : gchar_cursor());
@@ -6065,8 +6129,7 @@ static void internal_format(int textwidth, int second_indent, int flags, int for
if (curwin->w_cursor.col <= (colnr_T)wantcol) {
break;
}
- } else if ((cc >= 0x100 || !utf_allow_break_before(cc))
- && fo_multibyte) {
+ } else if ((cc >= 0x100 || !utf_allow_break_before(cc)) && fo_multibyte) {
int ncc;
bool allow_break;
@@ -6223,11 +6286,18 @@ static void internal_format(int textwidth, int second_indent, int flags, int for
+ (fo_white_par ? OPENLINE_KEEPTRAIL : 0)
+ (do_comments ? OPENLINE_DO_COM : 0)
+ ((flags & INSCHAR_COM_LIST) ? OPENLINE_COM_LIST : 0),
- ((flags & INSCHAR_COM_LIST) ? second_indent : old_indent));
+ ((flags & INSCHAR_COM_LIST) ? second_indent : old_indent),
+ &did_do_comment);
if (!(flags & INSCHAR_COM_LIST)) {
old_indent = 0;
}
+ // If a comment leader was inserted, may also do this on a following
+ // line.
+ if (did_do_comment) {
+ no_leader = false;
+ }
+
replace_offset = 0;
if (first_line) {
if (!(flags & INSCHAR_COM_LIST)) {
@@ -6564,7 +6634,7 @@ static void spell_back_to_badword(void)
int stop_arrow(void)
{
if (arrow_used) {
- Insstart = curwin->w_cursor; //new insertion starts here
+ Insstart = curwin->w_cursor; // new insertion starts here
if (Insstart.col > Insstart_orig.col && !ins_need_undo) {
// Don't update the original insert position when moved to the
// right, except when nothing was inserted yet.
@@ -6758,7 +6828,7 @@ void free_last_insert(void)
/// Add character "c" to buffer "s"
///
-/// Escapes the special meaning of K_SPECIAL and CSI, handles multi-byte
+/// Escapes the special meaning of K_SPECIAL, handles multi-byte
/// characters.
///
/// @param[in] c Character to add.
@@ -6772,7 +6842,7 @@ char_u *add_char2buf(int c, char_u *s)
const int len = utf_char2bytes(c, temp);
for (int i = 0; i < len; i++) {
c = temp[i];
- // Need to escape K_SPECIAL and CSI like in the typeahead buffer.
+ // Need to escape K_SPECIAL like in the typeahead buffer.
if (c == K_SPECIAL) {
*s++ = K_SPECIAL;
*s++ = KS_SPECIAL;
@@ -6846,8 +6916,7 @@ int oneright(void)
// move "l" bytes right, but don't end up on the NUL, unless 'virtualedit'
// contains "onemore".
- if (ptr[l] == NUL
- && (ve_flags & VE_ONEMORE) == 0) {
+ if (ptr[l] == NUL && (get_ve_flags() & VE_ONEMORE) == 0) {
return FAIL;
}
curwin->w_cursor.col += l;
@@ -7054,9 +7123,7 @@ int stuff_inserted(int c, long count, int no_esc)
stuffReadbuff((const char *)ptr);
// A trailing "0" is inserted as "<C-V>048", "^" as "<C-V>^".
if (last) {
- stuffReadbuff((last == '0'
- ? "\026\060\064\070"
- : "\026^"));
+ stuffReadbuff(last == '0' ? "\026\060\064\070" : "\026^");
}
} while (--count > 0);
@@ -7260,21 +7327,21 @@ static void mb_replace_pop_ins(int cc)
// Not a multi-byte char, put it back.
replace_push(c);
break;
+ }
+
+ buf[0] = c;
+ assert(n > 1);
+ for (i = 1; i < n; i++) {
+ buf[i] = replace_pop();
+ }
+ if (utf_iscomposing(utf_ptr2char(buf))) {
+ ins_bytes_len(buf, n);
} else {
- buf[0] = c;
- assert(n > 1);
- for (i = 1; i < n; i++) {
- buf[i] = replace_pop();
- }
- if (utf_iscomposing(utf_ptr2char(buf))) {
- ins_bytes_len(buf, n);
- } else {
- // Not a composing char, put it back.
- for (i = n - 1; i >= 0; i--) {
- replace_push(buf[i]);
- }
- break;
+ // Not a composing char, put it back.
+ for (i = n - 1; i >= 0; i--) {
+ replace_push(buf[i]);
}
+ break;
}
}
}
@@ -7630,16 +7697,34 @@ int hkmap(int c)
KAFsofit, hKAF, LAMED, MEMsofit, MEM, NUNsofit, NUN, SAMEH, AIN,
PEIsofit, PEI, ZADIsofit, ZADI, KOF, RESH, hSHIN, TAV,
};
- static char_u map[26] =
- { (char_u)hALEF /*a*/, (char_u)BET /*b*/, (char_u)hKAF /*c*/,
- (char_u)DALET /*d*/, (char_u)-1 /*e*/, (char_u)PEIsofit /*f*/,
- (char_u)GIMEL /*g*/, (char_u)HEI /*h*/, (char_u)IUD /*i*/,
- (char_u)HET /*j*/, (char_u)KOF /*k*/, (char_u)LAMED /*l*/,
- (char_u)MEM /*m*/, (char_u)NUN /*n*/, (char_u)SAMEH /*o*/,
- (char_u)PEI /*p*/, (char_u)-1 /*q*/, (char_u)RESH /*r*/,
- (char_u)ZAIN /*s*/, (char_u)TAV /*t*/, (char_u)TET /*u*/,
- (char_u)VAV /*v*/, (char_u)hSHIN /*w*/, (char_u)-1 /*x*/,
- (char_u)AIN /*y*/, (char_u)ZADI /*z*/ };
+ static char_u map[26] = {
+ (char_u)hALEF, // a
+ (char_u)BET, // b
+ (char_u)hKAF, // c
+ (char_u)DALET, // d
+ (char_u)-1, // e
+ (char_u)PEIsofit, // f
+ (char_u)GIMEL, // g
+ (char_u)HEI, // h
+ (char_u)IUD, // i
+ (char_u)HET, // j
+ (char_u)KOF, // k
+ (char_u)LAMED, // l
+ (char_u)MEM, // m
+ (char_u)NUN, // n
+ (char_u)SAMEH, // o
+ (char_u)PEI, // p
+ (char_u)-1, // q
+ (char_u)RESH, // r
+ (char_u)ZAIN, // s
+ (char_u)TAV, // t
+ (char_u)TET, // u
+ (char_u)VAV, // v
+ (char_u)hSHIN, // w
+ (char_u)-1, // x
+ (char_u)AIN, // y
+ (char_u)ZADI, // z
+ };
if (c == 'N' || c == 'M' || c == 'P' || c == 'C' || c == 'Z') {
return (int)(map[CharOrd(c)] - 1 + p_aleph);
@@ -7683,7 +7768,7 @@ int hkmap(int c)
case ';':
c = 't'; break;
default: {
- static char str[] = "zqbcxlsjphmkwonu ydafe rig";
+ static char_u str[] = "zqbcxlsjphmkwonu ydafe rig";
if (c < 'a' || c > 'z') {
return c;
@@ -7951,7 +8036,7 @@ static bool ins_esc(long *count, int cmdchar, bool nomove)
&& !VIsual_active
))
&& !revins_on) {
- if (curwin->w_cursor.coladd > 0 || ve_flags == VE_ALL) {
+ if (curwin->w_cursor.coladd > 0 || get_ve_flags() == VE_ALL) {
oneleft();
if (restart_edit != NUL) {
curwin->w_cursor.coladd++;
@@ -7965,8 +8050,11 @@ static bool ins_esc(long *count, int cmdchar, bool nomove)
State = NORMAL;
- // need to position cursor again (e.g. when on a TAB )
- changed_cline_bef_curs();
+ may_trigger_modechanged();
+ // need to position cursor again when on a TAB
+ if (gchar_cursor() == TAB) {
+ curwin->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL);
+ }
setmouse();
ui_cursor_shape(); // may show different cursor shape
@@ -8066,6 +8154,7 @@ static void ins_insert(int replaceState)
} else {
State = replaceState | (State & LANGMAP);
}
+ may_trigger_modechanged();
AppendCharToRedobuff(K_INS);
showmode();
ui_cursor_shape(); // may show different cursor shape
@@ -8202,6 +8291,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
int in_indent;
int oldState;
int cpc[MAX_MCO]; // composing characters
+ bool call_fix_indent = false;
// can't delete anything in an empty file
// can't backup past first character in buffer
@@ -8211,7 +8301,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
|| (!revins_on
&& ((curwin->w_cursor.lnum == 1 && curwin->w_cursor.col == 0)
|| (!can_bs(BS_START)
- && (arrow_used
+ && ((arrow_used && !bt_prompt(curbuf))
|| (curwin->w_cursor.lnum == Insstart_orig.lnum
&& curwin->w_cursor.col <= Insstart_orig.col)))
|| (!can_bs(BS_INDENT) && !arrow_used && ai_col > 0
@@ -8345,6 +8435,8 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
beginline(BL_WHITE);
if (curwin->w_cursor.col < save_col) {
mincol = curwin->w_cursor.col;
+ // should now fix the indent to match with the previous line
+ call_fix_indent = true;
}
curwin->w_cursor.col = save_col;
}
@@ -8479,6 +8571,11 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
if (curwin->w_cursor.col <= 1) {
did_ai = false;
}
+
+ if (call_fix_indent) {
+ fix_indent();
+ }
+
// It's a little strange to put backspaces into the redo
// buffer, but it makes auto-indent a lot easier to deal
// with.
@@ -9093,7 +9190,7 @@ static bool ins_eol(int c)
AppendToRedobuff(NL_STR);
bool i = open_line(FORWARD,
has_format_option(FO_RET_COMS) ? OPENLINE_DO_COM : 0,
- old_indent);
+ old_indent, NULL);
old_indent = 0;
can_cindent = true;
// When inserting a line the cursor line must never be in a closed fold.
@@ -9163,7 +9260,7 @@ static int ins_digraph(void)
}
if (cc != ESC) {
AppendToRedobuff(CTRL_V_STR);
- c = getdigraph(c, cc, true);
+ c = digraph_get(c, cc, true);
clear_showcmd();
return c;
}