Repository: ipython/ipython

Issue:
paste into ipython stop working with vi mode
this works well:

```
[ins] In [46]: In [41]: s = 'Abc Def Ghi'
[ins] In [47]:
```

this does not work.
```
[ins] In [44]: [ins] In [41]: s = 'Abc Def Ghi'                       
          ...:                 
          ...:                                                        
  File "<ipython-input-44-0af6a6a3f6c4>", line 1
    [ins] In [41]: s = 'Abc Def Ghi'
          ^
SyntaxError: invalid syntax
```

is it possible to configure ipython to also accept transcript under vi mode?

Comments:

Patch:
diff --git a/IPython/core/inputtransformer2.py b/IPython/core/inputtransformer2.py
index c7deab83b..fefc523d7 100644
--- a/IPython/core/inputtransformer2.py
+++ b/IPython/core/inputtransformer2.py
@@ -89,7 +89,30 @@ def __call__(self, lines):
     initial_re=re.compile(r'^>>>( |$)')
 )
 
-ipython_prompt = PromptStripper(re.compile(r'^(In \[\d+\]: |\s*\.{3,}: ?)'))
+ipython_prompt = PromptStripper(
+    re.compile(
+        r"""
+        ^(                         # Match from the beginning of a line, either:
+
+                                   # 1. First-line prompt:
+        ((\[nav\]|\[ins\])?\ )?    # Vi editing mode prompt, if it's there
+        In\                        # The 'In' of the prompt, with a space
+        \[\d+\]:                   # Command index, as displayed in the prompt
+        \                          # With a mandatory trailing space
+
+        |                          # ... or ...
+
+                                   # 2. The three dots of the multiline prompt
+        \s*                        # All leading whitespace characters
+        \.{3,}:                    # The three (or more) dots
+        \ ?                        # With an optional trailing space
+
+        )
+        """,
+        re.VERBOSE,
+    )
+)
+
 
 def cell_magic(lines):
     if not lines or not lines[0].startswith('%%'):
diff --git a/docs/source/whatsnew/pr/vi-prompt-strip.rst b/docs/source/whatsnew/pr/vi-prompt-strip.rst
new file mode 100644
index 000000000..e642a4d1f
--- /dev/null
+++ b/docs/source/whatsnew/pr/vi-prompt-strip.rst
@@ -0,0 +1,29 @@
+Automatic Vi prompt stripping
+=============================
+
+When pasting code into IPython, it will strip the leading prompt characters if
+there are any. For example, you can paste the following code into the console -
+it will still work, even though each line is prefixed with prompts (`In`,
+`Out`)::
+
+    In [1]: 2 * 2 == 4
+    Out[1]: True
+
+    In [2]: print("This still works as pasted")
+
+
+Previously, this was not the case for the Vi-mode prompts::
+
+    In [1]: [ins] In [13]: 2 * 2 == 4
+       ...: Out[13]: True
+       ...: 
+      File "<ipython-input-1-727bb88eaf33>", line 1
+        [ins] In [13]: 2 * 2 == 4
+              ^
+    SyntaxError: invalid syntax
+
+This is now fixed, and Vi prompt prefixes - ``[ins]`` and ``[nav]`` -  are
+skipped just as the normal ``In`` would be.
+
+IPython shell can be started in the Vi mode using ``ipython
+--TerminalInteractiveShell.editing_mode=vi``


Test patch:
diff --git a/IPython/core/tests/test_inputtransformer2_line.py b/IPython/core/tests/test_inputtransformer2_line.py
index 263bbd9ee..8643a46ce 100644
--- a/IPython/core/tests/test_inputtransformer2_line.py
+++ b/IPython/core/tests/test_inputtransformer2_line.py
@@ -61,10 +61,50 @@ def test_classic_prompt():
     print(a ** 2)
 """)
 
+
+IPYTHON_PROMPT_VI_INS = (
+    """\
+[ins] In [11]: def a():
+          ...:     123
+          ...:
+          ...: 123
+""",
+    """\
+def a():
+    123
+
+123
+""",
+)
+
+IPYTHON_PROMPT_VI_NAV = (
+    """\
+[nav] In [11]: def a():
+          ...:     123
+          ...:
+          ...: 123
+""",
+    """\
+def a():
+    123
+
+123
+""",
+)
+
+
 def test_ipython_prompt():
-    for sample, expected in [IPYTHON_PROMPT, IPYTHON_PROMPT_L2]:
-        nt.assert_equal(ipt2.ipython_prompt(sample.splitlines(keepends=True)),
-                        expected.splitlines(keepends=True))
+    for sample, expected in [
+        IPYTHON_PROMPT,
+        IPYTHON_PROMPT_L2,
+        IPYTHON_PROMPT_VI_INS,
+        IPYTHON_PROMPT_VI_NAV,
+    ]:
+        nt.assert_equal(
+            ipt2.ipython_prompt(sample.splitlines(keepends=True)),
+            expected.splitlines(keepends=True),
+        )
+
 
 INDENT_SPACES = ("""\
      if True:
@@ -123,4 +163,4 @@ def test_leading_empty_lines():
 
 def test_crlf_magic():
     for sample, expected in [CRLF_MAGIC]:
-        nt.assert_equal(ipt2.cell_magic(sample), expected)
\ No newline at end of file
+        nt.assert_equal(ipt2.cell_magic(sample), expected)