nsmarks: initial commit

This commit is contained in:
timeyyy
2017-01-18 13:20:07 +01:00
committed by Björn Linse
parent e757f4d536
commit a9065a5051
27 changed files with 3968 additions and 81 deletions

View File

@@ -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;