patch 9.1.1224: cannot :put while keeping indent
Problem: cannot :put while keeping indent (Peter Aronoff)
Solution: add the :iput ex command (64-bitman)
fixes: #16225
closes: #16886
Co-authored-by: zeertzjq <zeertzjq@outlook.com>
Co-authored-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: 64-bitman <60551350+64-bitman@users.noreply.github.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
diff --git a/src/vim9execute.c b/src/vim9execute.c
index 4b69dfa..c0c3103 100644
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -3253,6 +3253,58 @@
}
/*
+ * do ISN_PUT or ISN_IPUT instruction depending on fixindent parameter
+ */
+ static void
+isn_put_do(ectx_T *ectx, isn_T *iptr, typval_T *tv, int fixindent)
+{
+ int regname = iptr->isn_arg.put.put_regname;
+ linenr_T lnum = iptr->isn_arg.put.put_lnum;
+ char_u *expr = NULL;
+ int dir = FORWARD;
+
+ if (lnum < -2)
+ {
+ // line number was put on the stack by ISN_RANGE
+ tv = STACK_TV_BOT(-1);
+ curwin->w_cursor.lnum = tv->vval.v_number;
+ if (lnum == LNUM_VARIABLE_RANGE_ABOVE)
+ dir = BACKWARD;
+ --ectx->ec_stack.ga_len;
+ }
+ else if (lnum == -2)
+ // :put! above cursor
+ dir = BACKWARD;
+ else if (lnum >= 0)
+ {
+ curwin->w_cursor.lnum = lnum;
+ if (lnum == 0)
+ // check_cursor() below will move to line 1
+ dir = BACKWARD;
+ }
+
+ if (regname == '=')
+ {
+ tv = STACK_TV_BOT(-1);
+ if (tv->v_type == VAR_STRING)
+ expr = tv->vval.v_string;
+ else
+ {
+ expr = typval2string(tv, TRUE); // allocates value
+ clear_tv(tv);
+ }
+ --ectx->ec_stack.ga_len;
+ }
+ check_cursor();
+
+ if (fixindent)
+ do_put(regname, expr, dir, 1L, PUT_LINE|PUT_CURSLINE|PUT_FIXINDENT);
+ else
+ do_put(regname, expr, dir, 1L, PUT_LINE|PUT_CURSLINE);
+ vim_free(expr);
+}
+
+/*
* Execute instructions in execution context "ectx".
* Return OK or FAIL;
*/
@@ -5948,48 +6000,12 @@
break;
case ISN_PUT:
- {
- int regname = iptr->isn_arg.put.put_regname;
- linenr_T lnum = iptr->isn_arg.put.put_lnum;
- char_u *expr = NULL;
- int dir = FORWARD;
-
- if (lnum < -2)
- {
- // line number was put on the stack by ISN_RANGE
- tv = STACK_TV_BOT(-1);
- curwin->w_cursor.lnum = tv->vval.v_number;
- if (lnum == LNUM_VARIABLE_RANGE_ABOVE)
- dir = BACKWARD;
- --ectx->ec_stack.ga_len;
- }
- else if (lnum == -2)
- // :put! above cursor
- dir = BACKWARD;
- else if (lnum >= 0)
- {
- curwin->w_cursor.lnum = lnum;
- if (lnum == 0)
- // check_cursor() below will move to line 1
- dir = BACKWARD;
- }
-
- if (regname == '=')
- {
- tv = STACK_TV_BOT(-1);
- if (tv->v_type == VAR_STRING)
- expr = tv->vval.v_string;
- else
- {
- expr = typval2string(tv, TRUE); // allocates value
- clear_tv(tv);
- }
- --ectx->ec_stack.ga_len;
- }
- check_cursor();
- do_put(regname, expr, dir, 1L, PUT_LINE|PUT_CURSLINE);
- vim_free(expr);
- }
+ tv = NULL; // initialize it so we don't get a warning
+ isn_put_do(ectx, iptr, tv, FALSE);
+ break;
+ case ISN_IPUT:
+ tv = NULL;
+ isn_put_do(ectx, iptr, tv, TRUE);
break;
case ISN_CMDMOD:
@@ -7619,7 +7635,18 @@
iptr->isn_arg.put.put_regname,
(long)iptr->isn_arg.put.put_lnum);
break;
-
+ case ISN_IPUT:
+ if (iptr->isn_arg.put.put_lnum == LNUM_VARIABLE_RANGE_ABOVE)
+ smsg("%s%4d IPUT %c above range",
+ pfx, current, iptr->isn_arg.put.put_regname);
+ else if (iptr->isn_arg.put.put_lnum == LNUM_VARIABLE_RANGE)
+ smsg("%s%4d IPUT %c range",
+ pfx, current, iptr->isn_arg.put.put_regname);
+ else
+ smsg("%s%4d IPUT %c %ld", pfx, current,
+ iptr->isn_arg.put.put_regname,
+ (long)iptr->isn_arg.put.put_lnum);
+ break;
case ISN_CMDMOD:
{
char_u *buf;
@@ -7846,5 +7873,4 @@
return OK;
}
-
#endif // FEAT_EVAL