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.c43
1 files changed, 25 insertions, 18 deletions
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index 8f22243348..d5c92bc3e6 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -5225,16 +5225,13 @@ static void nv_left(cmdarg_T *cap)
* 'h' wraps to previous line if 'whichwrap' has 'h'.
* CURS_LEFT wraps to previous line if 'whichwrap' has '<'.
*/
- if ( (((cap->cmdchar == K_BS
- || cap->cmdchar == Ctrl_H)
- && vim_strchr(p_ww, 'b') != NULL)
- || (cap->cmdchar == 'h'
- && vim_strchr(p_ww, 'h') != NULL)
- || (cap->cmdchar == K_LEFT
- && vim_strchr(p_ww, '<') != NULL))
- && curwin->w_cursor.lnum > 1) {
- --(curwin->w_cursor.lnum);
- coladvance((colnr_T)MAXCOL);
+ if ((((cap->cmdchar == K_BS || cap->cmdchar == Ctrl_H)
+ && vim_strchr(p_ww, 'b') != NULL)
+ || (cap->cmdchar == 'h' && vim_strchr(p_ww, 'h') != NULL)
+ || (cap->cmdchar == K_LEFT && vim_strchr(p_ww, '<') != NULL))
+ && curwin->w_cursor.lnum > 1) {
+ curwin->w_cursor.lnum--;
+ coladvance(MAXCOL);
curwin->w_set_curswant = true;
// When the NL before the first char has to be deleted we
@@ -5792,16 +5789,20 @@ static void nv_percent(cmdarg_T *cap)
} else {
cap->oap->motion_type = kMTLineWise;
setpcmark();
- /* Round up, so CTRL-G will give same value. Watch out for a
- * large line count, the line number must not go negative! */
- if (curbuf->b_ml.ml_line_count > 1000000)
+ // Round up, so 'normal 100%' always jumps at the line line.
+ // Beyond 21474836 lines, (ml_line_count * 100 + 99) would
+ // overflow on 32-bits, so use a formula with less accuracy
+ // to avoid overflows.
+ if (curbuf->b_ml.ml_line_count >= 21474836) {
curwin->w_cursor.lnum = (curbuf->b_ml.ml_line_count + 99L)
/ 100L * cap->count0;
- else
+ } else {
curwin->w_cursor.lnum = (curbuf->b_ml.ml_line_count *
cap->count0 + 99L) / 100L;
- if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count)
+ }
+ if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count) {
curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
+ }
beginline(BL_SOL | BL_FIX);
}
} else { // "%" : go to matching paren
@@ -6467,7 +6468,7 @@ static void nv_visual(cmdarg_T *cap)
}
if (resel_VIsual_vcol == MAXCOL) {
curwin->w_curswant = MAXCOL;
- coladvance((colnr_T)MAXCOL);
+ coladvance(MAXCOL);
} else if (VIsual_mode == Ctrl_V) {
validate_virtcol();
assert(cap->count0 >= INT_MIN && cap->count0 <= INT_MAX);
@@ -7570,6 +7571,12 @@ static void nv_esc(cmdarg_T *cap)
got_int = false; /* don't stop executing autocommands et al. */
return;
}
+ } else if (cmdwin_type != 0 && ex_normal_busy) {
+ // When :normal runs out of characters while in the command line window
+ // vgetorpeek() will return ESC. Exit the cmdline window to break the
+ // loop.
+ cmdwin_result = K_IGNORE;
+ return;
}
if (VIsual_active) {
@@ -7600,7 +7607,7 @@ void set_cursor_for_append_to_line(void)
// Pretend Insert mode here to allow the cursor on the
// character past the end of the line
State = INSERT;
- coladvance((colnr_T)MAXCOL);
+ coladvance(MAXCOL);
State = save_State;
} else {
curwin->w_cursor.col += (colnr_T)STRLEN(get_cursor_pos_ptr());
@@ -7988,7 +7995,7 @@ static void nv_put_opt(cmdarg_T *cap, bool fix_indent)
* line. */
if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count) {
curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
- coladvance((colnr_T)MAXCOL);
+ coladvance(MAXCOL);
}
}
auto_format(false, true);