aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/ops.c
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2024-02-23 06:57:07 +0800
committerGitHub <noreply@github.com>2024-02-23 06:57:07 +0800
commit564fd1cc51db4f5a954da236d1abad9d8acc3b6e (patch)
tree8ae78d3ec9a066e878bee42195d1da8896fa8fca /src/nvim/ops.c
parentbb15fa035610bb9765ca16900703804a88faa3bb (diff)
parent1f75184b5cd4db7c250b1eb4d39ea06d3c906e5f (diff)
downloadrneovim-564fd1cc51db4f5a954da236d1abad9d8acc3b6e.tar.gz
rneovim-564fd1cc51db4f5a954da236d1abad9d8acc3b6e.tar.bz2
rneovim-564fd1cc51db4f5a954da236d1abad9d8acc3b6e.zip
Merge pull request #27578 from zeertzjq/vim-9.1.0120
vim-patch:9.1.{0120,0126,0127): add getregion() function
Diffstat (limited to 'src/nvim/ops.c')
-rw-r--r--src/nvim/ops.c141
1 files changed, 63 insertions, 78 deletions
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index e7a3aa29aa..a4af2a54be 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -84,25 +84,6 @@ static bool clipboard_delay_update = false; // delay clipboard update
static bool clipboard_needs_update = false; // clipboard was updated
static bool clipboard_didwarn = false;
-// structure used by block_prep, op_delete and op_yank for blockwise operators
-// also op_change, op_shift, op_insert, op_replace - AKelly
-struct block_def {
- int startspaces; // 'extra' cols before first char
- int endspaces; // 'extra' cols after last char
- int textlen; // chars in block
- char *textstart; // pointer to 1st char (partially) in block
- colnr_T textcol; // index of chars (partially) in block
- colnr_T start_vcol; // start col of 1st char wholly inside block
- colnr_T end_vcol; // start col of 1st char wholly after block
- int is_short; // true if line is too short to fit in block
- int is_MAX; // true if curswant==MAXCOL when starting
- int is_oneChar; // true if block within one character
- int pre_whitesp; // screen cols of ws before block
- int pre_whitesp_c; // chars of ws before block
- colnr_T end_char_vcols; // number of vcols of post-block char
- colnr_T start_char_vcols; // number of vcols of pre-block char
-};
-
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "ops.c.generated.h"
#endif
@@ -2655,66 +2636,11 @@ static void op_yank_reg(oparg_T *oap, bool message, yankreg_T *reg, bool append)
reg->y_array[y_idx] = xstrdup(ml_get(lnum));
break;
- case kMTCharWise: {
- colnr_T startcol = 0;
- colnr_T endcol = MAXCOL;
- bool is_oneChar = false;
- colnr_T cs, ce;
- char *p = ml_get(lnum);
- bd.startspaces = 0;
- bd.endspaces = 0;
-
- if (lnum == oap->start.lnum) {
- startcol = oap->start.col;
- if (virtual_op) {
- getvcol(curwin, &oap->start, &cs, NULL, &ce);
- if (ce != cs && oap->start.coladd > 0) {
- // Part of a tab selected -- but don't double-count it.
- bd.startspaces = (ce - cs + 1) - oap->start.coladd;
- if (bd.startspaces < 0) {
- bd.startspaces = 0;
- }
- startcol++;
- }
- }
- }
-
- if (lnum == oap->end.lnum) {
- endcol = oap->end.col;
- if (virtual_op) {
- getvcol(curwin, &oap->end, &cs, NULL, &ce);
- if (p[endcol] == NUL || (cs + oap->end.coladd < ce
- // Don't add space for double-wide
- // char; endcol will be on last byte
- // of multi-byte char.
- && utf_head_off(p, p + endcol) == 0)) {
- if (oap->start.lnum == oap->end.lnum
- && oap->start.col == oap->end.col) {
- // Special case: inside a single char
- is_oneChar = true;
- bd.startspaces = oap->end.coladd
- - oap->start.coladd + oap->inclusive;
- endcol = startcol;
- } else {
- bd.endspaces = oap->end.coladd
- + oap->inclusive;
- endcol -= oap->inclusive;
- }
- }
- }
- }
- if (endcol == MAXCOL) {
- endcol = (colnr_T)strlen(p);
- }
- if (startcol > endcol || is_oneChar) {
- bd.textlen = 0;
- } else {
- bd.textlen = endcol - startcol + oap->inclusive;
- }
- bd.textstart = p + startcol;
+ case kMTCharWise:
+ charwise_block_prep(oap->start, oap->end, &bd, lnum, oap->inclusive);
yank_copy_line(reg, &bd, y_idx, false);
break;
- }
+
// NOTREACHED
case kMTUnknown:
abort();
@@ -4203,7 +4129,7 @@ static void restore_lbr(bool lbr_saved)
/// - textlen includes the first/last char to be wholly yanked
/// - start/endspaces is the number of columns of the first/last yanked char
/// that are to be yanked.
-static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, bool is_del)
+void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, bool is_del)
{
int incr = 0;
// Avoid a problem with unwanted linebreaks in block mode.
@@ -4326,6 +4252,65 @@ static void block_prep(oparg_T *oap, struct block_def *bdp, linenr_T lnum, bool
restore_lbr(lbr_saved);
}
+/// Get block text from "start" to "end"
+void charwise_block_prep(pos_T start, pos_T end, struct block_def *bdp, linenr_T lnum,
+ bool inclusive)
+{
+ colnr_T startcol = 0;
+ colnr_T endcol = MAXCOL;
+ bool is_oneChar = false;
+ colnr_T cs, ce;
+ char *p = ml_get(lnum);
+ bdp->startspaces = 0;
+ bdp->endspaces = 0;
+
+ if (lnum == start.lnum) {
+ startcol = start.col;
+ if (virtual_op) {
+ getvcol(curwin, &start, &cs, NULL, &ce);
+ if (ce != cs && start.coladd > 0) {
+ // Part of a tab selected -- but don't double-count it.
+ bdp->startspaces = (ce - cs + 1) - start.coladd;
+ if (bdp->startspaces < 0) {
+ bdp->startspaces = 0;
+ }
+ startcol++;
+ }
+ }
+ }
+
+ if (lnum == end.lnum) {
+ endcol = end.col;
+ if (virtual_op) {
+ getvcol(curwin, &end, &cs, NULL, &ce);
+ if (p[endcol] == NUL || (cs + end.coladd < ce
+ // Don't add space for double-wide
+ // char; endcol will be on last byte
+ // of multi-byte char.
+ && utf_head_off(p, p + endcol) == 0)) {
+ if (start.lnum == end.lnum && start.col == end.col) {
+ // Special case: inside a single char
+ is_oneChar = true;
+ bdp->startspaces = end.coladd - start.coladd + inclusive;
+ endcol = startcol;
+ } else {
+ bdp->endspaces = end.coladd + inclusive;
+ endcol -= inclusive;
+ }
+ }
+ }
+ }
+ if (endcol == MAXCOL) {
+ endcol = (colnr_T)strlen(p);
+ }
+ if (startcol > endcol || is_oneChar) {
+ bdp->textlen = 0;
+ } else {
+ bdp->textlen = endcol - startcol + inclusive;
+ }
+ bdp->textstart = p + startcol;
+}
+
/// Handle the add/subtract operator.
///
/// @param[in] oap Arguments of operator.