Skip to content

Commit d79a262

Browse files
committed
patch 8.1.0039: cannot easily delete lines in another buffer
Problem: Cannot easily delete lines in another buffer. Solution: Add deletebufline().
1 parent 680c99b commit d79a262

File tree

4 files changed

+148
-13
lines changed

4 files changed

+148
-13
lines changed

runtime/doc/eval.txt

+15-2
Original file line numberDiff line numberDiff line change
@@ -2110,6 +2110,8 @@ cursor({lnum}, {col} [, {off}])
21102110
cursor({list}) Number move cursor to position in {list}
21112111
deepcopy({expr} [, {noref}]) any make a full copy of {expr}
21122112
delete({fname} [, {flags}]) Number delete the file or directory {fname}
2113+
deletebufline({expr}, {first}[, {last}])
2114+
Number delete lines from buffer {expr}
21132115
did_filetype() Number |TRUE| if FileType autocmd event used
21142116
diff_filler({lnum}) Number diff filler lines about {lnum}
21152117
diff_hlID({lnum}, {col}) Number diff highlighting at {lnum}/{col}
@@ -3517,8 +3519,19 @@ delete({fname} [, {flags}]) *delete()*
35173519
successful and -1 when the deletion failed or partly failed.
35183520

35193521
Use |remove()| to delete an item from a |List|.
3520-
To delete a line from the buffer use |:delete|. Use |:exe|
3521-
when the line number is in a variable.
3522+
To delete a line from the buffer use |:delete| or
3523+
|deletebufline()|.
3524+
3525+
deletebufline({expr}, {first}[, {last}]) *deletebufline()*
3526+
Delete lines {first} to {last} (inclusive) from buffer {expr}.
3527+
If {last} is omitted then delete line {first} only.
3528+
On success 0 is returned, on failure 1 is returned.
3529+
3530+
For the use of {expr}, see |bufname()| above.
3531+
3532+
{first} and {last} are used like with |setline()|. Note that
3533+
when using |line()| this refers to the current buffer. Use "$"
3534+
to refer to the last line in buffer {expr}.
35223535

35233536
*did_filetype()*
35243537
did_filetype() Returns |TRUE| when autocommands are being executed and the

src/evalfunc.c

+108-10
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ static void f_cscope_connection(typval_T *argvars, typval_T *rettv);
125125
static void f_cursor(typval_T *argsvars, typval_T *rettv);
126126
static void f_deepcopy(typval_T *argvars, typval_T *rettv);
127127
static void f_delete(typval_T *argvars, typval_T *rettv);
128+
static void f_deletebufline(typval_T *argvars, typval_T *rettv);
128129
static void f_did_filetype(typval_T *argvars, typval_T *rettv);
129130
static void f_diff_filler(typval_T *argvars, typval_T *rettv);
130131
static void f_diff_hlID(typval_T *argvars, typval_T *rettv);
@@ -577,6 +578,7 @@ static struct fst
577578
{"cursor", 1, 3, f_cursor},
578579
{"deepcopy", 1, 2, f_deepcopy},
579580
{"delete", 1, 2, f_delete},
581+
{"deletebufline", 2, 3, f_deletebufline},
580582
{"did_filetype", 0, 0, f_did_filetype},
581583
{"diff_filler", 1, 1, f_diff_filler},
582584
{"diff_hlID", 2, 2, f_diff_hlID},
@@ -1209,6 +1211,24 @@ get_tv_lnum_buf(typval_T *argvars, buf_T *buf)
12091211
return (linenr_T)get_tv_number_chk(&argvars[0], NULL);
12101212
}
12111213

1214+
/*
1215+
* If there is a window for "curbuf", make it the current window.
1216+
*/
1217+
static void
1218+
find_win_for_curbuf(void)
1219+
{
1220+
wininfo_T *wip;
1221+
1222+
for (wip = curbuf->b_wininfo; wip != NULL; wip = wip->wi_next)
1223+
{
1224+
if (wip->wi_win != NULL)
1225+
{
1226+
curwin = wip->wi_win;
1227+
break;
1228+
}
1229+
}
1230+
}
1231+
12121232
/*
12131233
* Set line or list of lines in buffer "buf".
12141234
*/
@@ -1241,19 +1261,10 @@ set_buffer_lines(
12411261

12421262
if (!is_curbuf)
12431263
{
1244-
wininfo_T *wip;
1245-
12461264
curbuf_save = curbuf;
12471265
curwin_save = curwin;
12481266
curbuf = buf;
1249-
for (wip = buf->b_wininfo; wip != NULL; wip = wip->wi_next)
1250-
{
1251-
if (wip->wi_win != NULL)
1252-
{
1253-
curwin = wip->wi_win;
1254-
break;
1255-
}
1256-
}
1267+
find_win_for_curbuf();
12571268
}
12581269

12591270
if (append)
@@ -2807,6 +2818,93 @@ f_delete(typval_T *argvars, typval_T *rettv)
28072818
EMSG2(_(e_invexpr2), flags);
28082819
}
28092820

