Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IPython 8 changes terminal cursor #13472

Closed
tebeka opened this issue Jan 16, 2022 · 18 comments
Closed

IPython 8 changes terminal cursor #13472

tebeka opened this issue Jan 16, 2022 · 18 comments
Milestone

Comments

@tebeka
Copy link

tebeka commented Jan 16, 2022

After starting IPython 8.0 and then returning to terminal, the cursor changes from block to I-Beam.

Before:
ipy-cursor-before

After:
ipy-cursor-after

I need to call reset to get the cursor back to block.

Setup: XFCE terminal + zsh + starship

@Jmillan-Dev
Copy link

Jmillan-Dev commented Jan 16, 2022

This behavior also occurs in VI edit mode where in [ins] mode the cursor changes to I-Beam but in [nav] mode the cursor changes back to Block. exiting in any of the two scenarios will keep the current cursor instead of getting back to the original cursor before opening IPython.

Setups:

  1. XTERM + zsh
  2. terminology + zsh

@Carreau
Copy link
Member

Carreau commented Jan 17, 2022

Hum... @jonathanslenders might have an idea ? I don't think we manipulate the cursor in IPython directly.

@ltrujello
Copy link
Contributor

It looks like IPython does manipulate the cursor directly, it was done so in this commit to change the cursor for INSERT, VISUAL, etc. modes (in the case where the user has vi as their editing mode). That code is using ANSI escape codes to tell the running terminal what kind of cursor to use.

The original author didn't add code to restore the cursor. I made a pull request here to fix that.

For now, users can also run

echo -en "\x1b[0 q"

after exiting IPython to get their cursor back.

@Carreau
Copy link
Member

Carreau commented Jan 30, 2022 via email

@jonathanslenders
Copy link
Contributor

I think at some point, this functionality should be merged into prompt_toolkit itself, so that all applications can benefit from it.
The issue about cursor shapes is actually open for 7 years now, but unfortunately I never had the time (well, it was never a priority, and didn't want to hurry into merging something without testing it works everywhere as expected). Let's hope I get around it in the coming weeks/month/year. :-)

See: prompt-toolkit/python-prompt-toolkit#192

Carreau pushed a commit to ltrujello/ipython that referenced this issue Feb 1, 2022
@ltrujello
Copy link
Contributor

@jonathanslenders If you do decide to implement this feature, consider also changing the cursor back when the user does ctrl+z. Currently, IPython cannot change the cursor back when the user decides to SIGTSTP their process. That is because when it detects ctrl+z, it calls a function in prompt-toolkit, which then calls a function to send itself SIGTSTP. So prompt-toolkit could add code to also change the cursor back and forth in that scenario, which applications using it could benefit from.

@jonathanslenders
Copy link
Contributor

@ltrujello : I'll keep that in mind, it should not be an issue. Thanks!

@jonathanslenders
Copy link
Contributor

@ltrujello: Can you check out this PR: prompt-toolkit/python-prompt-toolkit#1558
That should do it. It seems to work fine for suspend too.

With these changes, you can remove the custom cursor shape handling in IPython, pass a cursor_shape_config=.... option to the PromptSession in IPython/terminal/interactiveshell.py. For the modal cursor, take prompt_toolkit.cursor_shapes.ModalCursorShapeConfig(); otherwise take prompt_toolkit.cursor_shapes.CursorShape.BLOCK (if you want to always display a block, or None if cursor shapes should never be touched.)

@Carreau Carreau added this to the 8.1 milestone Feb 25, 2022
Carreau added a commit that referenced this issue Feb 25, 2022
Fixes #13472 by restoring user's terminal cursor after exiting IPython
@ianbrody
Copy link

ianbrody commented Mar 3, 2022

I'm using version 8.1.0. Now when I exit (Ctrl-D) ipython, I get a block cursor... but it's blinking (normally it is not blinking). This is with xterm and urxvt. Also, when I suspend ipython I still get an I-cursor.

@Carreau
Copy link
Member

Carreau commented Mar 4, 2022

I'm not sure there is anything we can do for the suspend – I don't know enough about signal.
In general the cursor thing is unsolvable in the general sens as we don't know the shape/state of the cursor when we start IPython, so we have no way of restoring it.

@jonathanslenders
Copy link
Contributor

@Carreau : See my pull request. This should restore the cursorshape on suspend.

Restoring the cursorshape works by rendering \x1b[0 q. This restores to whatever the terminal decides to be the default, not necessarily the cursor shape before IPython started, but almost always this is what we want.

Restoring cursorshapes during suspend works because prompt_toolkit configures the terminal in raw mode, which means that c-z doesn't send a SIGTSTP to the process group. We handle it as a key binding, restore the cursor shape, and then send SIGTSTP ourselves to our process group.

@jonathanslenders
Copy link
Contributor

@ianbrody : Would you be willing to try my pull request and see whether that fixes your issue?

@ianbrody
Copy link

ianbrody commented Mar 4, 2022

Now it changes back to a block cursor after suspend, but both after suspend and after quitting, the cursor is blinking.

@leycec
Copy link

leycec commented Jun 7, 2022

Personally, I'd strongly prefer that IPython do nothing whatsoever with the cursor. Even when IPython changes and then restores the cursor as expected, it's still unexpected. No other terminal application I use forcefully modifies the cursor – not even Vim or zsh. I'd prefer that IPython behave like (almost) everything else in the POSIX ecosystem. Is there a trivial way for end users to disable this questionable functionality without manually modifying IPython source?

If I grok this comment from @jonathanslenders above correctly, the only means of disabling IPython's cursor modification at the moment is to forcefully pass either cursor_shape_config=None or cursor_shape_config=prompt_toolkit.cursor_shapes.CursorShape.BLOCK to the PromptSession in IPython/terminal/interactiveshell.py. Is that right?

If so, that's better than nothing; at least I have some recourse. Still, changing the cursor without the user's permission only disgruntles users. This should ideally be an opt-in option disabled by default.

@MrMino
Copy link
Member

MrMino commented Jun 10, 2022

Personally, I'd strongly prefer that IPython do nothing whatsoever with the cursor. Even when IPython changes and then restores the cursor as expected, it's still unexpected. No other terminal application I use forcefully modifies the cursor – not even Vim or zsh. I'd prefer that IPython behave like (almost) everything else in the POSIX ecosystem. Is there a trivial way for end users to disable this questionable functionality without manually modifying IPython source?

If I grok this comment from @jonathanslenders above correctly, the only means of disabling IPython's cursor modification at the moment is to forcefully pass either cursor_shape_config=None or cursor_shape_config=prompt_toolkit.cursor_shapes.CursorShape.BLOCK to the PromptSession in IPython/terminal/interactiveshell.py. Is that right?

If so, that's better than nothing; at least I have some recourse. Still, changing the cursor without the user's permission only disgruntles users. This should ideally be an opt-in option disabled by default.

If you'd like to make this configurable, I'd be happy to accept a PR that adds the option. Just make sure to take other PRs that are currently open into account, specifically those open by @jonathanslenders.

@roachsinai
Copy link

Any updates here?

Ipython 8 change my vim cursor when using vim-repl, even vim in NORMAL mode.

image

Thanks.

@Carreau
Copy link
Member

Carreau commented Sep 19, 2023

According the discussion you either need to make the mentioned modification to IPython or send a PR to make it configurable. But as we have no way to know what the cursor shape is, we can't really restore it.

@roachsinai
Copy link

@Carreau thanks for quick reply.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants