-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
avoid cnorm on certain terminals #10769
Conversation
I looked into what vom does a lot more. Manually detecting every terminal cannot/should not be a solution. If you look at the sourcecode linked in the issue you will see that nvim doesn't actually use cnorm. Instead they use the The linked code that use TERM detection handles some edgecases but they seem pretty rare/for the most part affect terminal version that are over a decade old. I am ok with not supporting that. I suspect that nobody will actually ever run helix in auch a terminal (the only exception maybe being the Linux virtual terminal nut I doubt people care about cursor style there). So I think we should just keep the code as is and use |
Is In tmux (with correct $TERM set) |
I think you just need to use |
And Se is a extended capability and not part of thebdefault set. In practice terminfo is "whatever emulators supprot". There is no rfc or standardization process. You need to look at the sourcecode of implementations |
d667907
to
24d1eac
Compare
Alright, thank you. I've changed this to check for terminals that don't correctly use either |
I've tested this PR with the follow terminals and teminal multiplxer combinations:
The only combo I've tried that fails to reset the cursor is |
Kitty's docs and author are big proponents of ditching tmux if you use Kitty IIRC (since Kitty has native multiplexing) so I'm not sure we should add the tmux workaround just for Kitty's sake |
OK. Just to be clear: the workaround for tmux in this PR is for terminal other than kitty. |
You didn't implement what I said before. We should always use |
24d1eac
to
7724d34
Compare
Understood, I've rewritten it to build up a reset string to return, starting with I'm new to rust, so I used push_str() to build the string, is this an appropriate approach? Also the compiler told me to initialize the reset_str with |
7724d34
to
03d70b1
Compare
I reread your comment, and realized I did it wrong. Now the reset string:
|
helix-tui/src/backend/crossterm.rs
Outdated
|
||
match term_program().as_deref() { | ||
// some terminals don't reset the cursor with either cnorm or Se | ||
Some("tmux") => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So tmux sets both cnorm and SE and both don't contain that reset sequence?
I guess it's because it passes that escape sequence trough but doesn't know about it itself?
I would really like to avoid special cases like this. I think what would work is if you always prepend the fallback sequence. So basically format!("{fallback}{Se}{cnorm}")
(with this approach Se and cnorm won't need a fallback).
It's a bit of a hack but it should work. Emitting the escape sequence multiple times is fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so that approach works! although I'm confused as to why, because printf '\033[0 q' && tput Se && tput cnorm
doesn't work... maybe the way I've implemented it in rust is wrong?
helix-tui/src/backend/crossterm.rs
Outdated
} | ||
fn vte_version() -> Option<usize> { | ||
std::env::var("VTE_VERSION").ok()?.parse().ok() | ||
} | ||
fn reset_cursor_approach(terminfo: TermInfo, fallback: &str) -> String { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fn reset_cursor_approach(terminfo: TermInfo, fallback: &str) -> String { | |
fn reset_cursor_escape_sequence(terminfo: TermInfo) -> String { |
Passing the fallback as an argument is a bit qeord/unnecessary just put it into the function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry about that, it is a habit of my make all state come into the function through the arguments. I've undone it.
03d70b1
to
5c201c5
Compare
I've forced pushed an update. BTW, I'm happy to make as many changes as requested until this is suitable. So please don't feel like you are requesting too many changes. I love helix (thank you for making it ❤️) and want this issue to get resolved hopfully before a release, but it isn't urgent for me personally because I can easily patch helix on my system. 😄 |
helix-tui/src/backend/crossterm.rs
Outdated
}; | ||
|
||
format!( | ||
"{}{:?}{}", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"{:?}"
is wrong here, that is why the cursor resetting was working in tmux for me. I accidentally left the "{:?}"
while trying to figure out the types because I'm a rust noob xD
5c201c5
to
b4adff2
Compare
right, so I force pushed yet again, because I didn't do the The question is, do we ignore the tmux issue and go with the cleaner approach that works in many terminals? |
It seems that I've tried using the override options suggested there, and none of them work for me even when switching the |
b4adff2
to
a15ab09
Compare
OK, I've done more testing today. If I set @pascalkuthe I've forced pushed the version without a workaround for tmux. I agree with you that avoiding special cases is the way to go. After all the testing I've done, I think it is best to to tell users if the |
helix-tui/src/backend/crossterm.rs
Outdated
let Some(termini::Value::Utf8String(se_str)) = terminfo.extended_cap("Se") else { | ||
return "".to_string(); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there's no Se
capability we don't end up emitting the fallback? I thought the intent was to always use the fallback.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this current implementation always emits the fallback, (Se
or an empty string), and cnorm
in that order
That let se_str
is written that way because I couldn't figure out a cleaner way to access the value in Option<Value<'_>>
that .extended_cap("Se")
returns.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, this snippet early returns and an empty string is emitted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh, I see, thank you!!
a15ab09
to
24c979a
Compare
I corrected the early return. Thank you for pointing out my blunder! IDK why, but for some reason I was thinking about |
helix-tui/src/backend/crossterm.rs
Outdated
if let termini::Value::Utf8String(se_str) = terminfo | ||
.extended_cap("Se") | ||
.unwrap_or(termini::Value::Utf8String("")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if let termini::Value::Utf8String(se_str) = terminfo | |
.extended_cap("Se") | |
.unwrap_or(termini::Value::Utf8String("")) | |
if let Some(termini::Value::Utf8String(se_str)) = terminfo.extended_cap("Se") |
helix-tui/src/backend/crossterm.rs
Outdated
reset_str.push_str( | ||
terminfo | ||
.utf8_string_cap(termini::StringCapability::CursorNormal) | ||
.unwrap(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.unwrap(), | |
.unwrap_or(""), |
24c979a
to
26ffc66
Compare
Thank you for the review! both changes made, and pushed. 🙂 |
Should I push a fix to satisfy clippy? I didn't know that using the return keyward was not considered good practice 🙂 |
yes, please appease clippy 👍 |
using a terminfo's cnorm doesn't reset the cursor for many terminals, see issue: helix-editor#10089
26ffc66
to
1a59986
Compare
using a terminfo's cnorm doesn't reset the cursor for many terminals, see issue: helix-editor#10089
using a terminfo's cnorm doesn't reset the cursor for many terminals, see issue: helix-editor#10089
Inspired @pascalkuthe's comment on my previous PR to revert the use of cnorm for resetting the cursor, I've tried writing an approach that checks the $TERM_PROGRAM or $TERM to decide whether to use cnorm or
\x1B[0 q
.Please note, this is my first time writing rust, so please be picky about what I've done wrong or could do better.
I only have access to tmux and alacritty, and getting other terminals on my system is a little tedious because I need to compile them (gentoo). It would be nice if the folks affected by #10089 could run
echo $TERM_PROGRAM
andecho $TERM
in their terminal. I'll add those terminals to this PR.