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

Add Kitty protocol keyboard enhancement support #607

Merged
merged 5 commits into from
Aug 27, 2023

Conversation

Abdillah
Copy link
Contributor

@Abdillah Abdillah commented Jul 19, 2023

Background

Supporting Kitty keyboard enhancement protocol to enable vi action on other keyboard layout (e.g. ctrl+i on Colemak). Without this, ctrl+i will equivalent to Tab and cannot be remapped to anything else.

Change Summary

Add config use_kitty_protocol to determine whether to enable kitty protocol or not. Then if the terminal support this, send the request to enable this terminal feature. Also disable it back when the engine dropped the event handler finished.

@sholderbach
Copy link
Member

Thanks for implementing it and adding the check before enabling. If everything works fine when playing with the demo we can land this

@Abdillah
Copy link
Contributor Author

I found some issue when connecting to SSH. It seems the terminal still use Kitty protocol even after connecting to SSH. I'm not sure how to solve this.

@amtoine
Copy link
Member

amtoine commented Jul 21, 2023

@Abdillah
is this related to some issue?
i thought i saw a Kitty-related issue somewhere 🤔

src/engine.rs Outdated
}

/// Enable keyboard enhancement to disambiguate escape code
pub fn enable_kitty_protocol(&mut self) -> Result<()> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe a dumb question here 😌

do enable_kitty_protocol and disable_kitty_protocol need to return a Result<()>?

nothing in the function can fail, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes, I followed prior patterns. It might be best to just.. no return?

Copy link
Member

@amtoine amtoine Jul 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes, I followed prior patterns. It might be best to just.. no return?

this is why i said it might be a dumb question because i've never had a look at the source base of this repo so far...

looking at what the function does, it looks to me it could just be

pub fn enable_kitty_protocol(&mut self) {
    self.use_kitty_protocol = true;
}

and if it's not an implementation of some trait 🤔

again, not sure if it should be removed or not, just looking locally at this particular function 😌

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I will stick with the Result despite some itch 😆

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should only do this if necessary. The other commands directly write to STDOUT to perform their operation and are just fallible. As long as this is just setting an internal flag I think it should be infallible.

There may be an argument if we were to move the check for the flags here but as long we don't do it, let's not make preemptive API decisions. reedline is still quite liberal with making breaking changes if necessary. Until then lets keep the API as simple as possible.

@Abdillah
Copy link
Contributor Author

Abdillah commented Jul 21, 2023

I found some issue when connecting to SSH. It seems the terminal still use Kitty protocol even after connecting to SSH. I'm not sure how to solve this.

is this related to some issue?

Not sure, @amtoine, I haven't filled any issue nor looking for it. My initial guess is, it just because the terminal recognize the running program as between enable and disable kitty protocol:

  1. Enable kitty protocol
  2. Nushell keybinding handling
  3. Run a program
  4. Exit the program
  5. Disable kitty protocol

@Abdillah Abdillah force-pushed the feature/kittyproto branch 2 times, most recently from bc0cab8 to 8cc8c4e Compare July 21, 2023 15:46
@Abdillah
Copy link
Contributor Author

The ssh case solved.

@amtoine
Copy link
Member

amtoine commented Jul 23, 2023

Not sure, I haven't filled any issue nor looking for it.

no worries, i see quite a lot of issues, i might just have hallucinated this one 😉

src/engine.rs Outdated
Comment on lines 765 to 767
if self.use_kitty_protocol {
let _ = execute!(io::stdout(), event::PopKeyboardEnhancementFlags);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably the wrong place to handle this, we have the split into read_line and read_line_helper to make sure that we disable extended terminal modes when leaving read_line independent of whether it succeeded or exited with an Err.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, I'll move out from the _helper as is, since the pop operation is perceived as infallible.

src/engine.rs Outdated
Comment on lines 171 to 173
if self.use_kitty_protocol {
let _ = execute!(io::stdout(), event::PopKeyboardEnhancementFlags);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be defensive we could keep this in case the application hosting reedline panics.

Copy link
Contributor Author

@Abdillah Abdillah Jul 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh that's a good idea

src/engine.rs Outdated
}

/// Enable keyboard enhancement to disambiguate escape code
pub fn enable_kitty_protocol(&mut self) -> Result<()> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should only do this if necessary. The other commands directly write to STDOUT to perform their operation and are just fallible. As long as this is just setting an internal flag I think it should be infallible.

There may be an argument if we were to move the check for the flags here but as long we don't do it, let's not make preemptive API decisions. reedline is still quite liberal with making breaking changes if necessary. Until then lets keep the API as simple as possible.

@Abdillah
Copy link
Contributor Author

May I git rebase this? There's some conflicting lines.
I picked the 0.21.0 tag as the base actually for my daily driver.

@sholderbach
Copy link
Member

Feel free to rebase

@Abdillah
Copy link
Contributor Author

Hello @sholderbach, is there anything else I can do to make this PR ready to merge?

Copy link
Member

@sholderbach sholderbach left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks this looks good to me!

Let's get this in to give it a try in nushell.

@sholderbach sholderbach merged commit 6143b01 into nushell:main Aug 27, 2023
6 checks passed
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

Successfully merging this pull request may close these issues.

3 participants