aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/ops.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/ops.c')
-rw-r--r--src/nvim/ops.c65
1 files changed, 45 insertions, 20 deletions
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index af738d3fa9..78eebc520f 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -4213,7 +4213,7 @@ int do_addsub(int command, linenr_T Prenum1, bool g_cmd)
int pre; // 'X' or 'x': hex; '0': octal; 'B' or 'b': bin
static bool hexupper = false; // 0xABC
unsigned long n;
- long offset = 0;
+ unsigned long offset = 0;
unsigned long oldn;
char_u *ptr;
int c;
@@ -4226,9 +4226,11 @@ int do_addsub(int command, linenr_T Prenum1, bool g_cmd)
int firstdigit;
bool subtract;
bool negative = false;
+ bool was_positive = true;
bool visual = VIsual_active;
int lnum = curwin->w_cursor.lnum;
int lnume = curwin->w_cursor.lnum;
+ int startcol;
dohex = (vim_strchr(curbuf->b_p_nf, 'x') != NULL); // "heX"
dooct = (vim_strchr(curbuf->b_p_nf, 'o') != NULL); // "Octal"
@@ -4255,13 +4257,16 @@ int do_addsub(int command, linenr_T Prenum1, bool g_cmd)
curbuf->b_visual.vi_end = curwin->w_cursor;
curbuf->b_visual.vi_mode = VIsual_mode;
- col = VIsual.col;
+ if (VIsual_mode != 'v') {
+ startcol = VIsual.col < curwin->w_cursor.col
+ ? VIsual.col : curwin->w_cursor.col;
+ } else {
+ startcol = VIsual.col;
+ }
+ col = startcol;
+
lnum = VIsual.lnum;
lnume = curwin->w_cursor.lnum;
- if (ptr[col] == '-') {
- negative = true;
- col++;
- }
} else {
ptr = get_cursor_line_ptr();
RLADDSUBFIX(ptr);
@@ -4328,10 +4333,16 @@ int do_addsub(int command, linenr_T Prenum1, bool g_cmd)
for (int i = lnum; i <= lnume; i++) {
curwin->w_cursor.lnum = i;
ptr = get_cursor_line_ptr();
- RLADDSUBFIX(ptr);
if ((int)STRLEN(ptr) <= col) {
- col = 0;
+ // try again on next line
+ continue;
+ }
+ if (visual && ptr[col] == '-') {
+ negative = true;
+ was_positive = false;
+ col++;
}
+ RLADDSUBFIX(ptr);
// If a number was found, and saving for undo works, replace the number.
firstdigit = ptr[col];
RLADDSUBFIX(ptr);
@@ -4424,6 +4435,12 @@ int do_addsub(int command, linenr_T Prenum1, bool g_cmd)
}
}
+ if (visual && !was_positive && !negative) {
+ // need to remove the '-'
+ col--;
+ length++;
+ }
+
// Delete the old number.
curwin->w_cursor.col = col;
todel = length;
@@ -4452,8 +4469,7 @@ int do_addsub(int command, linenr_T Prenum1, bool g_cmd)
// Allocate a bit too much.
buf1 = xmalloc(length + NUMBUFLEN);
ptr = buf1;
- // do not add leading '-' for visual mode'
- if (negative && !visual) {
+ if (negative && (!visual || (visual && was_positive))) {
*ptr++ = '-';
}
if (pre) {
@@ -4483,21 +4499,16 @@ int do_addsub(int command, linenr_T Prenum1, bool g_cmd)
buf2[pos] = '\0';
} else if (pre == 0) {
- snprintf((char *)buf2, NUMBUFLEN, "%" PRIu64, (uint64_t)n + offset);
+ vim_snprintf((char *)buf2, ARRAY_SIZE(buf2), "%" PRIu64, (uint64_t)n);
} else if (pre == '0') {
- snprintf((char *)buf2, NUMBUFLEN, "%" PRIo64, (uint64_t)n + offset);
+ vim_snprintf((char *)buf2, ARRAY_SIZE(buf2), "%" PRIo64, (uint64_t)n);
} else if (pre && hexupper) {
- snprintf((char *)buf2, NUMBUFLEN, "%" PRIX64, (uint64_t)n + offset);
+ vim_snprintf((char *)buf2, ARRAY_SIZE(buf2), "%" PRIX64, (uint64_t)n);
} else {
- snprintf((char *)buf2, NUMBUFLEN, "%" PRIx64, (uint64_t)n + offset);
+ vim_snprintf((char *)buf2, ARRAY_SIZE(buf2), "%" PRIx64, (uint64_t)n);
}
length -= (int)STRLEN(buf2);
- if (g_cmd) {
- offset = subtract ? offset - (unsigned long) Prenum1
- : offset + (unsigned long) Prenum1;
- }
-
// Adjust number of zeros to the new number of digits, so the
// total length of the number remains the same.
// Don't do this when
@@ -4512,11 +4523,25 @@ int do_addsub(int command, linenr_T Prenum1, bool g_cmd)
ins_str(buf1); // insert the new number
xfree(buf1);
}
- curwin->w_cursor.col--;
+
+ if (g_cmd) {
+ offset = (unsigned long)Prenum1;
+ g_cmd = 0;
+ }
+ // reset
+ subtract = false;
+ negative = false;
+ if (visual && VIsual_mode != Ctrl_V) {
+ col = 0;
+ } else {
+ col = startcol;
+ }
+ Prenum1 += offset;
curwin->w_set_curswant = true;
ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum, true);
RLADDSUBFIX(ptr);
}
+ curwin->w_cursor.col--;
return OK;
}