Skip to content

Commit b2a136b

Browse files
authored
Merge pull request neovim#35445 from janlazo/vim-9.1.0546
vim-patch:8.1.{579,654,655},9.1.0546
2 parents 1f63735 + 76729a2 commit b2a136b

File tree

2 files changed

+73
-33
lines changed

2 files changed

+73
-33
lines changed

src/nvim/memline.c

Lines changed: 55 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1971,17 +1971,19 @@ int ml_line_alloced(void)
19711971
}
19721972

19731973
/// @param lnum append after this line (can be 0)
1974-
/// @param line text of the new line
1975-
/// @param len length of line, including NUL, or 0
1974+
/// @param line_arg text of the new line
1975+
/// @param len_arg length of line, including NUL, or 0
19761976
/// @param flags ML_APPEND_ flags
19771977
///
19781978
/// @return FAIL for failure, OK otherwise
1979-
static int ml_append_int(buf_T *buf, linenr_T lnum, char *line, colnr_T len, int flags)
1979+
static int ml_append_int(buf_T *buf, linenr_T lnum, char *line_arg, colnr_T len_arg, int flags)
19801980
FUNC_ATTR_NONNULL_ARG(1)
19811981
{
1982-
// lnum out of range
1982+
char *line = line_arg;
1983+
colnr_T len = len_arg;
1984+
19831985
if (lnum > buf->b_ml.ml_line_count || buf->b_ml.ml_mfp == NULL) {
1984-
return FAIL;
1986+
return FAIL; // lnum out of range
19851987
}
19861988

19871989
if (lowest_marked && lowest_marked > lnum) {
@@ -1999,10 +2001,11 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char *line, colnr_T len, int
19992001
// find the data block containing the previous line
20002002
// This also fills the stack with the blocks from the root to the data block
20012003
// This also releases any locked block.
2004+
int ret = FAIL;
20022005
bhdr_T *hp;
20032006
if ((hp = ml_find_line(buf, lnum == 0 ? 1 : lnum,
20042007
ML_INSERT)) == NULL) {
2005-
return FAIL;
2008+
goto theend;
20062009
}
20072010

20082011
buf->b_ml.ml_flags &= ~ML_EMPTY;
@@ -2031,7 +2034,7 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char *line, colnr_T len, int
20312034
(buf->b_ml.ml_locked_lineadd)--;
20322035
(buf->b_ml.ml_locked_high)--;
20332036
if ((hp = ml_find_line(buf, lnum + 1, ML_INSERT)) == NULL) {
2034-
return FAIL;
2037+
goto theend;
20352038
}
20362039

20372040
db_idx = -1; // careful, it is negative!
@@ -2048,7 +2051,8 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char *line, colnr_T len, int
20482051
buf->b_ml.ml_line_count++;
20492052

20502053
if ((int)dp->db_free >= space_needed) { // enough room in data block
2051-
// Insert new line in existing data block, or in data block allocated above.
2054+
// Insert the new line in an existing data block, or in the data block
2055+
// allocated above.
20522056
dp->db_txt_start -= (unsigned)len;
20532057
dp->db_free -= (unsigned)space_needed;
20542058
dp->db_line_count++;
@@ -2067,7 +2071,8 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char *line, colnr_T len, int
20672071
dp->db_index[i + 1] = dp->db_index[i] - (unsigned)len;
20682072
}
20692073
dp->db_index[db_idx + 1] = (unsigned)(offset - len);
2070-
} else { // add line at the end
2074+
} else {
2075+
// add line at the end (which is the start of the text)
20712076
dp->db_index[db_idx + 1] = dp->db_txt_start;
20722077
}
20732078

@@ -2083,13 +2088,6 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char *line, colnr_T len, int
20832088
buf->b_ml.ml_flags |= ML_LOCKED_POS;
20842089
}
20852090
} else { // not enough space in data block
2086-
// If there is not enough room we have to create a new data block and copy some
2087-
// lines into it.
2088-
// Then we have to insert an entry in the pointer block.
2089-
// If this pointer block also is full, we go up another block, and so on, up
2090-
// to the root if necessary.
2091-
// The line counts in the pointer blocks have already been adjusted by
2092-
// ml_find_line().
20932091
int line_count_left, line_count_right;
20942092
int page_count_left, page_count_right;
20952093
bhdr_T *hp_left;
@@ -2103,6 +2101,14 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char *line, colnr_T len, int
21032101
linenr_T lnum_left, lnum_right;
21042102
PointerBlock *pp_new;
21052103

2104+
// There is not enough room, we have to create a new data block and
2105+
// copy some lines into it.
2106+
// Then we have to insert an entry in the pointer block.
2107+
// If this pointer block also is full, we go up another block, and so
2108+
// on, up to the root if necessary.
2109+
// The line counts in the pointer blocks have already been adjusted by
2110+
// ml_find_line().
2111+
//
21062112
// We are going to allocate a new data block. Depending on the
21072113
// situation it will be put to the left or right of the existing
21082114
// block. If possible we put the new line in the left block and move
@@ -2236,13 +2242,13 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char *line, colnr_T len, int
22362242
infoptr_T *ip = &(buf->b_ml.ml_stack[stack_idx]);
22372243
int pb_idx = ip->ip_index;
22382244
if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL) {
2239-
return FAIL;
2245+
goto theend;
22402246
}
22412247
PointerBlock *pp = hp->bh_data; // must be pointer block
22422248
if (pp->pb_id != PTR_ID) {
22432249
iemsg(_(e_pointer_block_id_wrong_three));
22442250
mf_put(mfp, hp, false, false);
2245-
return FAIL;
2251+
goto theend;
22462252
}
22472253
// TODO(vim): If the pointer block is full and we are adding at the end
22482254
// try to insert in front of the next block
@@ -2292,7 +2298,7 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char *line, colnr_T len, int
22922298
while (true) { // do this twice when splitting block 1
22932299
hp_new = ml_new_ptr(mfp);
22942300
if (hp_new == NULL) { // TODO(vim): try to fix tree
2295-
return FAIL;
2301+
goto theend;
22962302
}
22972303
pp_new = hp_new->bh_data;
22982304

@@ -2375,7 +2381,10 @@ static int ml_append_int(buf_T *buf, linenr_T lnum, char *line, colnr_T len, int
23752381

23762382
// The line was inserted below 'lnum'
23772383
ml_updatechunk(buf, lnum + 1, len, ML_CHNK_ADDLINE);
2378-
return OK;
2384+
ret = OK;
2385+
2386+
theend:
2387+
return ret;
23792388
}
23802389

23812390
/// Flush any pending change and call ml_append_int()
@@ -2496,7 +2505,19 @@ int ml_replace(linenr_T lnum, char *line, bool copy)
24962505
///
24972506
/// @return FAIL for failure, OK otherwise
24982507
int ml_replace_buf(buf_T *buf, linenr_T lnum, char *line, bool copy, bool noalloc)
2508+
FUNC_ATTR_NONNULL_ARG(1)
24992509
{
2510+
size_t len = line != NULL ? strlen(line) : (size_t)-1;
2511+
return ml_replace_buf_len(buf, lnum, line, len, copy, noalloc);
2512+
}
2513+
2514+
int ml_replace_buf_len(buf_T *buf, linenr_T lnum, char *line_arg, size_t len_arg, bool copy,
2515+
bool noalloc)
2516+
FUNC_ATTR_NONNULL_ARG(1)
2517+
{
2518+
char *line = line_arg;
2519+
colnr_T len = (colnr_T)len_arg;
2520+
25002521
if (line == NULL) { // just checking...
25012522
return FAIL;
25022523
}
@@ -2508,7 +2529,7 @@ int ml_replace_buf(buf_T *buf, linenr_T lnum, char *line, bool copy, bool noallo
25082529

25092530
if (copy) {
25102531
assert(!noalloc);
2511-
line = xstrdup(line);
2532+
line = xmemdupz(line, len_arg);
25122533
}
25132534

25142535
if (buf->b_ml.ml_line_lnum != lnum) {
@@ -2525,7 +2546,7 @@ int ml_replace_buf(buf_T *buf, linenr_T lnum, char *line, bool copy, bool noallo
25252546
}
25262547

25272548
buf->b_ml.ml_line_ptr = line;
2528-
buf->b_ml.ml_line_len = (colnr_T)strlen(line) + 1;
2549+
buf->b_ml.ml_line_len = len + 1;
25292550
buf->b_ml.ml_line_lnum = lnum;
25302551
buf->b_ml.ml_flags = (buf->b_ml.ml_flags | ML_LINE_DIRTY) & ~ML_EMPTY;
25312552
if (noalloc) {
@@ -2578,8 +2599,8 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, int flags)
25782599
return i;
25792600
}
25802601

2581-
// find the data block containing the line
2582-
// This also fills the stack with the blocks from the root to the data block
2602+
// Find the data block containing the line.
2603+
// This also fills the stack with the blocks from the root to the data block.
25832604
// This also releases any locked block.
25842605
memfile_T *mfp = buf->b_ml.ml_mfp;
25852606
if (mfp == NULL) {
@@ -2620,6 +2641,7 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, int flags)
26202641
// block, and so on, up to the root if necessary.
26212642
// The line counts in the pointer blocks have already been adjusted by
26222643
// ml_find_line().
2644+
int ret = FAIL;
26232645
if (count == 1) {
26242646
mf_free(mfp, hp); // free the data block
26252647
buf->b_ml.ml_locked = NULL;
@@ -2629,13 +2651,13 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, int flags)
26292651
infoptr_T *ip = &(buf->b_ml.ml_stack[stack_idx]);
26302652
idx = ip->ip_index;
26312653
if ((hp = mf_get(mfp, ip->ip_bnum, 1)) == NULL) {
2632-
return FAIL;
2654+
goto theend;
26332655
}
26342656
PointerBlock *pp = hp->bh_data; // must be pointer block
26352657
if (pp->pb_id != PTR_ID) {
26362658
iemsg(_(e_pointer_block_id_wrong_four));
26372659
mf_put(mfp, hp, false, false);
2638-
return FAIL;
2660+
goto theend;
26392661
}
26402662
count = --(pp->pb_count);
26412663
if (count == 0) { // the pointer block becomes empty!
@@ -2681,7 +2703,10 @@ static int ml_delete_int(buf_T *buf, linenr_T lnum, int flags)
26812703
}
26822704

26832705
ml_updatechunk(buf, lnum, line_size, ML_CHNK_DELLINE);
2684-
return OK;
2706+
ret = OK;
2707+
2708+
theend:
2709+
return ret;
26852710
}
26862711

26872712
/// Delete line "lnum" in the current buffer.
@@ -2708,7 +2733,7 @@ int ml_delete_flags(linenr_T lnum, int flags)
27082733
return ml_delete_int(curbuf, lnum, flags);
27092734
}
27102735

2711-
/// set the B_MARKED flag for line 'lnum'
2736+
/// set the DB_MARKED flag for line 'lnum'
27122737
void ml_setmarked(linenr_T lnum)
27132738
{
27142739
// invalid line number
@@ -2732,7 +2757,7 @@ void ml_setmarked(linenr_T lnum)
27322757
curbuf->b_ml.ml_flags |= ML_LOCKED_DIRTY;
27332758
}
27342759

2735-
/// find the first line with its B_MARKED flag set
2760+
/// find the first line with its DB_MARKED flag set
27362761
linenr_T ml_firstmarked(void)
27372762
{
27382763
if (curbuf->b_ml.ml_mfp == NULL) {
@@ -2924,7 +2949,7 @@ static bhdr_T *ml_new_ptr(memfile_T *mfp)
29242949
return hp;
29252950
}
29262951

2927-
/// lookup line 'lnum' in a memline
2952+
/// Lookup line 'lnum' in a memline.
29282953
///
29292954
/// @param action: if ML_DELETE or ML_INSERT the line count is updated while searching
29302955
/// if ML_FLUSH only flush a locked block

test/functional/legacy/028_source_ctrl_v_spec.lua

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ local n = require('test.functional.testnvim')()
55
local clear, feed, insert = n.clear, n.feed, n.insert
66
local feed_command, expect = n.feed_command, n.expect
77

8-
describe('CTRL-V at the end of the line', function()
9-
setup(clear)
8+
describe('028', function()
9+
before_each(clear)
1010

11-
it('is working', function()
11+
it('CTRL-V at the end of the line is working', function()
1212
insert([[
1313
firstline
1414
map __1 afirst
@@ -35,6 +35,21 @@ describe('CTRL-V at the end of the line', function()
3535
map __2 asdsecondsdsd0map __5 asd0fifth]])
3636
end)
3737

38+
it('CTRL-X/CTRL-A is working', function()
39+
insert([[
40+
12352
41+
42+
12354]])
43+
feed_command('/12352')
44+
feed('<C-A>')
45+
feed_command('/12354')
46+
feed('<C-X>')
47+
expect([[
48+
12353
49+
50+
12353]])
51+
end)
52+
3853
teardown(function()
3954
os.remove('Xtestfile')
4055
end)

0 commit comments

Comments
 (0)