aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/edit.c
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2023-11-30 20:35:25 +0000
committerJosh Rahm <joshuarahm@gmail.com>2023-11-30 20:35:25 +0000
commit1b7b916b7631ddf73c38e3a0070d64e4636cb2f3 (patch)
treecd08258054db80bb9a11b1061bb091c70b76926a /src/nvim/edit.c
parenteaa89c11d0f8aefbb512de769c6c82f61a8baca3 (diff)
parent4a8bf24ac690004aedf5540fa440e788459e5e34 (diff)
downloadrneovim-1b7b916b7631ddf73c38e3a0070d64e4636cb2f3.tar.gz
rneovim-1b7b916b7631ddf73c38e3a0070d64e4636cb2f3.tar.bz2
rneovim-1b7b916b7631ddf73c38e3a0070d64e4636cb2f3.zip
Merge remote-tracking branch 'upstream/master' into aucmd_textputpostaucmd_textputpost
Diffstat (limited to 'src/nvim/edit.c')
-rw-r--r--src/nvim/edit.c698
1 files changed, 244 insertions, 454 deletions
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index 96df6a3044..71a12ea1b0 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -1,6 +1,3 @@
-// This is an open source non-commercial project. Dear PVS-Studio, please check
-// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-
// edit.c: functions for Insert mode
#include <assert.h>
@@ -10,8 +7,9 @@
#include <string.h>
#include <sys/types.h>
-#include "nvim/ascii.h"
+#include "nvim/ascii_defs.h"
#include "nvim/autocmd.h"
+#include "nvim/autocmd_defs.h"
#include "nvim/buffer.h"
#include "nvim/change.h"
#include "nvim/charset.h"
@@ -26,17 +24,18 @@
#include "nvim/extmark.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
+#include "nvim/func_attr.h"
#include "nvim/getchar.h"
#include "nvim/gettext.h"
#include "nvim/globals.h"
#include "nvim/grid.h"
-#include "nvim/highlight_defs.h"
+#include "nvim/highlight.h"
#include "nvim/highlight_group.h"
#include "nvim/indent.h"
#include "nvim/indent_c.h"
#include "nvim/insexpand.h"
#include "nvim/keycodes.h"
-#include "nvim/macros.h"
+#include "nvim/macros_defs.h"
#include "nvim/mapping.h"
#include "nvim/mark.h"
#include "nvim/mbyte.h"
@@ -48,11 +47,11 @@
#include "nvim/normal.h"
#include "nvim/ops.h"
#include "nvim/option.h"
+#include "nvim/option_vars.h"
#include "nvim/os/input.h"
#include "nvim/plines.h"
#include "nvim/popupmenu.h"
-#include "nvim/pos.h"
-#include "nvim/screen.h"
+#include "nvim/pos_defs.h"
#include "nvim/search.h"
#include "nvim/state.h"
#include "nvim/strings.h"
@@ -60,10 +59,10 @@
#include "nvim/terminal.h"
#include "nvim/textformat.h"
#include "nvim/textobject.h"
-#include "nvim/types.h"
+#include "nvim/types_defs.h"
#include "nvim/ui.h"
#include "nvim/undo.h"
-#include "nvim/vim.h"
+#include "nvim/vim_defs.h"
#include "nvim/window.h"
typedef struct insert_state {
@@ -73,7 +72,7 @@ typedef struct insert_state {
int cmdchar;
int cmdchar_todo; // cmdchar to handle once in init_prompt
int startln;
- long count;
+ int count;
int c;
int lastc;
int i;
@@ -138,7 +137,7 @@ static void insert_enter(InsertState *s)
did_restart_edit = restart_edit;
// sleep before redrawing, needed for "CTRL-O :" that results in an
// error message
- check_for_delay(true);
+ msg_check_for_delay(true);
// set Insstart_orig to Insstart
update_Insstart_orig = true;
@@ -194,7 +193,7 @@ static void insert_enter(InsertState *s)
}
}
- Insstart_textlen = (colnr_T)linetabsize(get_cursor_line_ptr());
+ Insstart_textlen = linetabsize_str(get_cursor_line_ptr());
Insstart_blank_vcol = MAXCOL;
if (!did_ai) {
@@ -232,8 +231,9 @@ static void insert_enter(InsertState *s)
may_trigger_modechanged();
stop_insert_mode = false;
- // need to position cursor again when on a TAB
- if (gchar_cursor() == TAB) {
+ // need to position cursor again when on a TAB and
+ // when on a char with inline virtual text
+ if (gchar_cursor() == TAB || curbuf->b_virt_text_inline > 0) {
curwin->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL);
}
@@ -355,6 +355,7 @@ static void insert_enter(InsertState *s)
ins_apply_autocmds(EVENT_INSERTLEAVE);
}
did_cursorhold = false;
+ curbuf->b_last_changedtick = buf_get_changedtick(curbuf);
}
static int insert_check(VimState *state)
@@ -394,6 +395,13 @@ static int insert_check(VimState *state)
Insstart_orig = Insstart;
}
+ if (curbuf->terminal) {
+ // Exit Insert mode and go to Terminal mode.
+ stop_insert_mode = true;
+ restart_edit = 'I';
+ stuffcharReadbuff(K_NOP);
+ }
+
if (stop_insert_mode && !ins_compl_active()) {
// ":stopinsert" used
s->count = 0;
@@ -523,10 +531,6 @@ static int insert_execute(VimState *state, int key)
did_cursorhold = true;
}
- if (p_hkmap && KeyTyped) {
- s->c = hkmap(s->c); // Hebrew mode mapping
- }
-
// Special handling of keys while the popup menu is visible or wanted
// and the cursor is still in the completed word. Only when there is
// a match, skip this when no matches were found.
@@ -558,10 +562,9 @@ static int insert_execute(VimState *state, int key)
if (ins_compl_accept_char(s->c)) {
// Trigger InsertCharPre.
char *str = do_insert_char_pre(s->c);
- char *p;
if (str != NULL) {
- for (p = str; *p != NUL; MB_PTR_ADV(p)) {
+ for (char *p = str; *p != NUL; MB_PTR_ADV(p)) {
ins_compl_addleader(utf_ptr2char(p));
}
xfree(str);
@@ -615,7 +618,9 @@ static int insert_execute(VimState *state, int key)
}
}
- s->c = do_digraph(s->c);
+ if (s->c != K_EVENT) {
+ s->c = do_digraph(s->c);
+ }
if ((s->c == Ctrl_V || s->c == Ctrl_Q) && ctrl_x_mode_cmdline()) {
insert_do_complete(s);
@@ -754,7 +759,7 @@ static int insert_handle_key(InsertState *s)
case Ctrl_A:
// For ^@ the trailing ESC will end the insert, unless there is an
// error.
- if (stuff_inserted(NUL, 1L, (s->c == Ctrl_A)) == FAIL
+ if (stuff_inserted(NUL, 1, (s->c == Ctrl_A)) == FAIL
&& s->c != Ctrl_A) {
return 0; // exit insert mode
}
@@ -880,14 +885,18 @@ static int insert_handle_key(InsertState *s)
case K_EVENT: // some event
state_handle_k_event();
+ // If CTRL-G U was used apply it to the next typed key.
+ if (dont_sync_undo == kTrue) {
+ dont_sync_undo = kNone;
+ }
goto check_pum;
- case K_COMMAND: // some command
+ case K_COMMAND: // <Cmd>command<CR>
do_cmdline(NULL, getcmdkeycmd, NULL, 0);
goto check_pum;
case K_LUA:
- map_execute_lua();
+ map_execute_lua(false);
check_pum:
// nvim_select_popupmenu_item() can be called from the handling of
@@ -1122,12 +1131,11 @@ normalchar:
if (!p_paste) {
// Trigger InsertCharPre.
char *str = do_insert_char_pre(s->c);
- char *p;
if (str != NULL) {
if (*str != NUL && stop_arrow() != FAIL) {
// Insert the new value of v:char literally.
- for (p = str; *p != NUL; MB_PTR_ADV(p)) {
+ for (char *p = str; *p != NUL; MB_PTR_ADV(p)) {
s->c = utf_ptr2char(p);
if (s->c == CAR || s->c == K_KENTER || s->c == NL) {
ins_eol(s->c);
@@ -1229,7 +1237,7 @@ static void insert_do_cindent(InsertState *s)
/// @param count repeat count for the command
///
/// @return true if a CTRL-O command caused the return (insert mode pending).
-bool edit(int cmdchar, bool startln, long count)
+bool edit(int cmdchar, bool startln, int count)
{
if (curbuf->terminal) {
if (ex_normal_busy) {
@@ -1252,12 +1260,14 @@ bool edit(int cmdchar, bool startln, long count)
// Don't allow changes in the buffer while editing the cmdline. The
// caller of getcmdline() may get confused.
// Don't allow recursive insert mode when busy with completion.
- if (textlock != 0 || ins_compl_active() || compl_busy || pum_visible()) {
+ // Allow in dummy buffers since they are only used internally
+ if (textlock != 0 || ins_compl_active() || compl_busy || pum_visible()
+ || expr_map_locked()) {
emsg(_(e_textlock));
return false;
}
- InsertState state, *s = &state;
+ InsertState s[1];
memset(s, 0, sizeof(InsertState));
s->state.execute = insert_execute;
s->state.check = insert_check;
@@ -1289,7 +1299,8 @@ void ins_redraw(bool ready)
// Trigger CursorMoved if the cursor moved. Not when the popup menu is
// visible, the command might delete it.
if (ready && has_event(EVENT_CURSORMOVEDI)
- && !equalpos(curwin->w_last_cursormoved, curwin->w_cursor)
+ && (last_cursormoved_win != curwin
+ || !equalpos(last_cursormoved, curwin->w_cursor))
&& !pum_visible()) {
// Need to update the screen first, to make sure syntax
// highlighting is correct after making a change (e.g., inserting
@@ -1302,12 +1313,13 @@ void ins_redraw(bool ready)
// getcurpos()
update_curswant();
ins_apply_autocmds(EVENT_CURSORMOVEDI);
- curwin->w_last_cursormoved = curwin->w_cursor;
+ last_cursormoved_win = curwin;
+ last_cursormoved = curwin->w_cursor;
}
- // Trigger TextChangedI if changedtick differs.
+ // Trigger TextChangedI if changedtick_i differs.
if (ready && has_event(EVENT_TEXTCHANGEDI)
- && curbuf->b_last_changedtick != buf_get_changedtick(curbuf)
+ && curbuf->b_last_changedtick_i != buf_get_changedtick(curbuf)
&& !pum_visible()) {
aco_save_T aco;
varnumber_T tick = buf_get_changedtick(curbuf);
@@ -1316,16 +1328,16 @@ void ins_redraw(bool ready)
aucmd_prepbuf(&aco, curbuf);
apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, false, curbuf);
aucmd_restbuf(&aco);
- curbuf->b_last_changedtick = buf_get_changedtick(curbuf);
+ curbuf->b_last_changedtick_i = 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
- // TextChangedI will need to trigger for backwards compatibility, thus use
- // different b_last_changedtick* variables.
+ // Trigger TextChangedP if changedtick_pum differs. When the popupmenu
+ // closes TextChangedI will need to trigger for backwards compatibility,
+ // thus use different b_last_changedtick* variables.
if (ready && has_event(EVENT_TEXTCHANGEDP)
&& curbuf->b_last_changedtick_pum != buf_get_changedtick(curbuf)
&& pum_visible()) {
@@ -1355,13 +1367,21 @@ void ins_redraw(bool ready)
curbuf->b_changed_invalid = false;
}
+ // Trigger SafeState if nothing is pending.
+ may_trigger_safestate(ready
+ && !ins_compl_active()
+ && !pum_visible());
+
pum_check_clear();
+ show_cursor_info_later(false);
if (must_redraw) {
update_screen();
- } else if (clear_cmdline || redraw_cmdline) {
- showmode(); // clear cmdline and show mode
+ } else {
+ redraw_statuslines();
+ if (clear_cmdline || redraw_cmdline || redraw_mode) {
+ showmode(); // clear cmdline and show mode
+ }
}
- show_cursor_info(false);
setcursor();
emsg_on_display = false; // may remove error message now
}
@@ -1369,7 +1389,6 @@ void ins_redraw(bool ready)
// Handle a CTRL-V or CTRL-Q typed in Insert mode.
static void ins_ctrl_v(void)
{
- int c;
bool did_putchar = false;
// may need to redraw when no more chars available now
@@ -1384,7 +1403,7 @@ static void ins_ctrl_v(void)
add_to_showcmd_c(Ctrl_V);
// Do not include modifiers into the key for CTRL-SHIFT-V.
- c = get_literal(mod_mask & MOD_MASK_SHIFT);
+ int c = get_literal(mod_mask & MOD_MASK_SHIFT);
if (did_putchar) {
// when the line fits in 'columns' the '^' is at the start of the next
// line and will not removed by the redraw
@@ -1399,20 +1418,19 @@ static void ins_ctrl_v(void)
// Put a character directly onto the screen. It's not stored in a buffer.
// Used while handling CTRL-K, CTRL-V, etc. in Insert mode.
static int pc_status;
-#define PC_STATUS_UNSET 0 // pc_bytes was not set
-#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
+#define PC_STATUS_UNSET 0 // nothing was put on screen
+#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_schar was filled
+static schar_T pc_schar; // saved char
static int pc_attr;
static int pc_row;
static int pc_col;
void edit_putchar(int c, bool highlight)
{
- int attr;
-
if (curwin->w_grid_alloc.chars != NULL || default_grid.chars != NULL) {
+ int attr;
update_topline(curwin); // just in case w_topline isn't valid
validate_cursor();
if (highlight) {
@@ -1421,30 +1439,34 @@ void edit_putchar(int c, bool highlight)
attr = 0;
}
pc_row = curwin->w_wrow;
- pc_col = 0;
pc_status = PC_STATUS_UNSET;
+ grid_line_start(&curwin->w_grid, pc_row);
if (curwin->w_p_rl) {
- pc_col += curwin->w_grid.cols - 1 - curwin->w_wcol;
- const int fix_col = grid_fix_col(&curwin->w_grid, pc_col, pc_row);
+ pc_col = curwin->w_grid.cols - 1 - curwin->w_wcol;
- if (fix_col != pc_col) {
- grid_putchar(&curwin->w_grid, ' ', pc_row, fix_col, attr);
+ if (grid_line_getchar(pc_col, NULL) == NUL) {
+ grid_line_put_schar(pc_col - 1, schar_from_ascii(' '), attr);
curwin->w_wcol--;
pc_status = PC_STATUS_RIGHT;
}
} else {
- pc_col += curwin->w_wcol;
- if (grid_lefthalve(&curwin->w_grid, pc_row, pc_col)) {
+ pc_col = curwin->w_wcol;
+
+ if (grid_line_getchar(pc_col + 1, NULL) == NUL) {
+ // pc_col is the left half of a double-width char
pc_status = PC_STATUS_LEFT;
}
}
// save the character to be able to put it back
if (pc_status == PC_STATUS_UNSET) {
- grid_getbytes(&curwin->w_grid, pc_row, pc_col, (char *)pc_bytes, &pc_attr);
+ pc_schar = grid_line_getchar(pc_col, &pc_attr);
pc_status = PC_STATUS_SET;
}
- grid_putchar(&curwin->w_grid, c, pc_row, pc_col, attr);
+
+ char buf[MB_MAXCHAR + 1];
+ grid_line_puts(pc_col, buf, utf_char2bytes(c, buf), attr);
+ grid_line_flush();
}
}
@@ -1470,10 +1492,9 @@ char *prompt_text(void)
static void init_prompt(int cmdchar_todo)
{
char *prompt = prompt_text();
- char *text;
curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
- text = get_cursor_line_ptr();
+ char *text = get_cursor_line_ptr();
if (strncmp(text, prompt, strlen(prompt)) != 0) {
// prompt is missing, insert it or append a line with it
if (*text == NUL) {
@@ -1517,29 +1538,32 @@ bool prompt_curpos_editable(void)
// Undo the previous edit_putchar().
void edit_unputchar(void)
{
- if (pc_status != PC_STATUS_UNSET && pc_row >= msg_scrolled) {
+ if (pc_status != PC_STATUS_UNSET) {
if (pc_status == PC_STATUS_RIGHT) {
curwin->w_wcol++;
}
if (pc_status == PC_STATUS_RIGHT || pc_status == PC_STATUS_LEFT) {
redrawWinline(curwin, curwin->w_cursor.lnum);
} else {
- grid_puts(&curwin->w_grid, (char *)pc_bytes, pc_row - msg_scrolled, pc_col, pc_attr);
+ // TODO(bfredl): this could be smarter and also handle the dubyawidth case
+ grid_line_start(&curwin->w_grid, pc_row);
+ grid_line_put_schar(pc_col, pc_schar, pc_attr);
+ grid_line_flush();
}
}
}
-// Called when p_dollar is set: display a '$' at the end of the changed text
-// Only works when cursor is in the line that changes.
-void display_dollar(colnr_T col)
+/// Called when "$" is in 'cpoptions': display a '$' at the end of the changed
+/// text. Only works when cursor is in the line that changes.
+void display_dollar(colnr_T col_arg)
{
- colnr_T save_col;
+ colnr_T col = col_arg < 0 ? 0 : col_arg;
if (!redrawing()) {
return;
}
- save_col = curwin->w_cursor.col;
+ colnr_T save_col = curwin->w_cursor.col;
curwin->w_cursor.col = col;
// If on the last byte of a multi-byte move to the first byte.
@@ -1574,16 +1598,9 @@ void undisplay_dollar(void)
/// @param call_changed_bytes call changed_bytes()
void change_indent(int type, int amount, int round, int replaced, int call_changed_bytes)
{
- int vcol;
- int last_vcol;
int insstart_less; // reduction for Insstart.col
- int new_cursor_col;
- char *ptr;
- int save_p_list;
- int start_col;
- colnr_T vc;
colnr_T orig_col = 0; // init for GCC
- char *new_line, *orig_line = NULL; // init for GCC
+ char *orig_line = NULL; // init for GCC
// MODE_VREPLACE state needs to know what the line was like before changing
if (State & VREPLACE_FLAG) {
@@ -1592,18 +1609,18 @@ void change_indent(int type, int amount, int round, int replaced, int call_chang
}
// for the following tricks we don't want list mode
- save_p_list = curwin->w_p_list;
+ int save_p_list = curwin->w_p_list;
curwin->w_p_list = false;
- vc = getvcol_nolist(&curwin->w_cursor);
- vcol = vc;
+ colnr_T vc = getvcol_nolist(&curwin->w_cursor);
+ int vcol = vc;
// For Replace mode we need to fix the replace stack later, which is only
// possible when the cursor is in the indent. Remember the number of
// characters before the cursor if it's possible.
- start_col = curwin->w_cursor.col;
+ int start_col = curwin->w_cursor.col;
// determine offset from first non-blank
- new_cursor_col = curwin->w_cursor.col;
+ int new_cursor_col = curwin->w_cursor.col;
beginline(BL_WHITE);
new_cursor_col -= curwin->w_cursor.col;
@@ -1656,8 +1673,8 @@ void change_indent(int type, int amount, int round, int replaced, int call_chang
curwin->w_virtcol = (colnr_T)((vcol < 0) ? 0 : vcol);
// Advance the cursor until we reach the right screen column.
- last_vcol = 0;
- ptr = get_cursor_line_ptr();
+ int last_vcol = 0;
+ char *ptr = get_cursor_line_ptr();
chartabsize_T cts;
init_chartabsize_arg(&cts, curwin, 0, 0, ptr, ptr);
while (cts.cts_vcol <= (int)curwin->w_virtcol) {
@@ -1699,7 +1716,7 @@ void change_indent(int type, int amount, int round, int replaced, int call_chang
curwin->w_cursor.col = (colnr_T)new_cursor_col;
}
curwin->w_set_curswant = true;
- changed_cline_bef_curs();
+ changed_cline_bef_curs(curwin);
// May have to adjust the start of the insert.
if (State & MODE_INSERT) {
@@ -1742,7 +1759,7 @@ void change_indent(int type, int amount, int round, int replaced, int call_chang
// then put it back again the way we wanted it.
if (State & VREPLACE_FLAG) {
// Save new line
- new_line = xstrdup(get_cursor_line_ptr());
+ char *new_line = xstrdup(get_cursor_line_ptr());
// We only put back the new line up to the cursor
new_line[curwin->w_cursor.col] = NUL;
@@ -1847,9 +1864,7 @@ static bool del_char_after_col(int limit_col)
/// @param no_simplify do not include modifiers into the key
int get_literal(bool no_simplify)
{
- int cc;
int nc;
- int i;
bool hex = false;
bool octal = false;
int unicode = 0;
@@ -1859,9 +1874,9 @@ int get_literal(bool no_simplify)
}
no_mapping++; // don't map the next key hits
- cc = 0;
- i = 0;
- for (;;) {
+ int cc = 0;
+ int i = 0;
+ while (true) {
nc = plain_vgetc();
if (!no_simplify) {
nc = merge_modifiers(nc, &mod_mask);
@@ -1949,9 +1964,6 @@ int get_literal(bool no_simplify)
/// @param ctrlv `c` was typed after CTRL-V
static void insert_special(int c, int allow_modmask, int ctrlv)
{
- char *p;
- int len;
-
// Special function key, translate into "<Key>". Up to the last '>' is
// inserted with ins_str(), so as not to replace characters in replace
// mode.
@@ -1961,8 +1973,8 @@ static void insert_special(int c, int allow_modmask, int ctrlv)
allow_modmask = true;
}
if (IS_SPECIAL(c) || (mod_mask && allow_modmask)) {
- p = (char *)get_special_key_name(c, mod_mask);
- len = (int)strlen(p);
+ char *p = get_special_key_name(c, mod_mask);
+ int len = (int)strlen(p);
c = (uint8_t)p[len - 1];
if (len > 2) {
if (stop_arrow() == FAIL) {
@@ -2041,7 +2053,7 @@ void insertchar(int c, int flags, int second_indent)
if (*curbuf->b_p_fex != NUL && (flags & INSCHAR_NO_FEX) == 0
&& (force_format || virtcol > (colnr_T)textwidth)) {
- do_internal = (fex_format(curwin->w_cursor.lnum, 1L, c) != 0);
+ do_internal = (fex_format(curwin->w_cursor.lnum, 1, c) != 0);
// It may be required to save for undo again, e.g. when setline()
// was called.
ins_need_undo = true;
@@ -2057,7 +2069,7 @@ void insertchar(int c, int flags, int second_indent)
// Check whether this character should end a comment.
if (did_ai && c == end_comment_pending) {
- char_u lead_end[COM_MAX_LEN]; // end-comment string
+ char lead_end[COM_MAX_LEN]; // end-comment string
// Need to remove existing (middle) comment leader and insert end
// comment leader. First, check what comment leader we can find.
@@ -2068,7 +2080,7 @@ void insertchar(int c, int flags, int second_indent)
while (*p && p[-1] != ':') { // find end of middle flags
p++;
}
- int middle_len = (int)copy_option_part(&p, (char *)lead_end, COM_MAX_LEN, ",");
+ int middle_len = (int)copy_option_part(&p, lead_end, COM_MAX_LEN, ",");
// Don't count trailing white space for middle_len
while (middle_len > 0 && ascii_iswhite(lead_end[middle_len - 1])) {
middle_len--;
@@ -2078,7 +2090,7 @@ void insertchar(int c, int flags, int second_indent)
while (*p && p[-1] != ':') { // find end of end flags
p++;
}
- int end_len = (int)copy_option_part(&p, (char *)lead_end, COM_MAX_LEN, ",");
+ int end_len = (int)copy_option_part(&p, lead_end, COM_MAX_LEN, ",");
// Skip white space before the cursor
i = curwin->w_cursor.col;
@@ -2089,13 +2101,13 @@ void insertchar(int c, int flags, int second_indent)
i -= middle_len;
// Check some expected things before we go on
- if (i >= 0 && lead_end[end_len - 1] == end_comment_pending) {
+ if (i >= 0 && (uint8_t)lead_end[end_len - 1] == end_comment_pending) {
// Backspace over all the stuff we want to replace
backspace_until_column(i);
// Insert the end-comment string, except for the last
// character, which will get inserted as normal later.
- ins_bytes_len((char *)lead_end, (size_t)(end_len - 1));
+ ins_bytes_len(lead_end, (size_t)(end_len - 1));
}
}
}
@@ -2146,9 +2158,6 @@ void insertchar(int c, int flags, int second_indent)
|| (virtcol += byte2cells((uint8_t)buf[i - 1])) < (colnr_T)textwidth)
&& !(!no_abbr && !vim_iswordc(c) && vim_iswordc((uint8_t)buf[i - 1]))) {
c = vgetc();
- if (p_hkmap && KeyTyped) {
- c = hkmap(c); // Hebrew mode mapping
- }
buf[i++] = (char)c;
}
@@ -2169,7 +2178,7 @@ void insertchar(int c, int flags, int second_indent)
int cc;
if ((cc = utf_char2len(c)) > 1) {
- char buf[MB_MAXBYTES + 1];
+ char buf[MB_MAXCHAR + 1];
utf_char2bytes(c, buf);
buf[cc] = NUL;
@@ -2260,7 +2269,7 @@ int stop_arrow(void)
// right, except when nothing was inserted yet.
update_Insstart_orig = false;
}
- Insstart_textlen = (colnr_T)linetabsize(get_cursor_line_ptr());
+ Insstart_textlen = linetabsize_str(get_cursor_line_ptr());
if (u_save_cursor() == OK) {
arrow_used = false;
@@ -2294,26 +2303,24 @@ int stop_arrow(void)
/// @param nomove <c-\><c-o>, don't move cursor
static void stop_insert(pos_T *end_insert_pos, int esc, int nomove)
{
- int cc;
- char *ptr;
-
stop_redo_ins();
replace_flush(); // abandon replace stack
// Save the inserted text for later redo with ^@ and CTRL-A.
// Don't do it when "restart_edit" was set and nothing was inserted,
// otherwise CTRL-O w and then <Left> will clear "last_insert".
- ptr = get_inserted();
- if (did_restart_edit == 0 || (ptr != NULL
- && (int)strlen(ptr) > new_insert_skip)) {
+ char *ptr = get_inserted();
+ int added = ptr == NULL ? 0 : (int)strlen(ptr) - new_insert_skip;
+ if (did_restart_edit == 0 || added > 0) {
xfree(last_insert);
last_insert = ptr;
- last_insert_skip = new_insert_skip;
+ last_insert_skip = added < 0 ? 0 : new_insert_skip;
} else {
xfree(ptr);
}
if (!arrow_used && end_insert_pos != NULL) {
+ int cc;
// Auto-format now. It may seem strange to do this when stopping an
// insertion (or moving the cursor), but it's required when appending
// a line and having it end in a space. But only do it when something
@@ -2365,7 +2372,7 @@ static void stop_insert(pos_T *end_insert_pos, int esc, int nomove)
curwin->w_cursor = *end_insert_pos;
check_cursor_col(); // make sure it is not past the line
- for (;;) {
+ while (true) {
if (gchar_cursor() == NUL && curwin->w_cursor.col > 0) {
curwin->w_cursor.col--;
}
@@ -2413,16 +2420,14 @@ static void stop_insert(pos_T *end_insert_pos, int esc, int nomove)
// Used for the replace command.
void set_last_insert(int c)
{
- char *s;
-
xfree(last_insert);
last_insert = xmalloc(MB_MAXBYTES * 3 + 5);
- s = last_insert;
+ char *s = last_insert;
// Use the CTRL-V only when entering a special char
if (c < ' ' || c == DEL) {
*s++ = Ctrl_V;
}
- s = (char *)add_char2buf(c, (char_u *)s);
+ s = add_char2buf(c, s);
*s++ = ESC;
*s++ = NUL;
last_insert_skip = 0;
@@ -2449,15 +2454,16 @@ void beginline(int flags)
curwin->w_cursor.coladd = 0;
if (flags & (BL_WHITE | BL_SOL)) {
- char_u *ptr;
+ char *ptr;
- for (ptr = (char_u *)get_cursor_line_ptr(); ascii_iswhite(*ptr)
+ for (ptr = get_cursor_line_ptr(); ascii_iswhite(*ptr)
&& !((flags & BL_FIX) && ptr[1] == NUL); ptr++) {
curwin->w_cursor.col++;
}
}
curwin->w_set_curswant = true;
}
+ adjust_skipcol();
}
// oneright oneleft cursor_down cursor_up
@@ -2469,15 +2475,14 @@ void beginline(int flags)
int oneright(void)
{
char *ptr;
- int l;
if (virtual_active()) {
pos_T prevpos = curwin->w_cursor;
// Adjust for multi-wide char (excluding TAB)
ptr = get_cursor_pos_ptr();
- coladvance(getviscol() + ((*ptr != TAB && vim_isprintc(utf_ptr2char(ptr))) ?
- ptr2cells(ptr) : 1));
+ coladvance(getviscol() + ((*ptr != TAB && vim_isprintc(utf_ptr2char(ptr)))
+ ? ptr2cells(ptr) : 1));
curwin->w_set_curswant = true;
// Return OK if the cursor moved, FAIL otherwise (at window edge).
return (prevpos.col != curwin->w_cursor.col
@@ -2489,7 +2494,7 @@ int oneright(void)
return FAIL; // already at the very end
}
- l = utfc_ptr2len(ptr);
+ int l = utfc_ptr2len(ptr);
// move "l" bytes right, but don't end up on the NUL, unless 'virtualedit'
// contains "onemore".
@@ -2499,13 +2504,13 @@ int oneright(void)
curwin->w_cursor.col += l;
curwin->w_set_curswant = true;
+ adjust_skipcol();
return OK;
}
int oneleft(void)
{
if (virtual_active()) {
- int width;
int v = getviscol();
if (v == 0) {
@@ -2513,8 +2518,8 @@ int oneleft(void)
}
// We might get stuck on 'showbreak', skip over it.
- width = 1;
- for (;;) {
+ int width = 1;
+ while (true) {
coladvance(v - width);
// getviscol() is slow, skip it when 'showbreak' is empty,
// 'breakindent' is not set and there are no multi-byte
@@ -2534,6 +2539,7 @@ int oneleft(void)
}
curwin->w_set_curswant = true;
+ adjust_skipcol();
return OK;
}
@@ -2547,20 +2553,16 @@ int oneleft(void)
// if the character on the left of the current cursor is a multi-byte
// character, move to its first byte
mb_adjust_cursor();
+ adjust_skipcol();
return OK;
}
/// Move the cursor up "n" lines in window "wp".
/// Takes care of closed folds.
-/// Returns the new cursor line or zero for failure.
-linenr_T cursor_up_inner(win_T *wp, long n)
+void cursor_up_inner(win_T *wp, linenr_T n)
{
linenr_T lnum = wp->w_cursor.lnum;
- // This fails if the cursor is already in the first line.
- if (lnum <= 1) {
- return 0;
- }
if (n >= lnum) {
lnum = 1;
} else if (hasAnyFolding(wp)) {
@@ -2586,19 +2588,20 @@ linenr_T cursor_up_inner(win_T *wp, long n)
lnum = 1;
}
} else {
- lnum -= (linenr_T)n;
+ lnum -= n;
}
wp->w_cursor.lnum = lnum;
- return lnum;
}
/// @param upd_topline When true: update topline
-int cursor_up(long n, int upd_topline)
+int cursor_up(linenr_T n, int upd_topline)
{
- if (n > 0 && cursor_up_inner(curwin, n) == 0) {
+ // This fails if the cursor is already in the first line.
+ if (n > 0 && curwin->w_cursor.lnum <= 1) {
return FAIL;
}
+ cursor_up_inner(curwin, n);
// try to advance to the column we want to be at
coladvance(curwin->w_curswant);
@@ -2612,18 +2615,11 @@ int cursor_up(long n, int upd_topline)
/// Move the cursor down "n" lines in window "wp".
/// Takes care of closed folds.
-/// Returns the new cursor line or zero for failure.
-linenr_T cursor_down_inner(win_T *wp, long n)
+void cursor_down_inner(win_T *wp, int n)
{
linenr_T lnum = wp->w_cursor.lnum;
linenr_T line_count = wp->w_buffer->b_ml.ml_line_count;
- // Move to last line of fold, will fail if it's the end-of-file.
- (void)hasFoldingWin(wp, lnum, NULL, &lnum, true, NULL);
- // This fails if the cursor is already in the last line.
- if (lnum >= line_count) {
- return FAIL;
- }
if (lnum + n >= line_count) {
lnum = line_count;
} else if (hasAnyFolding(wp)) {
@@ -2631,6 +2627,7 @@ linenr_T cursor_down_inner(win_T *wp, long n)
// count each sequence of folded lines as one logical line
while (n--) {
+ // Move to last line of fold, will fail if it's the end-of-file.
if (hasFoldingWin(wp, lnum, NULL, &last, true, NULL)) {
lnum = last + 1;
} else {
@@ -2648,15 +2645,16 @@ linenr_T cursor_down_inner(win_T *wp, long n)
}
wp->w_cursor.lnum = lnum;
- return lnum;
}
/// @param upd_topline When true: update topline
-int cursor_down(long n, int upd_topline)
+int cursor_down(int n, int upd_topline)
{
- if (n > 0 && cursor_down_inner(curwin, n) == 0) {
+ // This fails if the cursor is already in the last line.
+ if (n > 0 && curwin->w_cursor.lnum >= curwin->w_buffer->b_ml.ml_line_count) {
return FAIL;
}
+ cursor_down_inner(curwin, n);
// try to advance to the column we want to be at
coladvance(curwin->w_curswant);
@@ -2675,14 +2673,12 @@ int cursor_down(long n, int upd_topline)
/// @param c Command character to be inserted
/// @param count Repeat this many times
/// @param no_esc Don't add an ESC at the end
-int stuff_inserted(int c, long count, int no_esc)
+int stuff_inserted(int c, int count, int no_esc)
{
char *esc_ptr;
- char *ptr;
- char *last_ptr;
char last = NUL;
- ptr = (char *)get_last_insert();
+ char *ptr = get_last_insert();
if (ptr == NULL) {
emsg(_(e_noinstext));
return FAIL;
@@ -2700,7 +2696,7 @@ int stuff_inserted(int c, long count, int no_esc)
// when the last char is either "0" or "^" it will be quoted if no ESC
// comes after it OR if it will inserted more than once and "ptr"
// starts with ^D. -- Acevedo
- last_ptr = (esc_ptr ? esc_ptr : ptr + strlen(ptr)) - 1;
+ char *last_ptr = (esc_ptr ? esc_ptr : ptr + strlen(ptr)) - 1;
if (last_ptr >= ptr && (*last_ptr == '0' || *last_ptr == '^')
&& (no_esc || (*ptr == Ctrl_D && count > 1))) {
last = *last_ptr;
@@ -2708,7 +2704,7 @@ int stuff_inserted(int c, long count, int no_esc)
}
do {
- stuffReadbuff((const char *)ptr);
+ stuffReadbuff(ptr);
// A trailing "0" is inserted as "<C-V>048", "^" as "<C-V>^".
if (last) {
stuffReadbuff(last == '0' ? "\026\060\064\070" : "\026^");
@@ -2731,27 +2727,24 @@ int stuff_inserted(int c, long count, int no_esc)
return OK;
}
-char_u *get_last_insert(void)
+char *get_last_insert(void)
FUNC_ATTR_PURE
{
if (last_insert == NULL) {
return NULL;
}
- return (char_u *)last_insert + last_insert_skip;
+ return last_insert + last_insert_skip;
}
// Get last inserted string, and remove trailing <Esc>.
// Returns pointer to allocated memory (must be freed) or NULL.
char *get_last_insert_save(void)
{
- char *s;
- int len;
-
if (last_insert == NULL) {
return NULL;
}
- s = xstrdup(last_insert + last_insert_skip);
- len = (int)strlen(s);
+ char *s = xstrdup(last_insert + last_insert_skip);
+ int len = (int)strlen(s);
if (len > 0 && s[len - 1] == ESC) { // remove trailing ESC
s[len - 1] = NUL;
}
@@ -2793,11 +2786,11 @@ static bool echeck_abbr(int c)
// that the NL replaced. The extra one stores the characters after the cursor
// that were deleted (always white space).
-static char_u *replace_stack = NULL;
+static uint8_t *replace_stack = NULL;
static ssize_t replace_stack_nr = 0; // next entry in replace stack
static ssize_t replace_stack_len = 0; // max. number of entries
-/// Push character that is replaced onto the the replace stack.
+/// Push character that is replaced onto the replace stack.
///
/// replace_offset is normally 0, in which case replace_push will add a new
/// character at the end of the stack. If replace_offset is not 0, that many
@@ -2814,11 +2807,11 @@ void replace_push(int c)
replace_stack_len += 50;
replace_stack = xrealloc(replace_stack, (size_t)replace_stack_len);
}
- char_u *p = replace_stack + replace_stack_nr - replace_offset;
+ uint8_t *p = replace_stack + replace_stack_nr - replace_offset;
if (replace_offset) {
memmove(p + 1, p, (size_t)replace_offset);
}
- *p = (char_u)c;
+ *p = (uint8_t)c;
replace_stack_nr++;
}
@@ -2829,9 +2822,8 @@ void replace_push(int c)
int replace_push_mb(char *p)
{
int l = utfc_ptr2len(p);
- int j;
- for (j = l - 1; j >= 0; j--) {
+ for (int j = l - 1; j >= 0; j--) {
replace_push(p[j]);
}
return l;
@@ -2881,14 +2873,12 @@ static void replace_pop_ins(void)
static void mb_replace_pop_ins(int cc)
{
int n;
- char_u buf[MB_MAXBYTES + 1];
- int i;
- int c;
+ uint8_t buf[MB_MAXBYTES + 1];
if ((n = MB_BYTE2LEN(cc)) > 1) {
- buf[0] = (char_u)cc;
- for (i = 1; i < n; i++) {
- buf[i] = (char_u)replace_pop();
+ buf[0] = (uint8_t)cc;
+ for (int i = 1; i < n; i++) {
+ buf[i] = (uint8_t)replace_pop();
}
ins_bytes_len((char *)buf, (size_t)n);
} else {
@@ -2896,8 +2886,8 @@ static void mb_replace_pop_ins(int cc)
}
// Handle composing chars.
- for (;;) {
- c = replace_pop();
+ while (true) {
+ int c = replace_pop();
if (c == -1) { // stack empty
break;
}
@@ -2907,16 +2897,16 @@ static void mb_replace_pop_ins(int cc)
break;
}
- buf[0] = (char_u)c;
+ buf[0] = (uint8_t)c;
assert(n > 1);
- for (i = 1; i < n; i++) {
- buf[i] = (char_u)replace_pop();
+ for (int i = 1; i < n; i++) {
+ buf[i] = (uint8_t)replace_pop();
}
if (utf_iscomposing(utf_ptr2char((char *)buf))) {
ins_bytes_len((char *)buf, (size_t)n);
} else {
// Not a composing char, put it back.
- for (i = n - 1; i >= 0; i--) {
+ for (int i = n - 1; i >= 0; i--) {
replace_push(buf[i]);
}
break;
@@ -2942,18 +2932,13 @@ static void replace_flush(void)
// using composing characters, use del_char_after_col() instead of del_char().
static void replace_do_bs(int limit_col)
{
- int cc;
- int orig_len = 0;
- int ins_len;
- int orig_vcols = 0;
colnr_T start_vcol;
- char *p;
- int i;
- int vcol;
const int l_State = State;
- cc = replace_pop();
+ int cc = replace_pop();
if (cc > 0) {
+ int orig_len = 0;
+ int orig_vcols = 0;
if (l_State & VREPLACE_FLAG) {
// Get the number of screen cells used by the character we are
// going to delete.
@@ -2969,10 +2954,10 @@ static void replace_do_bs(int limit_col)
if (l_State & VREPLACE_FLAG) {
// Get the number of screen cells used by the inserted characters
- p = get_cursor_pos_ptr();
- ins_len = (int)strlen(p) - orig_len;
- vcol = start_vcol;
- for (i = 0; i < ins_len; i++) {
+ char *p = get_cursor_pos_ptr();
+ int ins_len = (int)strlen(p) - orig_len;
+ int vcol = start_vcol;
+ for (int i = 0; i < ins_len; i++) {
vcol += win_chartabsize(curwin, p + i, vcol);
i += utfc_ptr2len(p) - 1;
}
@@ -3131,7 +3116,7 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty)
return true;
}
- if (keytyped == get_special_key_code((char_u *)look + 1)) {
+ if (keytyped == get_special_key_code(look + 1)) {
return true;
}
}
@@ -3223,105 +3208,9 @@ bool in_cinkeys(int keytyped, int when, bool line_is_empty)
return false;
}
-// Map Hebrew keyboard when in hkmap mode.
-int hkmap(int c)
- FUNC_ATTR_PURE
-{
- if (p_hkmapp) { // phonetic mapping, by Ilya Dogolazky
- enum {
- hALEF = 0, BET, GIMEL, DALET, HEI, VAV, ZAIN, HET, TET, IUD,
- 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
- };
-
- if (c == 'N' || c == 'M' || c == 'P' || c == 'C' || c == 'Z') {
- return (int)(map[CHAR_ORD(c)] - 1 + p_aleph);
- } else if (c == 'x') { // '-1'='sofit'
- return 'X';
- } else if (c == 'q') {
- return '\''; // {geresh}={'}
- } else if (c == 246) {
- return ' '; // \"o --> ' ' for a german keyboard
- } else if (c == 228) {
- return ' '; // \"a --> ' ' -- / --
- } else if (c == 252) {
- return ' '; // \"u --> ' ' -- / --
- } else if (c >= 'a' && c <= 'z') {
- // NOTE: islower() does not do the right thing for us on Linux so we
- // do this the same was as 5.7 and previous, so it works correctly on
- // all systems. Specifically, the e.g. Delete and Arrow keys are
- // munged and won't work if e.g. searching for Hebrew text.
- return (int)(map[CHAR_ORD_LOW(c)] + p_aleph);
- } else {
- return c;
- }
- } else {
- switch (c) {
- case '`':
- return ';';
- case '/':
- return '.';
- case '\'':
- return ',';
- case 'q':
- return '/';
- case 'w':
- return '\'';
-
- // Hebrew letters - set offset from 'a'
- case ',':
- c = '{'; break;
- case '.':
- c = 'v'; break;
- case ';':
- c = 't'; break;
- default: {
- static char_u str[] = "zqbcxlsjphmkwonu ydafe rig";
-
- if (c < 'a' || c > 'z') {
- return c;
- }
- c = str[CHAR_ORD_LOW(c)];
- break;
- }
- }
-
- return (int)(CHAR_ORD_LOW(c) + p_aleph);
- }
-}
-
static void ins_reg(void)
{
bool need_redraw = false;
- int regname;
int literally = 0;
int vis_active = VIsual_active;
@@ -3339,7 +3228,7 @@ static void ins_reg(void)
// deleted when ESC is hit.
no_mapping++;
allow_keys++;
- regname = plain_vgetc();
+ int regname = plain_vgetc();
LANGMAP_ADJUST(regname, true);
if (regname == Ctrl_R || regname == Ctrl_O || regname == Ctrl_P) {
// Get a third key for literal register insertion
@@ -3410,8 +3299,6 @@ static void ins_reg(void)
// CTRL-G commands in Insert mode.
static void ins_ctrl_g(void)
{
- int c;
-
// Right after CTRL-X the cursor will be after the ruler.
setcursor();
@@ -3419,7 +3306,7 @@ static void ins_ctrl_g(void)
// deleted when ESC is hit.
no_mapping++;
allow_keys++;
- c = plain_vgetc();
+ int c = plain_vgetc();
no_mapping--;
allow_keys--;
switch (c) {
@@ -3455,6 +3342,10 @@ static void ins_ctrl_g(void)
dont_sync_undo = kNone;
break;
+ case ESC:
+ // Esc after CTRL-G cancels it.
+ break;
+
// Unknown CTRL-G command, reserved for future expansion.
default:
vim_beep(BO_CTRLG);
@@ -3487,7 +3378,7 @@ static void ins_ctrl_hat(void)
/// @param nomove when true, don't move the cursor
///
/// @return true when leaving insert mode, false when repeating the insert.
-static bool ins_esc(long *count, int cmdchar, bool nomove)
+static bool ins_esc(int *count, int cmdchar, bool nomove)
FUNC_ATTR_NONNULL_ARG(1)
{
static bool disabled_redraw = false;
@@ -3562,6 +3453,7 @@ static bool ins_esc(long *count, int cmdchar, bool nomove)
}
} else {
curwin->w_cursor.col--;
+ curwin->w_valid &= ~(VALID_WCOL|VALID_VIRTCOL);
// Correct cursor for multi-byte character.
mb_adjust_cursor();
}
@@ -3569,8 +3461,9 @@ static bool ins_esc(long *count, int cmdchar, bool nomove)
State = MODE_NORMAL;
may_trigger_modechanged();
- // need to position cursor again when on a TAB
- if (gchar_cursor() == TAB) {
+ // need to position cursor again when on a TAB and
+ // when on a char with inline virtual text
+ if (gchar_cursor() == TAB || curbuf->b_virt_text_inline > 0) {
curwin->w_valid &= ~(VALID_WROW|VALID_WCOL|VALID_VIRTCOL);
}
@@ -3581,14 +3474,15 @@ static bool ins_esc(long *count, int cmdchar, bool nomove)
// Otherwise remove the mode message.
if (reg_recording != 0 || restart_edit != NUL) {
showmode();
- } else if (p_smd && (got_int || !skip_showmode())) {
- msg("");
+ } else if (p_smd && (got_int || !skip_showmode())
+ && !(p_ch == 0 && !ui_has(kUIMessages))) {
+ msg("", 0);
}
// Exit Insert mode
return true;
}
-// Toggle language: hkmap and revins_on.
+// Toggle language: revins_on.
// Move to end of reverse inserted text.
static void ins_ctrl_(void)
{
@@ -3607,7 +3501,6 @@ static void ins_ctrl_(void)
} else {
revins_scol = -1;
}
- p_hkmap = curwin->w_p_rl ^ p_ri; // be consistent!
showmode();
}
@@ -3659,8 +3552,9 @@ static bool ins_start_select(int c)
// <Insert> key in Insert mode: toggle insert/replace mode.
static void ins_insert(int replaceState)
{
- set_vim_var_string(VV_INSERTMODE, ((State & REPLACE_FLAG) ? "i" :
- replaceState == MODE_VREPLACE ? "v" : "r"), 1);
+ set_vim_var_string(VV_INSERTMODE, ((State & REPLACE_FLAG)
+ ? "i"
+ : replaceState == MODE_VREPLACE ? "v" : "r"), 1);
ins_apply_autocmds(EVENT_INSERTCHANGE);
if (State & REPLACE_FLAG) {
State = MODE_INSERT | (State & MODE_LANGMAP);
@@ -3676,6 +3570,7 @@ static void ins_insert(int replaceState)
// Pressed CTRL-O in Insert mode.
static void ins_ctrl_o(void)
{
+ restart_VIsual_select = 0;
if (State & VREPLACE_FLAG) {
restart_edit = 'V';
} else if (State & REPLACE_FLAG) {
@@ -3786,15 +3681,9 @@ static void ins_bs_one(colnr_T *vcolp)
static bool ins_bs(int c, int mode, int *inserted_space_p)
FUNC_ATTR_NONNULL_ARG(3)
{
- linenr_T lnum;
int cc;
int temp = 0; // init for GCC
- colnr_T save_col;
- colnr_T mincol;
bool did_backspace = false;
- int in_indent;
- int oldState;
- int cpc[MAX_MCO]; // composing characters
bool call_fix_indent = false;
// can't delete anything in an empty file
@@ -3818,7 +3707,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
if (stop_arrow() == FAIL) {
return false;
}
- in_indent = inindent(0);
+ int in_indent = inindent(0);
if (in_indent) {
can_cindent = false;
}
@@ -3844,7 +3733,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
// Delete newline!
if (curwin->w_cursor.col == 0) {
- lnum = Insstart.lnum;
+ linenr_T lnum = Insstart.lnum;
if (curwin->w_cursor.lnum == lnum || revins_on) {
if (u_save((linenr_T)(curwin->w_cursor.lnum - 2),
(linenr_T)(curwin->w_cursor.lnum + 1)) == FAIL) {
@@ -3875,7 +3764,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
// again when auto-formatting.
if (has_format_option(FO_AUTO)
&& has_format_option(FO_WHITE_PAR)) {
- char *ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum, true);
+ char *ptr = ml_get_buf_mut(curbuf, curwin->w_cursor.lnum);
int len;
len = (int)strlen(ptr);
@@ -3900,11 +3789,11 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
// Do the next ins_char() in MODE_NORMAL state, to
// prevent ins_char() from replacing characters and
// avoiding showmatch().
- oldState = State;
+ int oldState = State;
State = MODE_NORMAL;
// restore characters (blanks) deleted after cursor
while (cc > 0) {
- save_col = curwin->w_cursor.col;
+ colnr_T save_col = curwin->w_cursor.col;
mb_replace_pop_ins(cc);
curwin->w_cursor.col = save_col;
cc = replace_pop();
@@ -3920,12 +3809,12 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
if (revins_on) { // put cursor on last inserted char
dec_cursor();
}
- mincol = 0;
+ colnr_T mincol = 0;
// keep indent
if (mode == BACKSPACE_LINE
&& (curbuf->b_p_ai || cindent_on())
&& !revins_on) {
- save_col = curwin->w_cursor.col;
+ colnr_T save_col = curwin->w_cursor.col;
beginline(BL_WHITE);
if (curwin->w_cursor.col < save_col) {
mincol = curwin->w_cursor.col;
@@ -3944,22 +3833,20 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
&& (*(get_cursor_pos_ptr() - 1) == TAB
|| (*(get_cursor_pos_ptr() - 1) == ' '
&& (!*inserted_space_p || arrow_used)))))) {
- int ts;
colnr_T vcol;
colnr_T want_vcol;
- colnr_T start_vcol;
*inserted_space_p = false;
// Compute the virtual column where we want to be. Since
// 'showbreak' may get in the way, need to get the last column of
// the previous character.
getvcol(curwin, &curwin->w_cursor, &vcol, NULL, NULL);
- start_vcol = vcol;
+ colnr_T start_vcol = vcol;
dec_cursor();
getvcol(curwin, &curwin->w_cursor, NULL, NULL, &want_vcol);
inc_cursor();
if (p_sta && in_indent) {
- ts = get_sw_value(curbuf);
+ int ts = get_sw_value(curbuf);
want_vcol = (want_vcol / ts) * ts;
} else {
want_vcol = tabstop_start(want_vcol,
@@ -3999,7 +3886,6 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
}
} else {
// Delete up to starting point, start of line or previous word.
- int prev_cclass = 0;
int cclass = mb_get_class(get_cursor_pos_ptr());
do {
@@ -4008,7 +3894,7 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
}
cc = gchar_cursor();
// look multi-byte character class
- prev_cclass = cclass;
+ int prev_cclass = cclass;
cclass = mb_get_class(get_cursor_pos_ptr());
if (mode == BACKSPACE_WORD && !ascii_isspace(cc)) { // start of word?
mode = BACKSPACE_WORD_NOT_SPACE;
@@ -4026,15 +3912,15 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
if (State & REPLACE_FLAG) {
replace_do_bs(-1);
} else {
- const int l_p_deco = p_deco;
- if (l_p_deco) {
- (void)utfc_ptr2char(get_cursor_pos_ptr(), cpc);
+ bool has_composing = false;
+ if (p_deco) {
+ char *p0 = get_cursor_pos_ptr();
+ has_composing = utf_composinglike(p0, p0 + utf_ptr2len(p0));
}
(void)del_char(false);
// If there are combining characters and 'delcombine' is set
- // move the cursor back. Don't back up before the base
- // character.
- if (l_p_deco && cpc[0] != NUL) {
+ // move the cursor back. Don't back up before the base character.
+ if (has_composing) {
inc_cursor();
}
if (revins_chars) {
@@ -4099,92 +3985,15 @@ static bool ins_bs(int c, int mode, int *inserted_space_p)
return did_backspace;
}
-static void ins_mouse(int c)
-{
- pos_T tpos;
- win_T *old_curwin = curwin;
-
- undisplay_dollar();
- tpos = curwin->w_cursor;
- if (do_mouse(NULL, c, BACKWARD, 1, 0)) {
- win_T *new_curwin = curwin;
-
- if (curwin != old_curwin && win_valid(old_curwin)) {
- // Mouse took us to another window. We need to go back to the
- // previous one to stop insert there properly.
- curwin = old_curwin;
- curbuf = curwin->w_buffer;
- if (bt_prompt(curbuf)) {
- // Restart Insert mode when re-entering the prompt buffer.
- curbuf->b_prompt_insert = 'A';
- }
- }
- start_arrow(curwin == old_curwin ? &tpos : NULL);
- if (curwin != new_curwin && win_valid(new_curwin)) {
- curwin = new_curwin;
- curbuf = curwin->w_buffer;
- }
- can_cindent = true;
- }
-
- // redraw status lines (in case another window became active)
- redraw_statuslines();
-}
-
-static void ins_mousescroll(int dir)
-{
- win_T *const old_curwin = curwin;
- pos_T tpos = curwin->w_cursor;
-
- if (mouse_row >= 0 && mouse_col >= 0) {
- int row = mouse_row, col = mouse_col, grid = mouse_grid;
-
- // find the window at the pointer coordinates
- win_T *wp = mouse_find_win(&grid, &row, &col);
- if (wp == NULL) {
- return;
- }
- curwin = wp;
- curbuf = curwin->w_buffer;
- }
- if (curwin == old_curwin) {
- undisplay_dollar();
- }
-
- // Don't scroll the window in which completion is being done.
- if (!pum_visible() || curwin != old_curwin) {
- if (dir == MSCR_DOWN || dir == MSCR_UP) {
- if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) {
- scroll_redraw(dir, (long)(curwin->w_botline - curwin->w_topline));
- } else if (p_mousescroll_vert > 0) {
- scroll_redraw(dir, p_mousescroll_vert);
- }
- } else {
- mouse_scroll_horiz(dir);
- }
- }
-
- curwin->w_redr_status = true;
-
- curwin = old_curwin;
- curbuf = curwin->w_buffer;
-
- if (!equalpos(curwin->w_cursor, tpos)) {
- start_arrow(&tpos);
- can_cindent = true;
- }
-}
-
static void ins_left(void)
{
- pos_T tpos;
const bool end_change = dont_sync_undo == kFalse; // end undoable change
if ((fdo_flags & FDO_HOR) && KeyTyped) {
foldOpenCursor();
}
undisplay_dollar();
- tpos = curwin->w_cursor;
+ pos_T tpos = curwin->w_cursor;
if (oneleft() == OK) {
start_arrow_with_change(&tpos, end_change);
if (!end_change) {
@@ -4210,13 +4019,11 @@ static void ins_left(void)
static void ins_home(int c)
{
- pos_T tpos;
-
if ((fdo_flags & FDO_HOR) && KeyTyped) {
foldOpenCursor();
}
undisplay_dollar();
- tpos = curwin->w_cursor;
+ pos_T tpos = curwin->w_cursor;
if (c == K_C_HOME) {
curwin->w_cursor.lnum = 1;
}
@@ -4228,13 +4035,11 @@ static void ins_home(int c)
static void ins_end(int c)
{
- pos_T tpos;
-
if ((fdo_flags & FDO_HOR) && KeyTyped) {
foldOpenCursor();
}
undisplay_dollar();
- tpos = curwin->w_cursor;
+ pos_T tpos = curwin->w_cursor;
if (c == K_C_END) {
curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
}
@@ -4256,7 +4061,7 @@ static void ins_s_left(void)
if (!end_change) {
AppendCharToRedobuff(K_S_LEFT);
}
- (void)bck_word(1L, false, false);
+ (void)bck_word(1, false, false);
curwin->w_set_curswant = true;
} else {
vim_beep(BO_CRSR);
@@ -4315,7 +4120,7 @@ static void ins_s_right(void)
if (!end_change) {
AppendCharToRedobuff(K_S_RIGHT);
}
- (void)fwd_word(1L, false, 0);
+ (void)fwd_word(1, false, 0);
curwin->w_set_curswant = true;
} else {
vim_beep(BO_CRSR);
@@ -4326,13 +4131,12 @@ static void ins_s_right(void)
/// @param startcol when true move to Insstart.col
static void ins_up(bool startcol)
{
- pos_T tpos;
linenr_T old_topline = curwin->w_topline;
int old_topfill = curwin->w_topfill;
undisplay_dollar();
- tpos = curwin->w_cursor;
- if (cursor_up(1L, true) == OK) {
+ pos_T tpos = curwin->w_cursor;
+ if (cursor_up(1, true) == OK) {
if (startcol) {
coladvance(getvcol_nolist(&Insstart));
}
@@ -4349,8 +4153,6 @@ static void ins_up(bool startcol)
static void ins_pageup(void)
{
- pos_T tpos;
-
undisplay_dollar();
if (mod_mask & MOD_MASK_CTRL) {
@@ -4362,8 +4164,8 @@ static void ins_pageup(void)
return;
}
- tpos = curwin->w_cursor;
- if (onepage(BACKWARD, 1L) == OK) {
+ pos_T tpos = curwin->w_cursor;
+ if (onepage(BACKWARD, 1) == OK) {
start_arrow(&tpos);
can_cindent = true;
} else {
@@ -4374,13 +4176,12 @@ static void ins_pageup(void)
/// @param startcol when true move to Insstart.col
static void ins_down(bool startcol)
{
- pos_T tpos;
linenr_T old_topline = curwin->w_topline;
int old_topfill = curwin->w_topfill;
undisplay_dollar();
- tpos = curwin->w_cursor;
- if (cursor_down(1L, true) == OK) {
+ pos_T tpos = curwin->w_cursor;
+ if (cursor_down(1, true) == OK) {
if (startcol) {
coladvance(getvcol_nolist(&Insstart));
}
@@ -4397,8 +4198,6 @@ static void ins_down(bool startcol)
static void ins_pagedown(void)
{
- pos_T tpos;
-
undisplay_dollar();
if (mod_mask & MOD_MASK_CTRL) {
@@ -4410,8 +4209,8 @@ static void ins_pagedown(void)
return;
}
- tpos = curwin->w_cursor;
- if (onepage(FORWARD, 1L) == OK) {
+ pos_T tpos = curwin->w_cursor;
+ if (onepage(FORWARD, 1) == OK) {
start_arrow(&tpos);
can_cindent = true;
} else {
@@ -4425,7 +4224,6 @@ static void ins_pagedown(void)
static bool ins_tab(void)
FUNC_ATTR_WARN_UNUSED_RESULT
{
- int i;
int temp;
if (Insstart_blank_vcol == MAXCOL && curwin->w_cursor.lnum == Insstart.lnum) {
@@ -4504,7 +4302,6 @@ static bool ins_tab(void)
char *ptr;
char *saved_line = NULL; // init for GCC
pos_T pos;
- pos_T fpos;
pos_T *cursor;
colnr_T want_vcol, vcol;
int change_col = -1;
@@ -4528,7 +4325,7 @@ static bool ins_tab(void)
}
// Find first white before the cursor
- fpos = curwin->w_cursor;
+ pos_T fpos = curwin->w_cursor;
while (fpos.col > 0 && ascii_iswhite(ptr[-1])) {
fpos.col--;
ptr--;
@@ -4553,7 +4350,7 @@ static bool ins_tab(void)
// Use as many TABs as possible. Beware of 'breakindent', 'showbreak'
// and 'linebreak' adding extra virtual columns.
while (ascii_iswhite(*ptr)) {
- i = lbr_chartabsize(&cts);
+ int i = lbr_chartabsize(&cts);
if (cts.cts_vcol + i > want_vcol) {
break;
}
@@ -4595,9 +4392,9 @@ static bool ins_tab(void)
fpos.col += repl_off;
// Delete following spaces.
- i = cursor->col - fpos.col;
+ int i = cursor->col - fpos.col;
if (i > 0) {
- STRMOVE(ptr, (char *)ptr + i);
+ STRMOVE(ptr, ptr + i);
// correct replace stack.
if ((State & REPLACE_FLAG)
&& !(State & VREPLACE_FLAG)) {
@@ -4606,9 +4403,8 @@ static bool ins_tab(void)
}
}
if (!(State & VREPLACE_FLAG)) {
- extmark_splice_cols(curbuf, (int)fpos.lnum - 1, change_col,
- cursor->col - change_col, fpos.col - change_col,
- kExtmarkUndo);
+ inserted_bytes(fpos.lnum, change_col,
+ cursor->col - change_col, fpos.col - change_col);
}
}
cursor->col -= i;
@@ -4689,8 +4485,6 @@ bool ins_eol(int c)
// done.
static int ins_digraph(void)
{
- int c;
- int cc;
bool did_putchar = false;
pc_status = PC_STATUS_UNSET;
@@ -4707,7 +4501,7 @@ static int ins_digraph(void)
// mode message to be deleted when ESC is hit
no_mapping++;
allow_keys++;
- c = plain_vgetc();
+ int c = plain_vgetc();
no_mapping--;
allow_keys--;
if (did_putchar) {
@@ -4736,7 +4530,7 @@ static int ins_digraph(void)
}
no_mapping++;
allow_keys++;
- cc = plain_vgetc();
+ int cc = plain_vgetc();
no_mapping--;
allow_keys--;
if (did_putchar) {
@@ -4759,9 +4553,7 @@ static int ins_digraph(void)
// Returns the char to be inserted, or NUL if none found.
int ins_copychar(linenr_T lnum)
{
- int c;
- char *ptr, *prev_ptr;
- char *line;
+ char *ptr;
if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) {
vim_beep(BO_COPY);
@@ -4769,9 +4561,9 @@ int ins_copychar(linenr_T lnum)
}
// try to advance to the cursor column
- line = ml_get(lnum);
- prev_ptr = line;
validate_virtcol();
+ char *line = ml_get(lnum);
+ char *prev_ptr = line;
chartabsize_T cts;
init_chartabsize_arg(&cts, curwin, lnum, 0, line, line);
@@ -4787,7 +4579,7 @@ int ins_copychar(linenr_T lnum)
}
clear_chartabsize_arg(&cts);
- c = utf_ptr2char(ptr);
+ int c = utf_ptr2char(ptr);
if (c == NUL) {
vim_beep(BO_COPY);
}
@@ -4809,8 +4601,6 @@ static int ins_ctrl_ey(int tc)
} else {
c = ins_copychar(curwin->w_cursor.lnum + (c == Ctrl_Y ? -1 : 1));
if (c != NUL) {
- long tw_save;
-
// The character must be taken literally, insert like it
// was typed after a CTRL-V, and pretend 'textwidth'
// wasn't set. Digits, 'o' and 'x' are special after a
@@ -4818,7 +4608,7 @@ static int ins_ctrl_ey(int tc)
if (c < 256 && !isalnum(c)) {
AppendToRedobuff(CTRL_V_STR);
}
- tw_save = curbuf->b_p_tw;
+ OptInt tw_save = curbuf->b_p_tw;
curbuf->b_p_tw = -1;
insert_special(c, true, false);
curbuf->b_p_tw = tw_save;
@@ -4835,13 +4625,14 @@ static int ins_ctrl_ey(int tc)
// Used when inserting a "normal" character.
static void ins_try_si(int c)
{
- pos_T *pos, old_pos;
- char *ptr;
- int i;
- bool temp;
+ pos_T *pos;
// do some very smart indenting when entering '{' or '}'
if (((did_si || can_si_back) && c == '{') || (can_si && c == '}' && inindent(0))) {
+ pos_T old_pos;
+ char *ptr;
+ int i;
+ bool temp;
// for '}' set indent equal to indent of line containing matching '{'
if (c == '}' && (pos = findmatch(NULL, '{')) != NULL) {
old_pos = curwin->w_cursor;
@@ -4974,9 +4765,8 @@ void set_can_cindent(bool val)
int ins_apply_autocmds(event_T event)
{
varnumber_T tick = buf_get_changedtick(curbuf);
- int r;
- r = apply_autocmds(event, NULL, NULL, false, curbuf);
+ int 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.