2821+
/*
2822+
* "deletebufline()" function
2823+
*/
2824+
static void
2825+
f_deletebufline(argvars, rettv)
2826+
typval_T *argvars;
2827+
typval_T *rettv;
2828+
{
2829+
buf_T *buf;
2830+
linenr_T first, last;
2831+
linenr_T lnum;
2832+
long count;
2833+
int is_curbuf;
2834+
buf_T *curbuf_save = NULL;
2835+
win_T *curwin_save = NULL;
2836+
tabpage_T *tp;
2837+
win_T *wp;
2838+
2839+
buf = get_buf_tv(&argvars[0], FALSE);
2840+
if (buf == NULL)
2841+
{
2842+
rettv->vval.v_number = 1; /* FAIL */
2843+
return;
2844+
}
2845+
is_curbuf = buf == curbuf;
2846+
2847+
first = get_tv_lnum_buf(&argvars[1], buf);
2848+
if (argvars[2].v_type != VAR_UNKNOWN)
2849+
last = get_tv_lnum_buf(&argvars[2], buf);
2850+
else
2851+
last = first;
2852+
2853+
if (buf->b_ml.ml_mfp == NULL || first < 1
2854+
|| first > buf->b_ml.ml_line_count || last < first)
2855+
{
2856+
rettv->vval.v_number = 1; /* FAIL */
2857+
return;
2858+
}
2859+
2860+
if (!is_curbuf)
2861+
{
2862+
curbuf_save = curbuf;
2863+
curwin_save = curwin;
2864+
curbuf = buf;
2865+
find_win_for_curbuf();
2866+
}
2867+
if (last > curbuf->b_ml.ml_line_count)
2868+
last = curbuf->b_ml.ml_line_count;
2869+
count = last - first + 1;
2870+
2871+
// When coming here from Insert mode, sync undo, so that this can be
2872+
// undone separately from what was previously inserted.
2873+
if (u_sync_once == 2)
2874+
{
2875+
u_sync_once = 1; // notify that u_sync() was called
2876+
u_sync(TRUE);
2877+
}
2878+
2879+
if (u_save(first - 1, last + 1) == FAIL)
2880+
{
2881+
rettv->vval.v_number = 1; /* FAIL */
2882+
return;
2883+
}
2884+
2885+
for (lnum = first; lnum <= last; ++lnum)
2886+
ml_delete(first, TRUE);
2887+
2888+
FOR_ALL_TAB_WINDOWS(tp, wp)
2889+
if (wp->w_buffer == buf)
2890+
{
2891+
if (wp->w_cursor.lnum > last)
2892+
wp->w_cursor.lnum -= count;
2893+
else if (wp->w_cursor.lnum> first)
2894+
wp->w_cursor.lnum = first;
2895+
if (wp->w_cursor.lnum > wp->w_buffer->b_ml.ml_line_count)
2896+
wp->w_cursor.lnum = wp->w_buffer->b_ml.ml_line_count;
2897+
}
2898+
check_cursor_col();
2899+
deleted_lines_mark(first, count);
2900+
2901+
if (!is_curbuf)
2902+
{
2903+
curbuf = curbuf_save;
2904+
curwin = curwin_save;
2905+
}
2906+
}
2907+
28102908
/*
28112909
* "did_filetype()" function
28122910
*/

src/testdir/test_bufline.vim

+23-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
" Tests for setbufline(), getbufline(), appendbufline()
1+
" Tests for setbufline(), getbufline(), appendbufline(), deletebufline()
22

33
source shared.vim
44

@@ -90,3 +90,25 @@ func Test_appendbufline()
9090
call assert_equal([], getbufline(b, 6))
9191
exe "bwipe! " . b
9292
endfunc
93+
94+
func Test_deletebufline()
95+
new
96+
let b = bufnr('%')
97+
call setline(1, ['aaa', 'bbb', 'ccc'])
98+
hide
99+
call assert_equal(0, deletebufline(b, 2))
100+
call assert_equal(['aaa', 'ccc'], getbufline(b, 1, 2))
101+
call assert_equal(0, deletebufline(b, 2, 8))
102+
call assert_equal(['aaa'], getbufline(b, 1, 2))
103+
exe "bd!" b
104+
call assert_equal(1, deletebufline(b, 1))
105+
106+
split Xtest
107+
call setline(1, ['a', 'b', 'c'])
108+
let b = bufnr('%')
109+
wincmd w
110+
call assert_equal(1, deletebufline(b, 4))
111+
call assert_equal(0, deletebufline(b, 1))
112+
call assert_equal(['b', 'c'], getbufline(b, 1, 2))
113+
exe "bwipe! " . b
114+
endfunc

src/version.c

+2
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,8 @@ static char *(features[]) =
761761

762762
static int included_patches[] =
763763
{ /* Add new patch number below this line */
764+
/**/
765+
39,
764766
/**/
765767
38,
766768
/**/

0 commit comments

Comments
 (0)