mirror of
https://github.com/neovim/neovim.git
synced 2025-11-28 05:00:44 +00:00
nsmarks: initial commit
This commit is contained in:
185
src/nvim/ops.c
185
src/nvim/ops.c
@@ -49,6 +49,7 @@
|
||||
#include "nvim/undo.h"
|
||||
#include "nvim/macros.h"
|
||||
#include "nvim/window.h"
|
||||
#include "nvim/lib/kvec.h"
|
||||
#include "nvim/os/input.h"
|
||||
#include "nvim/os/time.h"
|
||||
|
||||
@@ -126,6 +127,30 @@ static char opchars[][3] =
|
||||
{ Ctrl_X, NUL, false }, // OP_NR_SUB
|
||||
};
|
||||
|
||||
char *nvim_lltoa(int64_t val, int base)
|
||||
{
|
||||
static char buf[64] = { 0 };
|
||||
|
||||
int i = 62;
|
||||
int sign = (val < 0);
|
||||
if (sign) {
|
||||
val = -val;
|
||||
}
|
||||
|
||||
if (val == 0) {
|
||||
return "0";
|
||||
}
|
||||
|
||||
for (; val && i ; i--, val /= base) {
|
||||
buf[i] = "0123456789abcdef"[val % base];
|
||||
}
|
||||
|
||||
if (sign) {
|
||||
buf[i--] = '-';
|
||||
}
|
||||
return &buf[i+1];
|
||||
}
|
||||
|
||||
/*
|
||||
* Translate a command name into an operator type.
|
||||
* Must only be called with a valid operator name!
|
||||
@@ -306,6 +331,20 @@ void shift_line(
|
||||
change_indent(INDENT_SET, count, false, NUL, call_changed_bytes);
|
||||
} else {
|
||||
(void)set_indent(count, call_changed_bytes ? SIN_CHANGED : 0);
|
||||
|
||||
colnr_T col_amount;
|
||||
colnr_T mincol = (curwin->w_cursor.col + 1) -p_sw;
|
||||
if (left) {
|
||||
col_amount = -p_sw;
|
||||
} else {
|
||||
col_amount = p_sw;
|
||||
}
|
||||
extmark_col_adjust(curbuf,
|
||||
curwin->w_cursor.lnum,
|
||||
mincol,
|
||||
0,
|
||||
col_amount,
|
||||
kExtmarkUndo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -479,6 +518,13 @@ static void shift_block(oparg_T *oap, int amount)
|
||||
State = oldstate;
|
||||
curwin->w_cursor.col = oldcol;
|
||||
p_ri = old_p_ri;
|
||||
|
||||
colnr_T col_amount = p_sw;
|
||||
if (left) {
|
||||
col_amount = -col_amount;
|
||||
}
|
||||
extmark_col_adjust(curbuf, curwin->w_cursor.lnum,
|
||||
curwin->w_cursor.col, 0, col_amount, kExtmarkUndo);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -623,10 +669,19 @@ void op_reindent(oparg_T *oap, Indenter how)
|
||||
amount = how(); /* get the indent for this line */
|
||||
|
||||
if (amount >= 0 && set_indent(amount, SIN_UNDO)) {
|
||||
/* did change the indent, call changed_lines() later */
|
||||
if (first_changed == 0)
|
||||
// did change the indent, call changed_lines() later
|
||||
if (first_changed == 0) {
|
||||
first_changed = curwin->w_cursor.lnum;
|
||||
}
|
||||
last_changed = curwin->w_cursor.lnum;
|
||||
|
||||
// Adjust extmarks
|
||||
extmark_col_adjust(curbuf,
|
||||
curwin->w_cursor.lnum,
|
||||
0, // mincol
|
||||
0, // lnum_amount
|
||||
amount, // col_amount
|
||||
kExtmarkUndo);
|
||||
}
|
||||
}
|
||||
++curwin->w_cursor.lnum;
|
||||
@@ -1614,13 +1669,15 @@ int op_delete(oparg_T *oap)
|
||||
|
||||
curpos = curwin->w_cursor; // remember curwin->w_cursor
|
||||
curwin->w_cursor.lnum++;
|
||||
del_lines(oap->line_count - 2, false);
|
||||
del_lines(oap->line_count - 2, true);
|
||||
|
||||
// delete from start of line until op_end
|
||||
n = (oap->end.col + 1 - !oap->inclusive);
|
||||
curwin->w_cursor.col = 0;
|
||||
(void)del_bytes((colnr_T)n, !virtual_op,
|
||||
oap->op_type == OP_DELETE && !oap->is_VIsual);
|
||||
extmark_col_adjust(curbuf, curwin->w_cursor.lnum,
|
||||
(colnr_T)0, 0L, (long)-n, kExtmarkUndo);
|
||||
curwin->w_cursor = curpos; // restore curwin->w_cursor
|
||||
(void)do_join(2, false, false, false, false);
|
||||
}
|
||||
@@ -1632,10 +1689,41 @@ setmarks:
|
||||
if (oap->motion_type == kMTBlockWise) {
|
||||
curbuf->b_op_end.lnum = oap->end.lnum;
|
||||
curbuf->b_op_end.col = oap->start.col;
|
||||
} else
|
||||
} else {
|
||||
curbuf->b_op_end = oap->start;
|
||||
}
|
||||
curbuf->b_op_start = oap->start;
|
||||
|
||||
// TODO(timeyyy): refactor: Move extended marks
|
||||
// + 1 to change to buf mode,
|
||||
// and + 1 because we only move marks after the deleted col
|
||||
colnr_T mincol = oap->start.col + 1 + 1;
|
||||
colnr_T endcol;
|
||||
if (oap->motion_type == kMTBlockWise) {
|
||||
// TODO(timeyyy): refactor extmark_col_adjust to take lnumstart, lnum_end ?
|
||||
endcol = bd.end_vcol + 1;
|
||||
for (lnum = curwin->w_cursor.lnum; lnum <= oap->end.lnum; lnum++) {
|
||||
extmark_col_adjust_delete(curbuf, lnum, mincol, endcol,
|
||||
kExtmarkUndo, 0);
|
||||
}
|
||||
|
||||
// Delete characters within one line,
|
||||
// The case with multiple lines is handled by do_join
|
||||
} else if (oap->motion_type == kMTCharWise && oap->line_count == 1) {
|
||||
// + 1 to change to buf mode, then plus 1 to fit function requirements
|
||||
endcol = oap->end.col + 1 + 1;
|
||||
|
||||
lnum = curwin->w_cursor.lnum;
|
||||
if (oap->is_VIsual == false) {
|
||||
// for some reason we required this :/
|
||||
endcol = endcol - 1;
|
||||
// for some reason we required this :/
|
||||
if (endcol < mincol) {
|
||||
endcol = mincol;
|
||||
}
|
||||
}
|
||||
extmark_col_adjust_delete(curbuf, lnum, mincol, endcol, kExtmarkUndo, 0);
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -2031,8 +2119,8 @@ bool swapchar(int op_type, pos_T *pos)
|
||||
pos_T sp = curwin->w_cursor;
|
||||
|
||||
curwin->w_cursor = *pos;
|
||||
/* don't use del_char(), it also removes composing chars */
|
||||
del_bytes(utf_ptr2len(get_cursor_pos_ptr()), FALSE, FALSE);
|
||||
// don't use del_char(), it also removes composing chars
|
||||
del_bytes(utf_ptr2len(get_cursor_pos_ptr()), false, false);
|
||||
ins_char(nc);
|
||||
curwin->w_cursor = sp;
|
||||
} else {
|
||||
@@ -2105,8 +2193,9 @@ void op_insert(oparg_T *oap, long count1)
|
||||
* values in "bd". */
|
||||
if (u_save_cursor() == FAIL)
|
||||
return;
|
||||
for (i = 0; i < bd.endspaces; i++)
|
||||
for (i = 0; i < bd.endspaces; i++) {
|
||||
ins_char(' ');
|
||||
}
|
||||
bd.textlen += bd.endspaces;
|
||||
}
|
||||
} else {
|
||||
@@ -2224,6 +2313,10 @@ void op_insert(oparg_T *oap, long count1)
|
||||
xfree(ins_text);
|
||||
}
|
||||
}
|
||||
colnr_T col = oap->start.col;
|
||||
for (linenr_T lnum = oap->start.lnum; lnum <= oap->end.lnum; lnum++) {
|
||||
extmark_col_adjust(curbuf, lnum, col, 0, 1, kExtmarkUndo);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2694,6 +2787,34 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg)
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Function length couldn't be over 500 lines..
|
||||
static void extmarks_do_put(int dir,
|
||||
size_t totlen,
|
||||
MotionType y_type,
|
||||
linenr_T lnum,
|
||||
colnr_T col)
|
||||
{
|
||||
// adjust extmarks
|
||||
colnr_T col_amount;
|
||||
if (dir == FORWARD) {
|
||||
col_amount = (colnr_T)(totlen-1);
|
||||
} else {
|
||||
col_amount = (colnr_T)totlen;
|
||||
}
|
||||
// Move extmark with char put
|
||||
if (y_type == kMTCharWise) {
|
||||
extmark_col_adjust(curbuf, lnum, col, 0, col_amount, kExtmarkUndo);
|
||||
// Move extmark with blockwise put
|
||||
} else if (y_type == kMTBlockWise) {
|
||||
for (lnum = curbuf->b_op_start.lnum;
|
||||
lnum <= curbuf->b_op_end.lnum;
|
||||
lnum++) {
|
||||
extmark_col_adjust(curbuf, lnum, col, 0, col_amount, kExtmarkUndo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Put contents of register "regname" into the text.
|
||||
* Caller must check "regname" to be valid!
|
||||
@@ -2708,8 +2829,8 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
|
||||
char_u *oldp;
|
||||
int yanklen;
|
||||
size_t totlen = 0; // init for gcc
|
||||
linenr_T lnum;
|
||||
colnr_T col;
|
||||
linenr_T lnum = 0;
|
||||
colnr_T col = 0;
|
||||
size_t i; // index in y_array[]
|
||||
MotionType y_type;
|
||||
size_t y_size;
|
||||
@@ -3286,11 +3407,11 @@ error:
|
||||
curbuf->b_op_start.lnum++;
|
||||
}
|
||||
// Skip mark_adjust when adding lines after the last one, there
|
||||
// can't be marks there. But still needed in diff mode.
|
||||
// can't be marks there.
|
||||
if (curbuf->b_op_start.lnum + (y_type == kMTCharWise) - 1 + nr_lines
|
||||
< curbuf->b_ml.ml_line_count || curwin->w_p_diff) {
|
||||
< curbuf->b_ml.ml_line_count) {
|
||||
mark_adjust(curbuf->b_op_start.lnum + (y_type == kMTCharWise),
|
||||
(linenr_T)MAXLNUM, nr_lines, 0L, false);
|
||||
(linenr_T)MAXLNUM, nr_lines, 0L, false, kExtmarkUndo);
|
||||
}
|
||||
|
||||
// note changed text for displaying and folding
|
||||
@@ -3352,6 +3473,8 @@ end:
|
||||
|
||||
/* If the cursor is past the end of the line put it at the end. */
|
||||
adjust_cursor_eol();
|
||||
|
||||
extmarks_do_put(dir, totlen, y_type, lnum, col);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3745,6 +3868,12 @@ int do_join(size_t count,
|
||||
* column. This is not Vi compatible, but Vi deletes the marks, thus that
|
||||
* should not really be a problem.
|
||||
*/
|
||||
|
||||
linenr_T lnum;
|
||||
colnr_T mincol;
|
||||
long lnum_amount;
|
||||
long col_amount;
|
||||
|
||||
for (t = (linenr_T)count - 1;; t--) {
|
||||
cend -= currsize;
|
||||
memmove(cend, curr, (size_t)currsize);
|
||||
@@ -3756,12 +3885,18 @@ int do_join(size_t count,
|
||||
// If deleting more spaces than adding, the cursor moves no more than
|
||||
// what is added if it is inside these spaces.
|
||||
const int spaces_removed = (int)((curr - curr_start) - spaces[t]);
|
||||
lnum = curwin->w_cursor.lnum + t;
|
||||
mincol = (colnr_T)0;
|
||||
lnum_amount = (linenr_T)-t;
|
||||
col_amount = (long)(cend - newp - spaces_removed);
|
||||
|
||||
mark_col_adjust(lnum, mincol, lnum_amount, col_amount, spaces_removed,
|
||||
kExtmarkUndo);
|
||||
|
||||
mark_col_adjust(curwin->w_cursor.lnum + t, (colnr_T)0, (linenr_T)-t,
|
||||
(long)(cend - newp - spaces_removed), spaces_removed);
|
||||
if (t == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
curr = curr_start = ml_get((linenr_T)(curwin->w_cursor.lnum + t - 1));
|
||||
if (remove_comments)
|
||||
curr += comments[t - 1];
|
||||
@@ -3769,6 +3904,7 @@ int do_join(size_t count,
|
||||
curr = skipwhite(curr);
|
||||
currsize = (int)STRLEN(curr);
|
||||
}
|
||||
|
||||
ml_replace(curwin->w_cursor.lnum, newp, false);
|
||||
|
||||
if (setmark) {
|
||||
@@ -4189,14 +4325,14 @@ format_lines(
|
||||
if (next_leader_len > 0) {
|
||||
(void)del_bytes(next_leader_len, false, false);
|
||||
mark_col_adjust(curwin->w_cursor.lnum, (colnr_T)0, 0L,
|
||||
(long)-next_leader_len, 0);
|
||||
(long)-next_leader_len, 0, kExtmarkUndo);
|
||||
} else if (second_indent > 0) { // the "leader" for FO_Q_SECOND
|
||||
int indent = (int)getwhitecols_curline();
|
||||
|
||||
if (indent > 0) {
|
||||
(void)del_bytes(indent, FALSE, FALSE);
|
||||
mark_col_adjust(curwin->w_cursor.lnum,
|
||||
(colnr_T)0, 0L, (long)-indent, 0);
|
||||
(colnr_T)0, 0L, (long)-indent, 0, kExtmarkUndo);
|
||||
}
|
||||
}
|
||||
curwin->w_cursor.lnum--;
|
||||
@@ -4862,6 +4998,23 @@ int do_addsub(int op_type, pos_T *pos, int length, linenr_T Prenum1)
|
||||
curbuf->b_op_end.col--;
|
||||
}
|
||||
|
||||
if (did_change) {
|
||||
extmark_col_adjust_delete(curbuf,
|
||||
pos->lnum,
|
||||
startpos.col + 2,
|
||||
endpos.col + 1 + length,
|
||||
kExtmarkUndo,
|
||||
0);
|
||||
long col_amount = (long)strlen(nvim_lltoa((int64_t)n, 10));
|
||||
col_amount = negative ? col_amount + 1 : col_amount;
|
||||
extmark_col_adjust(curbuf,
|
||||
pos->lnum,
|
||||
startpos.col + 1,
|
||||
0,
|
||||
col_amount,
|
||||
kExtmarkUndo);
|
||||
}
|
||||
|
||||
theend:
|
||||
if (visual) {
|
||||
curwin->w_cursor = save_cursor;
|
||||
|
||||
Reference in New Issue
Block a user