Skip to content

Commit c3516f7

Browse files
committed
patch 8.2.1637: Vim9: :put ={expr} does not work inside :def function
Problem: Vim9: :put ={expr} does not work inside :def function. Solution: Add ISN_PUT. (closes #6397)
1 parent 6defa7b commit c3516f7

12 files changed

Lines changed: 158 additions & 13 deletions

File tree

src/edit.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3399,7 +3399,7 @@ ins_reg(void)
33993399
AppendCharToRedobuff(literally);
34003400
AppendCharToRedobuff(regname);
34013401

3402-
do_put(regname, BACKWARD, 1L,
3402+
do_put(regname, NULL, BACKWARD, 1L,
34033403
(literally == Ctrl_P ? PUT_FIXINDENT : 0) | PUT_CURSEND);
34043404
}
34053405
else if (insert_reg(regname, literally) == FAIL)
@@ -4776,7 +4776,7 @@ ins_pagedown(void)
47764776
static void
47774777
ins_drop(void)
47784778
{
4779-
do_put('~', BACKWARD, 1L, PUT_CURSEND);
4779+
do_put('~', NULL, BACKWARD, 1L, PUT_CURSEND);
47804780
}
47814781
#endif
47824782

src/ex_docmd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7321,7 +7321,7 @@ ex_put(exarg_T *eap)
73217321
eap->forceit = TRUE;
73227322
}
73237323
curwin->w_cursor.lnum = eap->line2;
7324-
do_put(eap->regname, eap->forceit ? BACKWARD : FORWARD, 1L,
7324+
do_put(eap->regname, NULL, eap->forceit ? BACKWARD : FORWARD, 1L,
73257325
PUT_LINE|PUT_CURSLINE);
73267326
}
73277327

