aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/normal.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/normal.c')
-rw-r--r--src/nvim/normal.c1139
1 files changed, 149 insertions, 990 deletions
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 47ad000385..8f4240c062 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -8,14 +8,21 @@
//
#include <assert.h>
+#include <ctype.h>
#include <inttypes.h>
+#include <limits.h>
#include <stdbool.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <time.h>
+#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
#include "nvim/ascii.h"
+#include "nvim/autocmd.h"
#include "nvim/buffer.h"
+#include "nvim/buffer_defs.h"
#include "nvim/change.h"
#include "nvim/charset.h"
#include "nvim/cmdhist.h"
@@ -25,8 +32,6 @@
#include "nvim/drawscreen.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
-#include "nvim/eval/userfunc.h"
-#include "nvim/event/loop.h"
#include "nvim/ex_cmds.h"
#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h"
@@ -34,18 +39,18 @@
#include "nvim/fileio.h"
#include "nvim/fold.h"
#include "nvim/getchar.h"
+#include "nvim/gettext.h"
#include "nvim/globals.h"
#include "nvim/grid.h"
#include "nvim/help.h"
-#include "nvim/indent.h"
+#include "nvim/highlight_defs.h"
#include "nvim/keycodes.h"
-#include "nvim/log.h"
-#include "nvim/main.h"
+#include "nvim/macros.h"
#include "nvim/mapping.h"
#include "nvim/mark.h"
+#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
-#include "nvim/menu.h"
#include "nvim/message.h"
#include "nvim/mouse.h"
#include "nvim/move.h"
@@ -57,16 +62,19 @@
#include "nvim/plines.h"
#include "nvim/profile.h"
#include "nvim/quickfix.h"
+#include "nvim/screen.h"
#include "nvim/search.h"
#include "nvim/spell.h"
#include "nvim/spellfile.h"
#include "nvim/spellsuggest.h"
#include "nvim/state.h"
+#include "nvim/statusline.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/tag.h"
#include "nvim/textformat.h"
#include "nvim/textobject.h"
+#include "nvim/types.h"
#include "nvim/ui.h"
#include "nvim/undo.h"
#include "nvim/vim.h"
@@ -145,8 +153,7 @@ static const struct nv_cmd {
nv_func_T cmd_func; ///< function for this command
uint16_t cmd_flags; ///< NV_ flags
int16_t cmd_arg; ///< value for ca.arg
-} nv_cmds[] =
-{
+} nv_cmds[] = {
{ NUL, nv_error, 0, 0 },
{ Ctrl_A, nv_addsub, 0, 0 },
{ Ctrl_B, nv_page, NV_STS, BACKWARD },
@@ -613,6 +620,7 @@ static bool normal_need_redraw_mode_message(NormalState *s)
&& stuff_empty()
&& typebuf_typed()
&& emsg_silent == 0
+ && !in_assert_fails
&& !did_wait_return
&& s->oa.op_type == OP_NOP);
}
@@ -629,18 +637,18 @@ static void normal_redraw_mode_message(NormalState *s)
// If need to redraw, and there is a "keep_msg", redraw before the
// delay
if (must_redraw && keep_msg != NULL && !emsg_on_display) {
- char_u *kmsg;
+ char *kmsg;
- kmsg = (char_u *)keep_msg;
+ kmsg = keep_msg;
keep_msg = NULL;
// Showmode() will clear keep_msg, but we want to use it anyway.
// First update w_topline.
setcursor();
- update_screen(0);
+ update_screen();
// now reset it, otherwise it's put in the history again
- keep_msg = (char *)kmsg;
+ keep_msg = kmsg;
- kmsg = vim_strsave((char_u *)keep_msg);
+ kmsg = xstrdup(keep_msg);
msg_attr((const char *)kmsg, keep_msg_attr);
xfree(kmsg);
}
@@ -1132,6 +1140,7 @@ static int normal_execute(VimState *state, int key)
if (s->need_flushbuf) {
ui_flush();
}
+
if (s->ca.cmdchar != K_IGNORE && s->ca.cmdchar != K_EVENT) {
did_cursorhold = false;
}
@@ -1222,8 +1231,7 @@ static void normal_check_interrupt(NormalState *s)
static void normal_check_window_scrolled(NormalState *s)
{
if (!finish_op) {
- // Trigger Scroll if the viewport changed.
- may_trigger_winscrolled();
+ may_trigger_win_scrolled_resized();
}
}
@@ -1284,9 +1292,9 @@ static void normal_redraw(NormalState *s)
if (VIsual_active) {
redraw_curbuf_later(UPD_INVERTED); // update inverted part
- update_screen(0);
+ update_screen();
} else if (must_redraw) {
- update_screen(0);
+ update_screen();
} else if (redraw_cmdline || clear_cmdline || redraw_mode) {
showmode();
}
@@ -1389,6 +1397,9 @@ static int normal_check(VimState *state)
fclose(time_fd);
time_fd = NULL;
}
+ // After the first screen update may start triggering WinScrolled
+ // autocmd events. Store all the scroll positions and sizes now.
+ may_make_initial_scroll_size_snapshot();
}
// May perform garbage collection when waiting for a character, but
@@ -1433,856 +1444,6 @@ static void set_vcount_ca(cmdarg_T *cap, bool *set_prevcount)
*set_prevcount = false; // only set v:prevcount once
}
-/// Move the current tab to tab in same column as mouse or to end of the
-/// tabline if there is no tab there.
-static void move_tab_to_mouse(void)
-{
- int tabnr = tab_page_click_defs[mouse_col].tabnr;
- if (tabnr <= 0) {
- tabpage_move(9999);
- } else if (tabnr < tabpage_index(curtab)) {
- tabpage_move(tabnr - 1);
- } else {
- tabpage_move(tabnr);
- }
-}
-
-/// Call click definition function for column "col" in the "click_defs" array for button
-/// "which_button".
-static void call_click_def_func(StlClickDefinition *click_defs, int col, int which_button)
-{
- typval_T argv[] = {
- {
- .v_lock = VAR_FIXED,
- .v_type = VAR_NUMBER,
- .vval = {
- .v_number = (varnumber_T)click_defs[col].tabnr
- },
- },
- {
- .v_lock = VAR_FIXED,
- .v_type = VAR_NUMBER,
- .vval = {
- .v_number = ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_4CLICK
- ? 4
- : ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_3CLICK
- ? 3
- : ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK
- ? 2
- : 1)))
- },
- },
- {
- .v_lock = VAR_FIXED,
- .v_type = VAR_STRING,
- .vval = {
- .v_string = (which_button == MOUSE_LEFT
- ? "l"
- : (which_button == MOUSE_RIGHT
- ? "r"
- : (which_button == MOUSE_MIDDLE
- ? "m"
- : "?")))
- },
- },
- {
- .v_lock = VAR_FIXED,
- .v_type = VAR_STRING,
- .vval = {
- .v_string = (char[]) {
- (char)(mod_mask & MOD_MASK_SHIFT ? 's' : ' '),
- (char)(mod_mask & MOD_MASK_CTRL ? 'c' : ' '),
- (char)(mod_mask & MOD_MASK_ALT ? 'a' : ' '),
- (char)(mod_mask & MOD_MASK_META ? 'm' : ' '),
- NUL
- }
- },
- }
- };
- typval_T rettv;
- (void)call_vim_function(click_defs[col].func, ARRAY_SIZE(argv), argv, &rettv);
- tv_clear(&rettv);
-}
-
-/// Do the appropriate action for the current mouse click in the current mode.
-/// Not used for Command-line mode.
-///
-/// Normal and Visual Mode:
-/// event modi- position visual change action
-/// fier cursor window
-/// left press - yes end yes
-/// left press C yes end yes "^]" (2)
-/// left press S yes end (popup: extend) yes "*" (2)
-/// left drag - yes start if moved no
-/// left relse - yes start if moved no
-/// middle press - yes if not active no put register
-/// middle press - yes if active no yank and put
-/// right press - yes start or extend yes
-/// right press S yes no change yes "#" (2)
-/// right drag - yes extend no
-/// right relse - yes extend no
-///
-/// Insert or Replace Mode:
-/// event modi- position visual change action
-/// fier cursor window
-/// left press - yes (cannot be active) yes
-/// left press C yes (cannot be active) yes "CTRL-O^]" (2)
-/// left press S yes (cannot be active) yes "CTRL-O*" (2)
-/// left drag - yes start or extend (1) no CTRL-O (1)
-/// left relse - yes start or extend (1) no CTRL-O (1)
-/// middle press - no (cannot be active) no put register
-/// right press - yes start or extend yes CTRL-O
-/// right press S yes (cannot be active) yes "CTRL-O#" (2)
-///
-/// (1) only if mouse pointer moved since press
-/// (2) only if click is in same buffer
-///
-/// @param oap operator argument, can be NULL
-/// @param c K_LEFTMOUSE, etc
-/// @param dir Direction to 'put' if necessary
-/// @param fixindent PUT_FIXINDENT if fixing indent necessary
-///
-/// @return true if start_arrow() should be called for edit mode.
-bool do_mouse(oparg_T *oap, int c, int dir, long count, bool fixindent)
-{
- static bool got_click = false; // got a click some time back
-
- int which_button; // MOUSE_LEFT, _MIDDLE or _RIGHT
- bool is_click; // If false it's a drag or release event
- bool is_drag; // If true it's a drag event
- int jump_flags = 0; // flags for jump_to_mouse()
- pos_T start_visual;
- bool moved; // Has cursor moved?
- bool in_winbar; // mouse in window bar
- bool in_status_line; // mouse in status line
- static bool in_tab_line = false; // mouse clicked in tab line
- bool in_sep_line; // mouse in vertical separator line
- int c1, c2;
- pos_T save_cursor;
- win_T *old_curwin = curwin;
- static pos_T orig_cursor;
- colnr_T leftcol, rightcol;
- pos_T end_visual;
- long diff;
- int old_active = VIsual_active;
- int old_mode = VIsual_mode;
- int regname;
-
- save_cursor = curwin->w_cursor;
-
- for (;;) {
- which_button = get_mouse_button(KEY2TERMCAP1(c), &is_click, &is_drag);
- if (is_drag) {
- // If the next character is the same mouse event then use that
- // one. Speeds up dragging the status line.
- // Note: Since characters added to the stuff buffer in the code
- // below need to come before the next character, do not do this
- // when the current character was stuffed.
- if (!KeyStuffed && vpeekc() != NUL) {
- int nc;
- int save_mouse_grid = mouse_grid;
- int save_mouse_row = mouse_row;
- int save_mouse_col = mouse_col;
-
- // Need to get the character, peeking doesn't get the actual one.
- nc = safe_vgetc();
- if (c == nc) {
- continue;
- }
- vungetc(nc);
- mouse_grid = save_mouse_grid;
- mouse_row = save_mouse_row;
- mouse_col = save_mouse_col;
- }
- }
- break;
- }
-
- if (c == K_MOUSEMOVE) {
- // Mouse moved without a button pressed.
- return false;
- }
-
- // Ignore drag and release events if we didn't get a click.
- if (is_click) {
- got_click = true;
- } else {
- if (!got_click) { // didn't get click, ignore
- return false;
- }
- if (!is_drag) { // release, reset got_click
- got_click = false;
- if (in_tab_line) {
- in_tab_line = false;
- return false;
- }
- }
- }
-
- // CTRL right mouse button does CTRL-T
- if (is_click && (mod_mask & MOD_MASK_CTRL) && which_button == MOUSE_RIGHT) {
- if (State & MODE_INSERT) {
- stuffcharReadbuff(Ctrl_O);
- }
- if (count > 1) {
- stuffnumReadbuff(count);
- }
- stuffcharReadbuff(Ctrl_T);
- got_click = false; // ignore drag&release now
- return false;
- }
-
- // CTRL only works with left mouse button
- if ((mod_mask & MOD_MASK_CTRL) && which_button != MOUSE_LEFT) {
- return false;
- }
-
- // When a modifier is down, ignore drag and release events, as well as
- // multiple clicks and the middle mouse button.
- // Accept shift-leftmouse drags when 'mousemodel' is "popup.*".
- if ((mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL | MOD_MASK_ALT
- | MOD_MASK_META))
- && (!is_click
- || (mod_mask & MOD_MASK_MULTI_CLICK)
- || which_button == MOUSE_MIDDLE)
- && !((mod_mask & (MOD_MASK_SHIFT|MOD_MASK_ALT))
- && mouse_model_popup()
- && which_button == MOUSE_LEFT)
- && !((mod_mask & MOD_MASK_ALT)
- && !mouse_model_popup()
- && which_button == MOUSE_RIGHT)) {
- return false;
- }
-
- // If the button press was used as the movement command for an operator (eg
- // "d<MOUSE>"), or it is the middle button that is held down, ignore
- // drag/release events.
- if (!is_click && which_button == MOUSE_MIDDLE) {
- return false;
- }
-
- if (oap != NULL) {
- regname = oap->regname;
- } else {
- regname = 0;
- }
-
- // Middle mouse button does a 'put' of the selected text
- if (which_button == MOUSE_MIDDLE) {
- if (State == MODE_NORMAL) {
- // If an operator was pending, we don't know what the user wanted to do.
- // Go back to normal mode: Clear the operator and beep().
- if (oap != NULL && oap->op_type != OP_NOP) {
- clearopbeep(oap);
- return false;
- }
-
- // If visual was active, yank the highlighted text and put it
- // before the mouse pointer position.
- // In Select mode replace the highlighted text with the clipboard.
- if (VIsual_active) {
- if (VIsual_select) {
- stuffcharReadbuff(Ctrl_G);
- stuffReadbuff("\"+p");
- } else {
- stuffcharReadbuff('y');
- stuffcharReadbuff(K_MIDDLEMOUSE);
- }
- return false;
- }
- // The rest is below jump_to_mouse()
- } else if ((State & MODE_INSERT) == 0) {
- return false;
- }
-
- // Middle click in insert mode doesn't move the mouse, just insert the
- // contents of a register. '.' register is special, can't insert that
- // with do_put().
- // Also paste at the cursor if the current mode isn't in 'mouse' (only
- // happens for the GUI).
- if ((State & MODE_INSERT)) {
- if (regname == '.') {
- insert_reg(regname, true);
- } else {
- if (regname == 0 && eval_has_provider("clipboard")) {
- regname = '*';
- }
- if ((State & REPLACE_FLAG) && !yank_register_mline(regname)) {
- insert_reg(regname, true);
- } else {
- do_put(regname, NULL, BACKWARD, 1L,
- (fixindent ? PUT_FIXINDENT : 0) | PUT_CURSEND);
-
- // Repeat it with CTRL-R CTRL-O r or CTRL-R CTRL-P r
- AppendCharToRedobuff(Ctrl_R);
- AppendCharToRedobuff(fixindent ? Ctrl_P : Ctrl_O);
- AppendCharToRedobuff(regname == 0 ? '"' : regname);
- }
- }
- return false;
- }
- }
-
- // When dragging or button-up stay in the same window.
- if (!is_click) {
- jump_flags |= MOUSE_FOCUS | MOUSE_DID_MOVE;
- }
-
- start_visual.lnum = 0;
-
- // Check for clicking in the tab page line.
- if (mouse_grid <= 1 && mouse_row == 0 && firstwin->w_winrow > 0) {
- if (is_drag) {
- if (in_tab_line) {
- move_tab_to_mouse();
- }
- return false;
- }
-
- // click in a tab selects that tab page
- if (is_click
- && cmdwin_type == 0
- && mouse_col < Columns) {
- in_tab_line = true;
- c1 = tab_page_click_defs[mouse_col].tabnr;
- switch (tab_page_click_defs[mouse_col].type) {
- case kStlClickDisabled:
- break;
- case kStlClickTabClose: {
- tabpage_T *tp;
-
- // Close the current or specified tab page.
- if (c1 == 999) {
- tp = curtab;
- } else {
- tp = find_tabpage(c1);
- }
- if (tp == curtab) {
- if (first_tabpage->tp_next != NULL) {
- tabpage_close(false);
- }
- } else if (tp != NULL) {
- tabpage_close_other(tp, false);
- }
- break;
- }
- case kStlClickTabSwitch:
- if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK) {
- // double click opens new page
- end_visual_mode();
- tabpage_new();
- tabpage_move(c1 == 0 ? 9999 : c1 - 1);
- } else {
- // Go to specified tab page, or next one if not clicking
- // on a label.
- goto_tabpage(c1);
-
- // It's like clicking on the status line of a window.
- if (curwin != old_curwin) {
- end_visual_mode();
- }
- }
- break;
- case kStlClickFuncRun:
- call_click_def_func(tab_page_click_defs, mouse_col, which_button);
- break;
- }
- }
- return true;
- } else if (is_drag && in_tab_line) {
- move_tab_to_mouse();
- return false;
- }
-
- // When 'mousemodel' is "popup" or "popup_setpos", translate mouse events:
- // right button up -> pop-up menu
- // shift-left button -> right button
- // alt-left button -> alt-right button
- if (mouse_model_popup()) {
- if (which_button == MOUSE_RIGHT
- && !(mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL))) {
- if (!is_click) {
- // Ignore right button release events, only shows the popup
- // menu on the button down event.
- return false;
- }
- jump_flags = 0;
- if (STRCMP(p_mousem, "popup_setpos") == 0) {
- // First set the cursor position before showing the popup
- // menu.
- if (VIsual_active) {
- pos_T m_pos;
- // set MOUSE_MAY_STOP_VIS if we are outside the
- // selection or the current window (might have false
- // negative here)
- if (mouse_row < curwin->w_winrow
- || mouse_row > (curwin->w_winrow + curwin->w_height)) {
- jump_flags = MOUSE_MAY_STOP_VIS;
- } else if (get_fpos_of_mouse(&m_pos) != IN_BUFFER) {
- jump_flags = MOUSE_MAY_STOP_VIS;
- } else {
- if ((lt(curwin->w_cursor, VIsual)
- && (lt(m_pos, curwin->w_cursor) || lt(VIsual, m_pos)))
- || (lt(VIsual, curwin->w_cursor)
- && (lt(m_pos, VIsual) || lt(curwin->w_cursor, m_pos)))) {
- jump_flags = MOUSE_MAY_STOP_VIS;
- } else if (VIsual_mode == Ctrl_V) {
- getvcols(curwin, &curwin->w_cursor, &VIsual, &leftcol, &rightcol);
- getvcol(curwin, &m_pos, NULL, &m_pos.col, NULL);
- if (m_pos.col < leftcol || m_pos.col > rightcol) {
- jump_flags = MOUSE_MAY_STOP_VIS;
- }
- }
- }
- } else {
- jump_flags = MOUSE_MAY_STOP_VIS;
- }
- }
- if (jump_flags) {
- jump_flags = jump_to_mouse(jump_flags, NULL, which_button);
- redraw_curbuf_later(VIsual_active ? UPD_INVERTED : UPD_VALID);
- update_screen(0);
- setcursor();
- ui_flush(); // Update before showing popup menu
- }
- show_popupmenu();
- got_click = false; // ignore release events
- return (jump_flags & CURSOR_MOVED) != 0;
- }
- if (which_button == MOUSE_LEFT
- && (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_ALT))) {
- which_button = MOUSE_RIGHT;
- mod_mask &= ~MOD_MASK_SHIFT;
- }
- }
-
- if ((State & (MODE_NORMAL | MODE_INSERT))
- && !(mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL))) {
- if (which_button == MOUSE_LEFT) {
- if (is_click) {
- // stop Visual mode for a left click in a window, but not when on a status line
- if (VIsual_active) {
- jump_flags |= MOUSE_MAY_STOP_VIS;
- }
- } else {
- jump_flags |= MOUSE_MAY_VIS;
- }
- } else if (which_button == MOUSE_RIGHT) {
- if (is_click && VIsual_active) {
- // Remember the start and end of visual before moving the cursor.
- if (lt(curwin->w_cursor, VIsual)) {
- start_visual = curwin->w_cursor;
- end_visual = VIsual;
- } else {
- start_visual = VIsual;
- end_visual = curwin->w_cursor;
- }
- }
- jump_flags |= MOUSE_FOCUS;
- jump_flags |= MOUSE_MAY_VIS;
- }
- }
-
- // If an operator is pending, ignore all drags and releases until the next mouse click.
- if (!is_drag && oap != NULL && oap->op_type != OP_NOP) {
- got_click = false;
- oap->motion_type = kMTCharWise;
- }
-
- // When releasing the button let jump_to_mouse() know.
- if (!is_click && !is_drag) {
- jump_flags |= MOUSE_RELEASED;
- }
-
- // JUMP!
- jump_flags = jump_to_mouse(jump_flags,
- oap == NULL ? NULL : &(oap->inclusive),
- which_button);
-
- moved = (jump_flags & CURSOR_MOVED);
- in_winbar = (jump_flags & MOUSE_WINBAR);
- in_status_line = (jump_flags & IN_STATUS_LINE);
- in_sep_line = (jump_flags & IN_SEP_LINE);
-
- if ((in_winbar || in_status_line) && is_click) {
- // Handle click event on window bar or status lin
- int click_grid = mouse_grid;
- int click_row = mouse_row;
- int click_col = mouse_col;
- win_T *wp = mouse_find_win(&click_grid, &click_row, &click_col);
- if (wp == NULL) {
- return false;
- }
-
- StlClickDefinition *click_defs = in_status_line ? wp->w_status_click_defs
- : wp->w_winbar_click_defs;
-
- if (in_status_line && global_stl_height() > 0) {
- // global statusline is displayed for the current window,
- // and spans the whole screen.
- click_defs = curwin->w_status_click_defs;
- click_col = mouse_col;
- }
-
- if (click_defs != NULL) {
- switch (click_defs[click_col].type) {
- case kStlClickDisabled:
- break;
- case kStlClickFuncRun:
- call_click_def_func(click_defs, click_col, which_button);
- break;
- default:
- assert(false && "winbar and statusline only support %@ for clicks");
- break;
- }
- }
-
- return false;
- } else if (in_winbar) {
- // A drag or release event in the window bar has no side effects.
- return false;
- }
-
- // When jumping to another window, clear a pending operator. That's a bit
- // friendlier than beeping and not jumping to that window.
- if (curwin != old_curwin && oap != NULL && oap->op_type != OP_NOP) {
- clearop(oap);
- }
-
- if (mod_mask == 0
- && !is_drag
- && (jump_flags & (MOUSE_FOLD_CLOSE | MOUSE_FOLD_OPEN))
- && which_button == MOUSE_LEFT) {
- // open or close a fold at this line
- if (jump_flags & MOUSE_FOLD_OPEN) {
- openFold(curwin->w_cursor, 1L);
- } else {
- closeFold(curwin->w_cursor, 1L);
- }
- // don't move the cursor if still in the same window
- if (curwin == old_curwin) {
- curwin->w_cursor = save_cursor;
- }
- }
-
- // Set global flag that we are extending the Visual area with mouse dragging;
- // temporarily minimize 'scrolloff'.
- if (VIsual_active && is_drag && get_scrolloff_value(curwin)) {
- // In the very first line, allow scrolling one line
- if (mouse_row == 0) {
- mouse_dragging = 2;
- } else {
- mouse_dragging = 1;
- }
- }
-
- // When dragging the mouse above the window, scroll down.
- if (is_drag && mouse_row < 0 && !in_status_line) {
- scroll_redraw(false, 1L);
- mouse_row = 0;
- }
-
- if (start_visual.lnum) { // right click in visual mode
- // When ALT is pressed make Visual mode blockwise.
- if (mod_mask & MOD_MASK_ALT) {
- VIsual_mode = Ctrl_V;
- }
-
- // In Visual-block mode, divide the area in four, pick up the corner
- // that is in the quarter that the cursor is in.
- if (VIsual_mode == Ctrl_V) {
- getvcols(curwin, &start_visual, &end_visual, &leftcol, &rightcol);
- if (curwin->w_curswant > (leftcol + rightcol) / 2) {
- end_visual.col = leftcol;
- } else {
- end_visual.col = rightcol;
- }
- if (curwin->w_cursor.lnum >=
- (start_visual.lnum + end_visual.lnum) / 2) {
- end_visual.lnum = start_visual.lnum;
- }
-
- // move VIsual to the right column
- start_visual = curwin->w_cursor; // save the cursor pos
- curwin->w_cursor = end_visual;
- coladvance(end_visual.col);
- VIsual = curwin->w_cursor;
- curwin->w_cursor = start_visual; // restore the cursor
- } else {
- // If the click is before the start of visual, change the start.
- // If the click is after the end of visual, change the end. If
- // the click is inside the visual, change the closest side.
- if (lt(curwin->w_cursor, start_visual)) {
- VIsual = end_visual;
- } else if (lt(end_visual, curwin->w_cursor)) {
- VIsual = start_visual;
- } else {
- // In the same line, compare column number
- if (end_visual.lnum == start_visual.lnum) {
- if (curwin->w_cursor.col - start_visual.col >
- end_visual.col - curwin->w_cursor.col) {
- VIsual = start_visual;
- } else {
- VIsual = end_visual;
- }
- } else {
- // In different lines, compare line number
- diff = (curwin->w_cursor.lnum - start_visual.lnum) -
- (end_visual.lnum - curwin->w_cursor.lnum);
-
- if (diff > 0) { // closest to end
- VIsual = start_visual;
- } else if (diff < 0) { // closest to start
- VIsual = end_visual;
- } else { // in the middle line
- if (curwin->w_cursor.col <
- (start_visual.col + end_visual.col) / 2) {
- VIsual = end_visual;
- } else {
- VIsual = start_visual;
- }
- }
- }
- }
- }
- } else if ((State & MODE_INSERT) && VIsual_active) {
- // If Visual mode started in insert mode, execute "CTRL-O"
- stuffcharReadbuff(Ctrl_O);
- }
-
- // Middle mouse click: Put text before cursor.
- if (which_button == MOUSE_MIDDLE) {
- if (regname == 0 && eval_has_provider("clipboard")) {
- regname = '*';
- }
- if (yank_register_mline(regname)) {
- if (mouse_past_bottom) {
- dir = FORWARD;
- }
- } else if (mouse_past_eol) {
- dir = FORWARD;
- }
-
- if (fixindent) {
- c1 = (dir == BACKWARD) ? '[' : ']';
- c2 = 'p';
- } else {
- c1 = (dir == FORWARD) ? 'p' : 'P';
- c2 = NUL;
- }
- prep_redo(regname, count, NUL, c1, NUL, c2, NUL);
-
- // Remember where the paste started, so in edit() Insstart can be set to this position
- if (restart_edit != 0) {
- where_paste_started = curwin->w_cursor;
- }
- do_put(regname, NULL, dir, count,
- (fixindent ? PUT_FIXINDENT : 0)| PUT_CURSEND);
- } else if (((mod_mask & MOD_MASK_CTRL) || (mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK)
- && bt_quickfix(curbuf)) {
- // Ctrl-Mouse click or double click in a quickfix window jumps to the
- // error under the mouse pointer.
- if (curwin->w_llist_ref == NULL) { // quickfix window
- do_cmdline_cmd(".cc");
- } else { // location list window
- do_cmdline_cmd(".ll");
- }
- got_click = false; // ignore drag&release now
- } else if ((mod_mask & MOD_MASK_CTRL)
- || (curbuf->b_help && (mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK)) {
- // Ctrl-Mouse click (or double click in a help window) jumps to the tag
- // under the mouse pointer.
- if (State & MODE_INSERT) {
- stuffcharReadbuff(Ctrl_O);
- }
- stuffcharReadbuff(Ctrl_RSB);
- got_click = false; // ignore drag&release now
- } else if ((mod_mask & MOD_MASK_SHIFT)) {
- // Shift-Mouse click searches for the next occurrence of the word under
- // the mouse pointer
- if (State & MODE_INSERT || (VIsual_active && VIsual_select)) {
- stuffcharReadbuff(Ctrl_O);
- }
- if (which_button == MOUSE_LEFT) {
- stuffcharReadbuff('*');
- } else { // MOUSE_RIGHT
- stuffcharReadbuff('#');
- }
- } else if (in_status_line || in_sep_line) {
- // Do nothing if on status line or vertical separator
- // Handle double clicks otherwise
- } else if ((mod_mask & MOD_MASK_MULTI_CLICK) && (State & (MODE_NORMAL | MODE_INSERT))) {
- if (is_click || !VIsual_active) {
- if (VIsual_active) {
- orig_cursor = VIsual;
- } else {
- VIsual = curwin->w_cursor;
- orig_cursor = VIsual;
- VIsual_active = true;
- VIsual_reselect = true;
- // start Select mode if 'selectmode' contains "mouse"
- may_start_select('o');
- setmouse();
- }
- if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK) {
- // Double click with ALT pressed makes it blockwise.
- if (mod_mask & MOD_MASK_ALT) {
- VIsual_mode = Ctrl_V;
- } else {
- VIsual_mode = 'v';
- }
- } else if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_3CLICK) {
- VIsual_mode = 'V';
- } else if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_4CLICK) {
- VIsual_mode = Ctrl_V;
- }
- }
- // A double click selects a word or a block.
- if ((mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK) {
- pos_T *pos = NULL;
- int gc;
-
- if (is_click) {
- // If the character under the cursor (skipping white space) is
- // not a word character, try finding a match and select a (),
- // {}, [], #if/#endif, etc. block.
- end_visual = curwin->w_cursor;
- while (gc = gchar_pos(&end_visual), ascii_iswhite(gc)) {
- inc(&end_visual);
- }
- if (oap != NULL) {
- oap->motion_type = kMTCharWise;
- }
- if (oap != NULL
- && VIsual_mode == 'v'
- && !vim_iswordc(gchar_pos(&end_visual))
- && equalpos(curwin->w_cursor, VIsual)
- && (pos = findmatch(oap, NUL)) != NULL) {
- curwin->w_cursor = *pos;
- if (oap->motion_type == kMTLineWise) {
- VIsual_mode = 'V';
- } else if (*p_sel == 'e') {
- if (lt(curwin->w_cursor, VIsual)) {
- VIsual.col++;
- } else {
- curwin->w_cursor.col++;
- }
- }
- }
- }
-
- if (pos == NULL && (is_click || is_drag)) {
- // When not found a match or when dragging: extend to include a word.
- if (lt(curwin->w_cursor, orig_cursor)) {
- find_start_of_word(&curwin->w_cursor);
- find_end_of_word(&VIsual);
- } else {
- find_start_of_word(&VIsual);
- if (*p_sel == 'e' && *get_cursor_pos_ptr() != NUL) {
- curwin->w_cursor.col +=
- utfc_ptr2len((char *)get_cursor_pos_ptr());
- }
- find_end_of_word(&curwin->w_cursor);
- }
- }
- curwin->w_set_curswant = true;
- }
- if (is_click) {
- redraw_curbuf_later(UPD_INVERTED); // update the inversion
- }
- } else if (VIsual_active && !old_active) {
- if (mod_mask & MOD_MASK_ALT) {
- VIsual_mode = Ctrl_V;
- } else {
- VIsual_mode = 'v';
- }
- }
-
- // If Visual mode changed show it later.
- if ((!VIsual_active && old_active && mode_displayed)
- || (VIsual_active && p_smd && msg_silent == 0
- && (!old_active || VIsual_mode != old_mode))) {
- redraw_cmdline = true;
- }
-
- return moved;
-}
-
-/// Move "pos" back to the start of the word it's in.
-static void find_start_of_word(pos_T *pos)
-{
- char_u *line;
- int cclass;
- int col;
-
- line = ml_get(pos->lnum);
- cclass = get_mouse_class(line + pos->col);
-
- while (pos->col > 0) {
- col = pos->col - 1;
- col -= utf_head_off(line, line + col);
- if (get_mouse_class(line + col) != cclass) {
- break;
- }
- pos->col = col;
- }
-}
-
-/// Move "pos" forward to the end of the word it's in.
-/// When 'selection' is "exclusive", the position is just after the word.
-static void find_end_of_word(pos_T *pos)
-{
- char_u *line;
- int cclass;
- int col;
-
- line = ml_get(pos->lnum);
- if (*p_sel == 'e' && pos->col > 0) {
- pos->col--;
- pos->col -= utf_head_off(line, line + pos->col);
- }
- cclass = get_mouse_class(line + pos->col);
- while (line[pos->col] != NUL) {
- col = pos->col + utfc_ptr2len((char *)line + pos->col);
- if (get_mouse_class(line + col) != cclass) {
- if (*p_sel == 'e') {
- pos->col = col;
- }
- break;
- }
- pos->col = col;
- }
-}
-
-/// Get class of a character for selection: same class means same word.
-/// 0: blank
-/// 1: punctuation groups
-/// 2: normal word character
-/// >2: multi-byte word character.
-static int get_mouse_class(char_u *p)
-{
- if (MB_BYTE2LEN(p[0]) > 1) {
- return mb_get_class(p);
- }
-
- const int c = *p;
- if (c == ' ' || c == '\t') {
- return 0;
- }
- if (vim_iswordc(c)) {
- return 2;
- }
-
- // There are a few special cases where we want certain combinations of
- // characters to be considered as a single word. These are things like
- // "->", "/ *", "*=", "+=", "&=", "<=", ">=", "!=" etc. Otherwise, each
- // character is in its own class.
- if (c != NUL && vim_strchr("-+*/%<>&|^!=", c) != NULL) {
- return 1;
- }
- return c;
-}
-
/// End Visual mode.
/// This function should ALWAYS be called to end Visual mode, except from
/// do_pending_operator().
@@ -2416,7 +1577,7 @@ size_t find_ident_at_pos(win_T *wp, linenr_T lnum, colnr_T startcol, char **text
// if i == 0: try to find an identifier
// if i == 1: try to find any non-white text
- char_u *ptr = ml_get_buf(wp->w_buffer, lnum, false);
+ char *ptr = ml_get_buf(wp->w_buffer, lnum, false);
for (i = (find_type & FIND_IDENT) ? 0 : 1; i < 2; i++) {
// 1. skip to start of identifier/text
col = startcol;
@@ -2429,7 +1590,7 @@ size_t find_ident_at_pos(win_T *wp, linenr_T lnum, colnr_T startcol, char **text
if (this_class != 0 && (i == 1 || this_class != 1)) {
break;
}
- col += utfc_ptr2len((char *)ptr + col);
+ col += utfc_ptr2len(ptr + col);
}
// When starting on a ']' count it, so that we include the '['.
@@ -2440,7 +1601,7 @@ size_t find_ident_at_pos(win_T *wp, linenr_T lnum, colnr_T startcol, char **text
//
// Remember class of character under cursor.
if ((find_type & FIND_EVAL) && ptr[col] == ']') {
- this_class = mb_get_class((char_u *)"a");
+ this_class = mb_get_class("a");
} else {
this_class = mb_get_class(ptr + col);
}
@@ -2453,7 +1614,7 @@ size_t find_ident_at_pos(win_T *wp, linenr_T lnum, colnr_T startcol, char **text
|| (find_type & FIND_IDENT))
&& (!(find_type & FIND_EVAL)
|| prevcol == 0
- || !find_is_eval_item(ptr + prevcol, &prevcol, &bn, BACKWARD))) {
+ || !find_is_eval_item((char_u *)ptr + prevcol, &prevcol, &bn, BACKWARD))) {
break;
}
col = prevcol;
@@ -2479,7 +1640,7 @@ size_t find_ident_at_pos(win_T *wp, linenr_T lnum, colnr_T startcol, char **text
return 0;
}
ptr += col;
- *text = (char *)ptr;
+ *text = ptr;
if (textcol != NULL) {
*textcol = col;
}
@@ -2496,8 +1657,8 @@ size_t find_ident_at_pos(win_T *wp, linenr_T lnum, colnr_T startcol, char **text
: mb_get_class(ptr + col) != 0)
|| ((find_type & FIND_EVAL)
&& col <= (int)startcol
- && find_is_eval_item(ptr + col, &col, &bn, FORWARD)))) {
- col += utfc_ptr2len((char *)ptr + col);
+ && find_is_eval_item((char_u *)ptr + col, &col, &bn, FORWARD)))) {
+ col += utfc_ptr2len(ptr + col);
}
assert(col >= 0);
@@ -2622,9 +1783,7 @@ void may_clear_cmdline(void)
}
// Routines for displaying a partly typed command
-#define SHOWCMD_BUFLEN (SHOWCMD_COLS + 1 + 30)
-static char_u showcmd_buf[SHOWCMD_BUFLEN];
-static char_u old_showcmd_buf[SHOWCMD_BUFLEN]; // For push_showcmd()
+static char old_showcmd_buf[SHOWCMD_BUFLEN]; // For push_showcmd()
static bool showcmd_is_clear = true;
static bool showcmd_visual = false;
@@ -2663,12 +1822,12 @@ void clear_showcmd(void)
getvcols(curwin, &curwin->w_cursor, &VIsual, &leftcol, &rightcol);
p_sbr = saved_sbr;
curwin->w_p_sbr = saved_w_sbr;
- snprintf((char *)showcmd_buf, SHOWCMD_BUFLEN, "%" PRId64 "x%" PRId64,
+ snprintf(showcmd_buf, SHOWCMD_BUFLEN, "%" PRId64 "x%" PRId64,
(int64_t)lines, (int64_t)rightcol - leftcol + 1);
} else if (VIsual_mode == 'V' || VIsual.lnum != curwin->w_cursor.lnum) {
- snprintf((char *)showcmd_buf, SHOWCMD_BUFLEN, "%" PRId64, (int64_t)lines);
+ snprintf(showcmd_buf, SHOWCMD_BUFLEN, "%" PRId64, (int64_t)lines);
} else {
- char_u *s, *e;
+ char *s, *e;
int l;
int bytes = 0;
int chars = 0;
@@ -2681,7 +1840,7 @@ void clear_showcmd(void)
e = ml_get_pos(&VIsual);
}
while ((*p_sel != 'e') ? s <= e : s < e) {
- l = utfc_ptr2len((char *)s);
+ l = utfc_ptr2len(s);
if (l == 0) {
bytes++;
chars++;
@@ -2692,9 +1851,9 @@ void clear_showcmd(void)
s += l;
}
if (bytes == chars) {
- sprintf((char *)showcmd_buf, "%d", chars);
+ snprintf(showcmd_buf, SHOWCMD_BUFLEN, "%d", chars);
} else {
- sprintf((char *)showcmd_buf, "%d-%d", chars, bytes);
+ snprintf(showcmd_buf, SHOWCMD_BUFLEN, "%d-%d", chars, bytes);
}
}
int limit = ui_has(kUIMessages) ? SHOWCMD_BUFLEN - 1 : SHOWCMD_COLS;
@@ -2751,8 +1910,8 @@ bool add_to_showcmd(int c)
if (*p == ' ') {
STRCPY(p, "<20>");
}
- size_t old_len = STRLEN(showcmd_buf);
- size_t extra_len = STRLEN(p);
+ size_t old_len = strlen(showcmd_buf);
+ size_t extra_len = strlen(p);
size_t limit = ui_has(kUIMessages) ? SHOWCMD_BUFLEN - 1 : SHOWCMD_COLS;
if (old_len + extra_len > limit) {
size_t overflow = old_len + extra_len - limit;
@@ -2784,7 +1943,7 @@ static void del_from_showcmd(int len)
return;
}
- old_len = (int)STRLEN(showcmd_buf);
+ old_len = (int)strlen(showcmd_buf);
if (len > old_len) {
len = old_len;
}
@@ -2817,13 +1976,23 @@ void pop_showcmd(void)
static void display_showcmd(void)
{
- if (!ui_has_messages()) {
+ int len = (int)strlen(showcmd_buf);
+ showcmd_is_clear = (len == 0);
+
+ if (*p_sloc == 's') {
+ win_redr_status(curwin);
+ setcursor(); // put cursor back where it belongs
+ return;
+ }
+ if (*p_sloc == 't') {
+ draw_tabline();
+ setcursor(); // put cursor back where it belongs
+ return;
+ }
+ // 'showcmdloc' is "last" or empty
+ if (p_ch == 0 && !ui_has(kUIMessages)) {
return;
}
-
- int len;
- len = (int)STRLEN(showcmd_buf);
- showcmd_is_clear = (len == 0);
if (ui_has(kUIMessages)) {
MAXSIZE_TEMP_ARRAY(content, 1);
@@ -2831,7 +2000,7 @@ static void display_showcmd(void)
if (len > 0) {
// placeholder for future highlight support
ADD_C(chunk, INTEGER_OBJ(0));
- ADD_C(chunk, STRING_OBJ(cstr_as_string((char *)showcmd_buf)));
+ ADD_C(chunk, STRING_OBJ(cstr_as_string(showcmd_buf)));
ADD_C(content, ARRAY_OBJ(chunk));
}
ui_call_msg_showcmd(content);
@@ -2843,7 +2012,7 @@ static void display_showcmd(void)
grid_puts_line_start(&msg_grid_adj, showcmd_row);
if (!showcmd_is_clear) {
- grid_puts(&msg_grid_adj, (char *)showcmd_buf, showcmd_row, sc_col,
+ grid_puts(&msg_grid_adj, showcmd_buf, showcmd_row, sc_col,
HL_ATTR(HLF_MSG));
}
@@ -3059,7 +2228,7 @@ static void nv_gd(oparg_T *oap, int nchar, int thisblock)
/// @return true if line[offset] is not inside a C-style comment or string,
/// false otherwise.
-static bool is_ident(char_u *line, int offset)
+static bool is_ident(const char_u *line, int offset)
{
bool incomment = false;
int instring = 0;
@@ -3100,7 +2269,7 @@ static bool is_ident(char_u *line, int offset)
/// @return fail when not found.
bool find_decl(char_u *ptr, size_t len, bool locally, bool thisblock, int flags_arg)
{
- char_u *pat;
+ char *pat;
pos_T old_pos;
pos_T par_pos;
pos_T found_pos;
@@ -3116,7 +2285,7 @@ bool find_decl(char_u *ptr, size_t len, bool locally, bool thisblock, int flags_
// Put "\V" before the pattern to avoid that the special meaning of "."
// and "~" causes trouble.
assert(len <= INT_MAX);
- sprintf((char *)pat, vim_iswordp(ptr) ? "\\V\\<%.*s\\>" : "\\V%.*s",
+ sprintf(pat, vim_iswordp((char *)ptr) ? "\\V\\<%.*s\\>" : "\\V%.*s", // NOLINT(runtime/printf)
(int)len, ptr);
old_pos = curwin->w_cursor;
save_p_ws = p_ws;
@@ -3134,7 +2303,7 @@ bool find_decl(char_u *ptr, size_t len, bool locally, bool thisblock, int flags_
} else {
par_pos = curwin->w_cursor;
while (curwin->w_cursor.lnum > 1
- && *skipwhite((char *)get_cursor_line_ptr()) != NUL) {
+ && *skipwhite(get_cursor_line_ptr()) != NUL) {
curwin->w_cursor.lnum--;
}
}
@@ -3144,7 +2313,7 @@ bool find_decl(char_u *ptr, size_t len, bool locally, bool thisblock, int flags_
clearpos(&found_pos);
for (;;) {
t = searchit(curwin, curbuf, &curwin->w_cursor, NULL, FORWARD,
- pat, 1L, searchflags, RE_LAST, NULL);
+ (char_u *)pat, 1L, searchflags, RE_LAST, NULL);
if (curwin->w_cursor.lnum >= old_pos.lnum) {
t = false; // match after start is failure too
}
@@ -3171,13 +2340,13 @@ bool find_decl(char_u *ptr, size_t len, bool locally, bool thisblock, int flags_
}
break;
}
- if (get_leader_len((char *)get_cursor_line_ptr(), NULL, false, true) > 0) {
+ if (get_leader_len(get_cursor_line_ptr(), NULL, false, true) > 0) {
// Ignore this line, continue at start of next line.
curwin->w_cursor.lnum++;
curwin->w_cursor.col = 0;
continue;
}
- bool valid = is_ident(get_cursor_line_ptr(), curwin->w_cursor.col);
+ bool valid = is_ident((char_u *)get_cursor_line_ptr(), curwin->w_cursor.col);
// If the current position is not a valid identifier and a previous match is
// present, favor that one instead.
@@ -3361,7 +2530,7 @@ static bool nv_screengo(oparg_T *oap, int dir, long dist)
virtcol -= vim_strsize((char *)get_showbreak_value(curwin));
}
- int c = utf_ptr2char((char *)get_cursor_pos_ptr());
+ int c = utf_ptr2char(get_cursor_pos_ptr());
if (dir == FORWARD && virtcol < curwin->w_curswant
&& (curwin->w_curswant <= (colnr_T)width1)
&& !vim_isprintc(c) && c > 255) {
@@ -3410,7 +2579,7 @@ static void nv_mousescroll(cmdarg_T *cap)
if (cap->arg == MSCR_UP || cap->arg == MSCR_DOWN) {
if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) {
(void)onepage(cap->arg ? FORWARD : BACKWARD, 1L);
- } else {
+ } else if (p_mousescroll_vert > 0) {
cap->count1 = p_mousescroll_vert;
cap->count0 = p_mousescroll_vert;
nv_scroll_line(cap);
@@ -3514,6 +2683,7 @@ static bool nv_z_get_count(cmdarg_T *cap, int *nchar_arg)
no_mapping--;
allow_keys--;
(void)add_to_showcmd(nchar);
+
if (nchar == K_DEL || nchar == K_KDEL) {
n /= 10;
} else if (ascii_isdigit(nchar)) {
@@ -3554,6 +2724,7 @@ static int nv_zg_zw(cmdarg_T *cap, int nchar)
no_mapping--;
allow_keys--;
(void)add_to_showcmd(nchar);
+
if (vim_strchr("gGwW", nchar) == NULL) {
clearopbeep(cap->oap);
return OK;
@@ -3579,7 +2750,7 @@ static int nv_zg_zw(cmdarg_T *cap, int nchar)
len = spell_move_to(curwin, FORWARD, true, true, NULL);
emsg_off--;
if (len != 0 && curwin->w_cursor.col <= pos.col) {
- ptr = (char *)ml_get_pos(&curwin->w_cursor);
+ ptr = ml_get_pos(&curwin->w_cursor);
}
curwin->w_cursor = pos;
}
@@ -3588,7 +2759,7 @@ static int nv_zg_zw(cmdarg_T *cap, int nchar)
return FAIL;
}
assert(len <= INT_MAX);
- spell_add_word((char_u *)ptr, (int)len,
+ spell_add_word(ptr, (int)len,
nchar == 'w' || nchar == 'W' ? SPELL_ADD_BAD : SPELL_ADD_GOOD,
(nchar == 'G' || nchar == 'W') ? 0 : (int)cap->count1,
undo);
@@ -3605,7 +2776,7 @@ static void nv_zet(cmdarg_T *cap)
long old_fdl = curwin->w_p_fdl;
int old_fen = curwin->w_p_fen;
- int l_p_siso = (int)get_sidescrolloff_value(curwin);
+ int siso = (int)get_sidescrolloff_value(curwin);
if (ascii_isdigit(nchar) && !nv_z_get_count(cap, &nchar)) {
return;
@@ -3735,8 +2906,8 @@ static void nv_zet(cmdarg_T *cap)
} else {
getvcol(curwin, &curwin->w_cursor, &col, NULL, NULL);
}
- if (col > l_p_siso) {
- col -= l_p_siso;
+ if (col > siso) {
+ col -= siso;
} else {
col = 0;
}
@@ -3756,10 +2927,10 @@ static void nv_zet(cmdarg_T *cap)
getvcol(curwin, &curwin->w_cursor, NULL, NULL, &col);
}
n = curwin->w_width_inner - curwin_col_off();
- if (col + l_p_siso < n) {
+ if (col + siso < n) {
col = 0;
} else {
- col = col + l_p_siso - n + 1;
+ col = col + siso - n + 1;
}
if (curwin->w_leftcol != col) {
curwin->w_leftcol = col;
@@ -4057,7 +3228,7 @@ static void nv_colon(cmdarg_T *cap)
} else if (cap->oap->op_type != OP_NOP
&& (cap->oap->start.lnum > curbuf->b_ml.ml_line_count
|| cap->oap->start.col >
- (colnr_T)STRLEN(ml_get(cap->oap->start.lnum))
+ (colnr_T)strlen(ml_get(cap->oap->start.lnum))
|| did_emsg)) {
// The start of the operator has become invalid by the Ex command.
clearopbeep(cap->oap);
@@ -4164,7 +3335,7 @@ void do_nv_ident(int c1, int c2)
/// 'K' normal-mode command. Get the command to lookup the keyword under the
/// cursor.
-static size_t nv_K_getcmd(cmdarg_T *cap, char_u *kp, bool kp_help, bool kp_ex, char **ptr_arg,
+static size_t nv_K_getcmd(cmdarg_T *cap, char *kp, bool kp_help, bool kp_ex, char **ptr_arg,
size_t n, char *buf, size_t buf_size)
{
if (kp_help) {
@@ -4201,8 +3372,8 @@ static size_t nv_K_getcmd(cmdarg_T *cap, char_u *kp, bool kp_help, bool kp_ex, c
// When a count is given, turn it into a range. Is this
// really what we want?
- bool isman = (STRCMP(kp, "man") == 0);
- bool isman_s = (STRCMP(kp, "man -s") == 0);
+ bool isman = (strcmp(kp, "man") == 0);
+ bool isman_s = (strcmp(kp, "man -s") == 0);
if (cap->count0 != 0 && !(isman || isman_s)) {
snprintf(buf, buf_size, ".,.+%" PRId64, (int64_t)(cap->count0 - 1));
}
@@ -4216,7 +3387,7 @@ static size_t nv_K_getcmd(cmdarg_T *cap, char_u *kp, bool kp_help, bool kp_ex, c
}
STRCAT(buf, " ");
if (cap->count0 != 0 && (isman || isman_s)) {
- snprintf(buf + STRLEN(buf), buf_size - STRLEN(buf), "%" PRId64,
+ snprintf(buf + strlen(buf), buf_size - strlen(buf), "%" PRId64,
(int64_t)cap->count0);
STRCAT(buf, " ");
}
@@ -4234,12 +3405,12 @@ static size_t nv_K_getcmd(cmdarg_T *cap, char_u *kp, bool kp_help, bool kp_ex, c
static void nv_ident(cmdarg_T *cap)
{
char *ptr = NULL;
- char_u *p;
+ char *p;
size_t n = 0; // init for GCC
int cmdchar;
bool g_cmd; // "g" command
bool tag_cmd = false;
- char_u *aux_ptr;
+ char *aux_ptr;
if (cap->cmdchar == 'g') { // "g*", "g#", "g]" and "gCTRL-]"
cmdchar = cap->nchar;
@@ -4275,14 +3446,14 @@ static void nv_ident(cmdarg_T *cap)
// Allocate buffer to put the command in. Inserting backslashes can
// double the length of the word. p_kp / curbuf->b_p_kp could be added
// and some numbers.
- char_u *kp = *curbuf->b_p_kp == NUL ? p_kp : (char_u *)curbuf->b_p_kp; // 'keywordprg'
- bool kp_help = (*kp == NUL || STRCMP(kp, ":he") == 0 || STRCMP(kp, ":help") == 0);
+ char *kp = *curbuf->b_p_kp == NUL ? (char *)p_kp : curbuf->b_p_kp; // 'keywordprg'
+ bool kp_help = (*kp == NUL || strcmp(kp, ":he") == 0 || strcmp(kp, ":help") == 0);
if (kp_help && *skipwhite(ptr) == NUL) {
emsg(_(e_noident)); // found white space only
return;
}
bool kp_ex = (*kp == ':'); // 'keywordprg' is an ex command
- size_t buf_size = n * 2 + 30 + STRLEN(kp);
+ size_t buf_size = n * 2 + 30 + strlen(kp);
char *buf = xmalloc(buf_size);
buf[0] = NUL;
@@ -4294,9 +3465,9 @@ static void nv_ident(cmdarg_T *cap)
// Call setpcmark() first, so "*``" puts the cursor back where
// it was.
setpcmark();
- curwin->w_cursor.col = (colnr_T)(ptr - (char *)get_cursor_line_ptr());
+ curwin->w_cursor.col = (colnr_T)(ptr - get_cursor_line_ptr());
- if (!g_cmd && vim_iswordp((char_u *)ptr)) {
+ if (!g_cmd && vim_iswordp(ptr)) {
STRCPY(buf, "\\<");
}
no_smartcase = true; // don't use 'smartcase' now
@@ -4311,11 +3482,7 @@ static void nv_ident(cmdarg_T *cap)
case ']':
tag_cmd = true;
- if (p_cst) {
- STRCPY(buf, "cstag ");
- } else {
- STRCPY(buf, "ts ");
- }
+ STRCPY(buf, "ts ");
break;
default:
@@ -4336,45 +3503,45 @@ static void nv_ident(cmdarg_T *cap)
ptr = xstrnsave(ptr, n);
if (kp_ex) {
// Escape the argument properly for an Ex command
- p = (char_u *)vim_strsave_fnameescape((const char *)ptr, VSE_NONE);
+ p = vim_strsave_fnameescape((const char *)ptr, VSE_NONE);
} else {
// Escape the argument properly for a shell command
- p = vim_strsave_shellescape((char_u *)ptr, true, true);
+ p = vim_strsave_shellescape(ptr, true, true);
}
xfree(ptr);
- char *newbuf = xrealloc(buf, STRLEN(buf) + STRLEN(p) + 1);
+ char *newbuf = xrealloc(buf, strlen(buf) + strlen(p) + 1);
buf = newbuf;
STRCAT(buf, p);
xfree(p);
} else {
if (cmdchar == '*') {
- aux_ptr = (char_u *)(p_magic ? "/.*~[^$\\" : "/^$\\");
+ aux_ptr = (magic_isset() ? "/.*~[^$\\" : "/^$\\");
} else if (cmdchar == '#') {
- aux_ptr = (char_u *)(p_magic ? "/?.*~[^$\\" : "/?^$\\");
+ aux_ptr = (magic_isset() ? "/?.*~[^$\\" : "/?^$\\");
} else if (tag_cmd) {
if (curbuf->b_help) {
// ":help" handles unescaped argument
- aux_ptr = (char_u *)"";
+ aux_ptr = "";
} else {
- aux_ptr = (char_u *)"\\|\"\n[";
+ aux_ptr = "\\|\"\n[";
}
} else {
- aux_ptr = (char_u *)"\\|\"\n*?[";
+ aux_ptr = "\\|\"\n*?[";
}
- p = (char_u *)buf + STRLEN(buf);
+ p = buf + strlen(buf);
while (n-- > 0) {
// put a backslash before \ and some others
- if (vim_strchr((char *)aux_ptr, *ptr) != NULL) {
+ if (vim_strchr(aux_ptr, *ptr) != NULL) {
*p++ = '\\';
}
// When current byte is a part of multibyte character, copy all
// bytes of that character.
const size_t len = (size_t)(utfc_ptr2len(ptr) - 1);
for (size_t i = 0; i < len && n > 0; i++, n--) {
- *p++ = (char_u)(*ptr++);
+ *p++ = *ptr++;
}
- *p++ = (char_u)(*ptr++);
+ *p++ = *ptr++;
}
*p = NUL;
}
@@ -4382,13 +3549,13 @@ static void nv_ident(cmdarg_T *cap)
// Execute the command.
if (cmdchar == '*' || cmdchar == '#') {
if (!g_cmd
- && vim_iswordp(mb_prevptr(get_cursor_line_ptr(), (char_u *)ptr))) {
+ && vim_iswordp(mb_prevptr(get_cursor_line_ptr(), ptr))) {
STRCAT(buf, "\\>");
}
// put pattern in search history
init_history();
- add_to_history(HIST_SEARCH, (char_u *)buf, true, NUL);
+ add_to_history(HIST_SEARCH, buf, true, NUL);
(void)normal_search(cap, cmdchar == '*' ? '/' : '?', buf, 0, NULL);
} else {
@@ -4425,14 +3592,14 @@ bool get_visual_text(cmdarg_T *cap, char **pp, size_t *lenp)
return false;
}
if (VIsual_mode == 'V') {
- *pp = (char *)get_cursor_line_ptr();
- *lenp = STRLEN(*pp);
+ *pp = get_cursor_line_ptr();
+ *lenp = strlen(*pp);
} else {
if (lt(curwin->w_cursor, VIsual)) {
- *pp = (char *)ml_get_pos(&curwin->w_cursor);
+ *pp = ml_get_pos(&curwin->w_cursor);
*lenp = (size_t)VIsual.col - (size_t)curwin->w_cursor.col + 1;
} else {
- *pp = (char *)ml_get_pos(&VIsual);
+ *pp = ml_get_pos(&VIsual);
*lenp = (size_t)curwin->w_cursor.col - (size_t)VIsual.col + 1;
}
if (**pp == NUL) {
@@ -4451,7 +3618,7 @@ bool get_visual_text(cmdarg_T *cap, char **pp, size_t *lenp)
static void nv_tagpop(cmdarg_T *cap)
{
if (!checkclearopq(cap->oap)) {
- do_tag((char_u *)"", DT_POP, (int)cap->count1, false, true);
+ do_tag("", DT_POP, (int)cap->count1, false, true);
}
}
@@ -4478,7 +3645,9 @@ static void nv_scroll(cmdarg_T *cap)
&& curwin->w_cursor.lnum > curwin->w_topline; n--) {
(void)hasFolding(curwin->w_cursor.lnum,
&curwin->w_cursor.lnum, NULL);
- curwin->w_cursor.lnum--;
+ if (curwin->w_cursor.lnum > curwin->w_topline) {
+ curwin->w_cursor.lnum--;
+ }
}
} else {
curwin->w_cursor.lnum -= (linenr_T)cap->count1 - 1;
@@ -4600,7 +3769,7 @@ static void nv_right(cmdarg_T *cap)
if (virtual_active()) {
oneright();
} else {
- curwin->w_cursor.col += utfc_ptr2len((char *)get_cursor_pos_ptr());
+ curwin->w_cursor.col += utfc_ptr2len(get_cursor_pos_ptr());
}
}
}
@@ -4648,10 +3817,10 @@ static void nv_left(cmdarg_T *cap)
// Don't adjust op_end now, otherwise it won't work.
if ((cap->oap->op_type == OP_DELETE || cap->oap->op_type == OP_CHANGE)
&& !LINEEMPTY(curwin->w_cursor.lnum)) {
- char_u *cp = get_cursor_pos_ptr();
+ char *cp = get_cursor_pos_ptr();
if (*cp != NUL) {
- curwin->w_cursor.col += utfc_ptr2len((char *)cp);
+ curwin->w_cursor.col += utfc_ptr2len(cp);
}
cap->retval |= CA_NO_ADJ_OP_END;
}
@@ -4723,7 +3892,7 @@ static void nv_down(cmdarg_T *cap)
/// Grab the file name under the cursor and edit it.
static void nv_gotofile(cmdarg_T *cap)
{
- char_u *ptr;
+ char *ptr;
linenr_T lnum = -1;
if (check_text_locked(cap->oap)) {
@@ -4734,7 +3903,7 @@ static void nv_gotofile(cmdarg_T *cap)
return;
}
- ptr = grab_file_name(cap->count1, &lnum);
+ ptr = (char *)grab_file_name(cap->count1, &lnum);
if (ptr != NULL) {
// do autowrite if necessary
@@ -4742,7 +3911,7 @@ static void nv_gotofile(cmdarg_T *cap)
(void)autowrite(curbuf, false);
}
setpcmark();
- if (do_ecmd(0, (char *)ptr, NULL, NULL, ECMD_LAST,
+ if (do_ecmd(0, ptr, NULL, NULL, ECMD_LAST,
buf_hide(curbuf) ? ECMD_HIDE : 0, curwin) == OK
&& cap->nchar == 'F' && lnum >= 0) {
curwin->w_cursor.lnum = lnum;
@@ -4849,7 +4018,7 @@ static int normal_search(cmdarg_T *cap, int dir, char *pat, int opt, int *wrappe
curwin->w_set_curswant = true;
CLEAR_FIELD(sia);
- int i = do_search(cap->oap, dir, dir, (char_u *)pat, cap->count1,
+ int i = do_search(cap->oap, dir, dir, pat, cap->count1,
opt | SEARCH_OPT | SEARCH_ECHO | SEARCH_MSG, &sia);
if (wrapped != NULL) {
*wrapped = sia.sa_wrapped;
@@ -5058,7 +4227,7 @@ static void nv_brackets(cmdarg_T *cap)
} else {
// Make a copy, if the line was changed it will be freed.
ptr = xstrnsave(ptr, len);
- find_pattern_in_path((char_u *)ptr, 0, len, true,
+ find_pattern_in_path(ptr, 0, len, true,
cap->count0 == 0 ? !isupper(cap->nchar) : false,
(((cap->nchar & 0xf) == ('d' & 0xf))
? FIND_DEFINE
@@ -5151,9 +4320,8 @@ static void nv_brackets(cmdarg_T *cap)
cap->nchar == 's', false, NULL) == 0) {
clearopbeep(cap->oap);
break;
- } else {
- curwin->w_set_curswant = true;
}
+ curwin->w_set_curswant = true;
}
if (cap->oap->op_type == OP_NOP && (fdo_flags & FDO_SEARCH) && KeyTyped) {
foldOpenCursor();
@@ -5297,7 +4465,7 @@ static void nv_kundo(cmdarg_T *cap)
/// Handle the "r" command.
static void nv_replace(cmdarg_T *cap)
{
- char_u *ptr;
+ char *ptr;
int had_ctrl_v;
if (checkclearop(cap->oap)) {
@@ -5361,7 +4529,7 @@ static void nv_replace(cmdarg_T *cap)
// Abort if not enough characters to replace.
ptr = get_cursor_pos_ptr();
- if (STRLEN(ptr) < (unsigned)cap->count1
+ if (strlen(ptr) < (unsigned)cap->count1
|| (mb_charlen(ptr) < cap->count1)) {
clearopbeep(cap->oap);
return;
@@ -5692,6 +4860,10 @@ static void nv_gomark(cmdarg_T *cap)
{
int name;
MarkMove flags = jop_flags & JOP_VIEW ? kMarkSetView : 0; // flags for moving to the mark
+ if (cap->oap->op_type != OP_NOP) {
+ // When there is a pending operator, do not restore the view as this is usually unexpected.
+ flags = 0;
+ }
MarkMoveRes move_res = 0; // Result from moving to the mark
const bool old_KeyTyped = KeyTyped; // getting file may reset it
@@ -5743,7 +4915,7 @@ static void nv_pcmark(cmdarg_T *cap)
fm = get_changelist(curbuf, curwin, (int)cap->count1);
} else {
fm = get_jumplist(curwin, (int)cap->count1);
- flags |= KMarkNoContext | kMarkJumpList;
+ flags |= KMarkNoContext | kMarkJumpList;
}
// Changelist and jumplist have their own error messages. Therefore avoid
// calling nv_mark_move_to() when not found to avoid incorrect error
@@ -5841,10 +5013,12 @@ static void nv_visual(cmdarg_T *cap)
VIsual_mode = resel_VIsual_mode;
if (VIsual_mode == 'v') {
if (resel_VIsual_line_count <= 1) {
- validate_virtcol();
+ update_curswant_force();
assert(cap->count0 >= INT_MIN && cap->count0 <= INT_MAX);
- curwin->w_curswant = (curwin->w_virtcol
- + resel_VIsual_vcol * (int)cap->count0 - 1);
+ curwin->w_curswant += resel_VIsual_vcol * (int)cap->count0;
+ if (*p_sel != 'e') {
+ curwin->w_curswant--;
+ }
} else {
curwin->w_curswant = resel_VIsual_vcol;
}
@@ -5854,10 +5028,9 @@ static void nv_visual(cmdarg_T *cap)
curwin->w_curswant = MAXCOL;
coladvance(MAXCOL);
} else if (VIsual_mode == Ctrl_V) {
- validate_virtcol();
+ update_curswant_force();
assert(cap->count0 >= INT_MIN && cap->count0 <= INT_MAX);
- curwin->w_curswant = (curwin->w_virtcol
- + resel_VIsual_vcol * (int)cap->count0 - 1);
+ curwin->w_curswant += resel_VIsual_vcol * (int)cap->count0 - 1;
coladvance(curwin->w_curswant);
} else {
curwin->w_set_curswant = true;
@@ -6068,7 +5241,7 @@ static void nv_g_underscore_cmd(cmdarg_T *cap)
return;
}
- char_u *ptr = get_cursor_line_ptr();
+ char *ptr = get_cursor_line_ptr();
// In Visual mode we may end up after the line.
if (curwin->w_cursor.col > 0 && ptr[curwin->w_cursor.col] == NUL) {
@@ -6106,9 +5279,7 @@ static void nv_g_dollar_cmd(cmdarg_T *cap)
coladvance((colnr_T)i);
// Make sure we stick in this column.
- validate_virtcol();
- curwin->w_curswant = curwin->w_virtcol;
- curwin->w_set_curswant = false;
+ update_curswant_force();
if (curwin->w_cursor.col > 0 && curwin->w_p_wrap) {
// Check for landing on a character that got split at
// the end of the line. We do not want to advance to
@@ -6139,9 +5310,7 @@ static void nv_g_dollar_cmd(cmdarg_T *cap)
}
// Make sure we stick in this column.
- validate_virtcol();
- curwin->w_curswant = curwin->w_virtcol;
- curwin->w_set_curswant = false;
+ update_curswant_force();
}
}
@@ -6151,7 +5320,7 @@ static void nv_gi_cmd(cmdarg_T *cap)
if (curbuf->b_last_insert.mark.lnum != 0) {
curwin->w_cursor = curbuf->b_last_insert.mark;
check_cursor_lnum();
- int i = (int)STRLEN(get_cursor_line_ptr());
+ int i = (int)strlen(get_cursor_line_ptr());
if (curwin->w_cursor.col > (colnr_T)i) {
if (virtual_active()) {
curwin->w_cursor.coladd += curwin->w_cursor.col - i;
@@ -6513,8 +5682,7 @@ static void n_opencmd(cmdarg_T *cap)
if (u_save((linenr_T)(curwin->w_cursor.lnum -
(cap->cmdchar == 'O' ? 1 : 0)),
(linenr_T)(curwin->w_cursor.lnum +
- (cap->cmdchar == 'o' ? 1 : 0))
- )
+ (cap->cmdchar == 'o' ? 1 : 0)))
&& open_line(cap->cmdchar == 'O' ? BACKWARD : FORWARD,
has_format_option(FO_OPEN_COMS) ? OPENLINE_DO_COM : 0,
0, NULL)) {
@@ -6834,7 +6002,7 @@ bool unadjust_for_sel(void)
mark_mb_adjustpos(curbuf, pp);
} else if (pp->lnum > 1) {
pp->lnum--;
- pp->col = (colnr_T)STRLEN(ml_get(pp->lnum));
+ pp->col = (colnr_T)strlen(ml_get(pp->lnum));
return true;
}
}
@@ -6917,10 +6085,7 @@ static void nv_esc(cmdarg_T *cap)
&& cap->oap->regname == 0);
if (cap->arg) { // true for CTRL-C
- if (restart_edit == 0
- && cmdwin_type == 0
- && !VIsual_active
- && no_reason) {
+ if (restart_edit == 0 && cmdwin_type == 0 && !VIsual_active && no_reason) {
if (anyBufIsChanged()) {
msg(_("Type :qa! and press <Enter> to abandon all changes"
" and exit Nvim"));
@@ -6971,7 +6136,7 @@ void set_cursor_for_append_to_line(void)
coladvance(MAXCOL);
State = save_State;
} else {
- curwin->w_cursor.col += (colnr_T)STRLEN(get_cursor_pos_ptr());
+ curwin->w_cursor.col += (colnr_T)strlen(get_cursor_pos_ptr());
}
}
@@ -7064,7 +6229,7 @@ static void nv_object(cmdarg_T *cap)
{
bool flag;
bool include;
- char_u *mps_save;
+ char *mps_save;
if (cap->cmdchar == 'i') {
include = false; // "ix" = inner object: exclude white space
@@ -7072,7 +6237,7 @@ static void nv_object(cmdarg_T *cap)
include = true; // "ax" = an object: include white space
}
// Make sure (), [], {} and <> are in 'matchpairs'
- mps_save = (char_u *)curbuf->b_p_mps;
+ mps_save = curbuf->b_p_mps;
curbuf->b_p_mps = "(:),{:},[:],<:>";
switch (cap->nchar) {
@@ -7127,7 +6292,7 @@ static void nv_object(cmdarg_T *cap)
break;
}
- curbuf->b_p_mps = (char *)mps_save;
+ curbuf->b_p_mps = mps_save;
if (!flag) {
clearopbeep(cap->oap);
}
@@ -7396,12 +6561,6 @@ static void nv_event(cmdarg_T *cap)
}
}
-/// @return true when 'mousemodel' is set to "popup" or "popup_setpos".
-static bool mouse_model_popup(void)
-{
- return p_mousem[0] == 'p';
-}
-
void normal_cmd(oparg_T *oap, bool toplevel)
{
NormalState s;