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/testdir/test_put.vim b/src/testdir/test_put.vim
index 2af31db..26eb7f0 100644
--- a/src/testdir/test_put.vim
+++ b/src/testdir/test_put.vim
Binary files differ
diff --git a/src/testdir/test_vim9_cmd.vim b/src/testdir/test_vim9_cmd.vim
index 900bf8a..26a3f09 100644
--- a/src/testdir/test_vim9_cmd.vim
+++ b/src/testdir/test_vim9_cmd.vim
@@ -1350,6 +1350,59 @@
   bwipe!
 enddef
 
+def Test_iput()
+  new
+  set noexpandtab
+
+  call feedkeys("i\<Tab>foo", 'x')
+
+  @p = "ppp"
+  iput p
+  call assert_equal("\<Tab>ppp", getline(2))
+
+  iput ="below"
+  assert_equal("\<Tab>below", getline(3))
+  iput! ="above"
+  assert_equal("\<Tab>above", getline(3))
+  assert_equal("\<Tab>below", getline(4))
+
+  :2iput =['a', 'b', 'c']
+  assert_equal(["\<Tab>ppp", "\<Tab>a", "\<Tab>b", "\<Tab>c", "\<Tab>above"], getline(2, 6))
+
+  :0iput =  "\<Tab>\<Tab>first"
+  assert_equal("\<Tab>first", getline(1))
+  :1iput! ="first again"
+  assert_equal("\<Tab>first again", getline(1))
+
+  bw!
+  v9.CheckDefFailure(['iput =xxx'], 'E1001:')
+enddef
+
+def Test_iput_with_linebreak()
+  new
+  var lines =<< trim END
+    vim9script
+    ip =split('abc', '\zs')
+            ->join()
+  END
+  v9.CheckScriptSuccess(lines)
+  getline(2)->assert_equal('a b c')
+  bwipe!
+enddef
+
+def Test_iput_not_put()
+  new
+  call feedkeys("ggS\<Tab>foo", 'x')
+  @a = "putting"
+  :0iput a
+  assert_equal("\<Tab>putting", getline(1))
+  put a
+  assert_equal("putting", getline(2))
+  iput a
+  assert_equal("putting", getline(3))
+  bwipe!
+enddef
+
 def Test_command_star_range()
   new
   setline(1, ['xxx foo xxx', 'xxx bar xxx', 'xxx foo xx bar'])
diff --git a/src/testdir/test_vim9_disassemble.vim b/src/testdir/test_vim9_disassemble.vim
index 7a41b5d..27b71fe 100644
--- a/src/testdir/test_vim9_disassemble.vim
+++ b/src/testdir/test_vim9_disassemble.vim
@@ -286,6 +286,20 @@
         res)
 enddef
 
+def s:IputExpr()
+  :3iput ="text"
+enddef
+
+def Test_disassemble_iput_expr()
+  var res = execute('disass s:IputExpr')
+  assert_match('<SNR>\d*_IputExpr.*' ..
+        ' :3iput ="text"\_s*' ..
+        '\d PUSHS "text"\_s*' ..
+        '\d IPUT = 3\_s*' ..
+        '\d RETURN void',
+        res)
+enddef
+
 def s:PutRange()
   :$-2put a
   :$-3put! b
@@ -305,6 +319,25 @@
         res)
 enddef
 
+def s:IputRange()
+  :$-2iput a
+  :$-3iput! b
+enddef
+
+def Test_disassemble_iput_range()
+  var res = execute('disass s:IputRange')
+  assert_match('<SNR>\d*_IputRange.*' ..
+        ' :$-2iput a\_s*' ..
+        '\d RANGE $-2\_s*' ..
+        '\d IPUT a range\_s*' ..
+
+        ' :$-3iput! b\_s*' ..
+        '\d RANGE $-3\_s*' ..
+        '\d IPUT b above range\_s*' ..
+        '\d RETURN void',
+        res)
+enddef
+
 def s:ScriptFuncPush()
   var localbool = true
   var localspec = v:none