src/mouse.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,8 @@ do_mouse(
430430
insert_reg(regname, TRUE);
431431
else
432432
{
433-
do_put(regname, BACKWARD, 1L, fixindent | PUT_CURSEND);
433+
do_put(regname, NULL, BACKWARD, 1L,
434+
fixindent | PUT_CURSEND);
434435

435436
// Repeat it with CTRL-R CTRL-O r or CTRL-R CTRL-P r
436437
AppendCharToRedobuff(Ctrl_R);
@@ -849,7 +850,7 @@ do_mouse(
849850
// to this position
850851
if (restart_edit != 0)
851852
where_paste_started = curwin->w_cursor;
852-
do_put(regname, dir, count, fixindent | PUT_CURSEND);
853+
do_put(regname, NULL, dir, count, fixindent | PUT_CURSEND);
853854
}
854855

855856
#if defined(FEAT_QUICKFIX)

src/normal.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7427,7 +7427,7 @@ nv_put_opt(cmdarg_T *cap, int fix_indent)
74277427
// May have been reset in do_put().
74287428
VIsual_active = TRUE;
74297429
}
7430-
do_put(cap->oap->regname, dir, cap->count1, flags);
7430+
do_put(cap->oap->regname, NULL, dir, cap->count1, flags);
74317431

74327432
// If a register was saved, put it back now.
74337433
if (reg2 != NULL)
@@ -7500,7 +7500,7 @@ nv_nbcmd(cmdarg_T *cap)
75007500
static void
75017501
nv_drop(cmdarg_T *cap UNUSED)
75027502
{
7503-
do_put('~', BACKWARD, 1L, PUT_CURSEND);
7503+
do_put('~', NULL, BACKWARD, 1L, PUT_CURSEND);
75047504
}
75057505
#endif
75067506

src/proto/register.pro

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ void init_yank(void);
2727
void clear_registers(void);
2828
void free_yank_all(void);
2929
int op_yank(oparg_T *oap, int deleting, int mess);
30-
void do_put(int regname, int dir, long count, int flags);
30+
void do_put(int regname, char_u *expr_result, int dir, long count, int flags);
3131
int get_register_name(int num);
3232
int get_unname_register(void);
3333
void ex_display(exarg_T *eap);

src/register.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1487,6 +1487,7 @@ copy_yank_reg(yankreg_T *reg)
14871487
void
14881488
do_put(
14891489
int regname,
1490+
char_u *expr_result, // result for regname "=" when compiled
14901491
int dir, // BACKWARD for 'P', FORWARD for 'p'
14911492
long count,
14921493
int flags)
@@ -1551,11 +1552,12 @@ do_put(
15511552

15521553
// For special registers '%' (file name), '#' (alternate file name) and
15531554
// ':' (last command line), etc. we have to create a fake yank register.
1554-
if (get_spec_reg(regname, &insert_string, &allocated, TRUE))
1555-
{
1556-
if (insert_string == NULL)
1557-
return;
1558-
}
1555+
// For compiled code "expr_result" holds the expression result.
1556+
if (regname == '=' && expr_result != NULL)
1557+
insert_string = expr_result;
1558+
else if (get_spec_reg(regname, &insert_string, &allocated, TRUE)
1559+
&& insert_string == NULL)
1560+
return;
15591561

15601562
// Autocommands may be executed when saving lines for undo. This might
15611563
// make "y_array" invalid, so we start undo now to avoid that.

src/testdir/test_vim9_cmd.vim

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,5 +315,21 @@ def Test_normal_command()
315315
bwipe!
316316
enddef
317317

318+
def Test_put_command()
319+
new
320+
@p = 'ppp'
321+
put p
322+
assert_equal('ppp', getline(2))
323+
324+
put ='below'
325+
assert_equal('below', getline(3))
326+
put! ='above'
327+
assert_equal('above', getline(3))
328+
assert_equal('below', getline(4))
329+
330+
bwipe!
331+
enddef
332+
333+
318334

319335
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker

src/testdir/test_vim9_disassemble.vim

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,21 @@ def Test_disassemble_yank_range()
118118
res)
119119
enddef
120120

121+
def s:PutExpr()
122+
:3put ="text"
123+
enddef
124+
125+
def Test_disassemble_put_expr()
126+
let res = execute('disass s:PutExpr')
127+
assert_match('<SNR>\d*_PutExpr.*' ..
128+
' :3put ="text"\_s*' ..
129+
'\d PUSHS "text"\_s*' ..
130+
'\d PUT = 3\_s*' ..
131+
'\d PUSHNR 0\_s*' ..
132+
'\d RETURN',
133+
res)
134+
enddef
135+
121136
def s:ScriptFuncPush()
122137
let localbool = true
123138
let localspec = v:none

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,8 @@ static char *(features[]) =
754754

755755
static int included_patches[] =
756756
{ /* Add new patch number below this line */
757+
/**/
758+
1637,
757759
/**/
758760
1636,
759761
/**/

src/vim9.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ typedef enum {
135135
ISN_CHECKTYPE, // check value type is isn_arg.type.tc_type
136136
ISN_CHECKLEN, // check list length is isn_arg.checklen.cl_min_len
137137

138+
ISN_PUT, // ":put", uses isn_arg.put
139+
138140
ISN_SHUFFLE, // move item on stack up or down
139141
ISN_DROP // pop stack and discard value
140142
} isntype_T;
@@ -261,6 +263,12 @@ typedef struct {
261263
int shfl_up; // places to move upwards
262264
} shuffle_T;
263265

266+
// arguments to ISN_PUT
267+
typedef struct {
268+
int put_regname; // register, can be NUL
269+
linenr_T put_lnum; // line number to put below
270+
} put_T;
271+
264272
/*
265273
* Instruction
266274
*/
@@ -296,6 +304,7 @@ struct isn_S {
296304
newfunc_T newfunc;
297305
checklen_T checklen;
298306
shuffle_T shuffle;
307+
put_T put;
299308
} isn_arg;
300309
};
301310

0 commit comments

Comments
 (0)