diff options
Diffstat (limited to 'src/nvim/normal.c')
-rw-r--r-- | src/nvim/normal.c | 113 |
1 files changed, 56 insertions, 57 deletions
diff --git a/src/nvim/normal.c b/src/nvim/normal.c index aeb85eba1c..d491a0ce84 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -4983,19 +4983,22 @@ static void nv_brackets(cmdarg_T *cap) nv_put_opt(cap, true); } else if (cap->nchar == '\'' || cap->nchar == '`') { // "['", "[`", "]'" and "]`": jump to next mark + fmark_T *fm = NULL; pos = &curwin->w_cursor; for (n = cap->count1; n > 0; n--) { prev_pos = *pos; - pos = getnextmark(pos, cap->cmdchar == '[' ? BACKWARD : FORWARD, - cap->nchar == '\''); + fm = getnextmark(pos, cap->cmdchar == '[' ? BACKWARD : FORWARD, + cap->nchar == '\''); if (pos == NULL) { break; + } else { + pos = fm != NULL ? &fm->mark : NULL; // Adjust for the next iteration. } } - if (pos == NULL) { - pos = &prev_pos; - } - nv_cursormark(cap, cap->nchar == '\'', pos); + fm = fm == NULL ? pos_to_mark(curbuf, NULL, curwin->w_cursor) : fm; + MarkMove flags = kMarkContext; + flags |= cap->nchar == '\'' ? kMarkBeginLine: 0; + nv_mark_move_to(cap, flags, fm); } else if (cap->nchar >= K_RIGHTRELEASE && cap->nchar <= K_LEFTMOUSE) { // [ or ] followed by a middle mouse click: put selected text with // indent adjustment. Any other button just does as usual. @@ -5465,31 +5468,28 @@ static void n_swapchar(cmdarg_T *cap) } } -/// Move cursor to mark. -static void nv_cursormark(cmdarg_T *cap, int flag, pos_T *pos) -{ - if (check_mark(pos) == false) { +/// Move the cursor to the mark position +/// +/// Wrapper to mark_move_to() that also handles normal mode command arguments. +/// @note It will switch the buffer if neccesarry, move the cursor and set the +/// view depending on the given flags. +/// @param cap command line arguments +/// @param flags for mark_move_to() +/// @param mark mark +/// @return The result of calling mark_move_to() +static MarkMoveRes nv_mark_move_to(cmdarg_T *cap, MarkMove flags, fmark_T *fm) +{ + MarkMoveRes res = mark_move_to(fm, flags); + if (res & kMarkMoveFailed) { clearop(cap->oap); - } else { - if (cap->cmdchar == '\'' - || cap->cmdchar == '`' - || cap->cmdchar == '[' - || cap->cmdchar == ']') { - setpcmark(); - } - curwin->w_cursor = *pos; - if (flag) { - beginline(BL_WHITE | BL_FIX); - } else { - check_cursor(); - } } - cap->oap->motion_type = flag ? kMTLineWise : kMTCharWise; + cap->oap->motion_type = flags & kMarkBeginLine ? kMTLineWise : kMTCharWise; if (cap->cmdchar == '`') { cap->oap->use_reg_one = true; } cap->oap->inclusive = false; // ignored if not kMTCharWise curwin->w_set_curswant = true; + return res; } /// Handle commands that are operators in Visual mode. @@ -5564,36 +5564,32 @@ static void nv_optrans(cmdarg_T *cap) /// cap->arg is true for "'" and "g'". static void nv_gomark(cmdarg_T *cap) { - pos_T *pos; - int c; - pos_T old_cursor = curwin->w_cursor; - const bool old_KeyTyped = KeyTyped; // getting file may reset it + int name; + MarkMove flags = jop_flags & JOP_VIEW ? kMarkSetView : 0; // flags for moving to the mark + MarkMoveRes move_res = 0; // Result from moving to the mark + const bool old_KeyTyped = KeyTyped; // getting file may reset it if (cap->cmdchar == 'g') { - c = cap->extra_char; - } else { - c = cap->nchar; - } - pos = getmark(c, (cap->oap->op_type == OP_NOP)); - if (pos == (pos_T *)-1) { // jumped to other file - if (cap->arg) { - check_cursor_lnum(); - beginline(BL_WHITE | BL_FIX); - } else { - check_cursor(); - } + name = cap->extra_char; + flags |= KMarkNoContext; } else { - nv_cursormark(cap, cap->arg, pos); + name = cap->nchar; + flags |= kMarkContext; } + flags |= cap->arg ? kMarkBeginLine : 0; + flags |= cap->count0 ? kMarkSetView : 0; + + fmark_T *fm = mark_get(curbuf, curwin, NULL, kMarkAll, name); + move_res = nv_mark_move_to(cap, flags, fm); // May need to clear the coladd that a mark includes. if (!virtual_active()) { curwin->w_cursor.coladd = 0; } - check_cursor_col(); + if (cap->oap->op_type == OP_NOP - && pos != NULL - && (pos == (pos_T *)-1 || !equalpos(old_cursor, *pos)) + && move_res & kMarkMoveSuccess + && (move_res & kMarkSwitchedBuf || move_res & kMarkChangedCursor) && (fdo_flags & FDO_MARK) && old_KeyTyped) { foldOpenCursor(); @@ -5601,11 +5597,13 @@ static void nv_gomark(cmdarg_T *cap) } /// Handle CTRL-O, CTRL-I, "g;", "g,", and "CTRL-Tab" commands. +/// Movement in the jumplist and changelist. static void nv_pcmark(cmdarg_T *cap) { - pos_T *pos; - linenr_T lnum = curwin->w_cursor.lnum; - const bool old_KeyTyped = KeyTyped; // getting file may reset it + fmark_T *fm = NULL; + MarkMove flags = jop_flags & JOP_VIEW ? kMarkSetView : 0; // flags for moving to the mark + MarkMoveRes move_res = 0; // Result from moving to the mark + const bool old_KeyTyped = KeyTyped; // getting file may reset it. if (!checkclearopq(cap->oap)) { if (cap->cmdchar == TAB && mod_mask == MOD_MASK_CTRL) { @@ -5614,16 +5612,18 @@ static void nv_pcmark(cmdarg_T *cap) } return; } + if (cap->cmdchar == 'g') { - pos = movechangelist((int)cap->count1); + fm = get_changelist(curbuf, curwin, (int)cap->count1); } else { - pos = movemark((int)cap->count1); - } - if (pos == (pos_T *)-1) { // jump to other file - curwin->w_set_curswant = true; - check_cursor(); - } else if (pos != NULL) { // can jump - nv_cursormark(cap, false, pos); + fm = get_jumplist(curwin, (int)cap->count1); + 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 + // messages. + if (fm != NULL) { + move_res = nv_mark_move_to(cap, flags, fm); } else if (cap->cmdchar == 'g') { if (curbuf->b_changelistlen == 0) { emsg(_("E664: changelist is empty")); @@ -5636,7 +5636,7 @@ static void nv_pcmark(cmdarg_T *cap) clearopbeep(cap->oap); } if (cap->oap->op_type == OP_NOP - && (pos == (pos_T *)-1 || lnum != curwin->w_cursor.lnum) + && (move_res & kMarkSwitchedBuf || move_res & kMarkChangedLine) && (fdo_flags & FDO_MARK) && old_KeyTyped) { foldOpenCursor(); @@ -6804,7 +6804,6 @@ void set_cursor_for_append_to_line(void) curwin->w_set_curswant = true; if (get_ve_flags() == VE_ALL) { const int save_State = State; - // Pretend Insert mode here to allow the cursor on the // character past the end of the line State = MODE_INSERT; |