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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support kitty's new shell integration #4623

Closed
Techcable opened this issue Jan 4, 2022 · 16 comments
Closed

Support kitty's new shell integration #4623

Techcable opened this issue Jan 4, 2022 · 16 comments

Comments

@Techcable
Copy link

Techcable commented Jan 4, 2022

Hi! I use xonsh as my primary shell and kitty as my terminal.

Kitty 0.2.4 adds new Shell Integration, which includes a ton of awesome features 馃槃 馃殌

Amazing features 1. Open the output of the last command in a pager such as less (ctrl+shift+g) 2. Jump to the previous/next prompt in the scrollback (ctrl+shift+z / ctrl+shift+x) 3. Click with the mouse anywhere in the current command to move the cursor there 4. Hold ctrl+shift and right-click on any command output in the scrollback to view it in a pager 5. The current working directory or the command being executed are automatically displayed in the kitty window titlebar/tab title. 6. The text cursor is changed to a bar when editing commands at the shell prompt 7. Glitch free window resizing even with complex prompts. Achieved by erasing the prompt on resize and allowing the shell to redraw it cleanly. 8. Sophisticated completion for the kitty command in the shell. 9. When confirming a quit command if a window is sitting at a shell prompt, it is optionally, not counted (see confirm_os_window_close)

It looks like the shell's core would only need to add three hooks.

config

config ``` | xonsh | 0.11.0 | | Git SHA | 337cf25 | | Commit Date | Nov 17 15:37:41 2021 | | Python | 3.9.9 | | PLY | 3.11 | | have readline | True | | prompt toolkit | 3.0.23 | | shell type | prompt_toolkit | | history backend | sqlite | | pygments | None | | on posix | True | | on linux | False | | on darwin | True | | on windows | False | | on cygwin | False | | on msys2 | False | | is superuser | False | | default encoding | utf-8 | | xonsh encoding | utf-8 | | encoding errors | surrogateescape | | on jupyter | False | | jupyter kernel | None | | xontrib 1 | back2dir | | xontrib 2 | jedi | | xontrib 3 | readable-traceback | | RC file 1 | /Users/nicholas/.xonshrc | +------------------+--------------------------+ ```

Expected Behavior

First-class integration with kitty. I propose adding it as a built-in xontrib.

Here is a link to an explanation on how it works.

The actual shell integration code uses hooks provided by each shell to send special escape codes to kitty, to perform the various tasks.

Here's a link to the code for the builtin supported shells

It looks like the hooks required directly from the shell side are pretty simple (just a couple of escape codes).

From the Notes for Shell Developers:

The protocol used for marking the prompt is very simple. You should consider adding it to your shell as a builtin. Many modern terminals make use of it, for example: kitty, iTerm2, WezTerm, DomTerm

  1. Just before starting to draw the PS1 prompt send the escape code: <OSC>133;A<ST>
  2. Just before starting to draw the PS2 prompt send the escape code: <OSC>133;A;k=s<ST>
  3. Just before running a command/program, send the escape code: 133;C

Proposal

Due to the increasing popularity of kitty (13.2k stars), I propose adding kitty integration as a builtin xontrib.

I don't really have the proper experience with xonsh internals to put those three hooks in place (or know if they're already there).

However, once the hooks are in place, I would be happy to port the bulk of the integration and maintain it as a builtin xontrib 馃槃

Current Behavior (and existing integration)

There is an existing kitty xontrib, but it's extremely barebones and does not support these new features. It has not been updated since 2019

It really only adds a couple of aliases and enables fancy matplotlib integration.

I

To be clear, I'm not proposing we add the matplotlib, only port the "official" integration from zsh/fish.

Also I highly doubt kitty will add support for xonsh on their end. I think we're considered somewhat of a niche community 馃槮

For community

猬囷笍 Please click the 馃憤 reaction instead of leaving a +1 or 馃憤 comment

@kovidgoyal
Copy link

I actually like the idea of a python based shell and would be open to adding explicit support for it to kitty, provided:

  1. there is some way for an invoking process to inject code into the shell robustly (something like ZDOTDIR for zsh or XDG_DATA_DIRS for fish)

  2. Someone familiar with xonsh is willing to help write the integration scripts

That said, adding builtin support for this in the shell itself is the the more robust and better long term solution.

@pannet1
Copy link

pannet1 commented Jan 6, 2022

Qtile, Kitty and Xonsh. Lets make it rock.

@jnoortheen
Copy link
Member

There is a long standing issue similar to this here #374
It is better to keep the shell-integrations as a separate xontrib. Any hook/callbacks that is needed can be implemented in the Xonsh itself.

@kovidgoyal

  1. I think you are asking the data-dir in order to add shell completions for kitty. The file can be inside any locations, it just need to be imported in the rc file. The xonsh completer is just a function with a registry. The following environment variables can be of interest,
  1. I am willing to help. I can help writing the completer script.

@kovidgoyal
Copy link

kovidgoyal commented Jan 7, 2022 via email

@jnoortheen
Copy link
Member

The problem with the above two env vars is
that if kitty sets them, I assume it will prevent the loadig of the
default rc files. What I need is some way to add an additional
location from which to load rc files, without affecting the defaults.

Yes you are right. It will stop loading the rc file if set explicitly. The usual way is to import such paths/xontribs in the main rc file.

Completion is done by kitty itself, completion scripts for kitty are just
thin wrappers. See the "Shell specific code" section in complete.py

I will look into it

@kovidgoyal
Copy link

I would rather avoid having kitty modify the user's rc files if at all possible.

@jnoortheen
Copy link
Member

I would rather avoid having kitty modify the user's rc files if at all possible.

Yes , the user should be loading the extension in that case.
Also if wanted, we can make the rc related env variables a list of paths to load.

@kovidgoyal
Copy link

Here are the current requirements, for full shell integration with kitty:

  1. An env var that appends a location to look for rc files to load during startup
  2. Some way to send escape codes to the terminal at specific points:
    a) Just before the prompt is printed (with access to the cwd so the terminal title bar can be updated)
    b) Just before a command is executed (with access to the command to be executed so the terminal title bar can be updated with the command name)
  3. kitty likes to set the cursor to a bar at the shell prompt so while in insert mode (if the prompt supports vi modes which I believe prompt_toolkit does) so some hook for that
  4. Someone needs to write the shell specific code section in complete.py that works for whatever completio system xonsh uses.

@gforsyth
Copy link
Collaborator

gforsyth commented Jan 7, 2022

Also if wanted, we can make the rc related env variables a list of paths to load.

I believe that's what $XONSHRC_DIR does.

For pre-PS1 and pre-command hooks, the event system will work well, e.g.:

@events.on_pre_prompt
def pre_prompt_escape():
    t = "<OSC>133;A<ST>"
    print(t, file=sys.__stdout__, flush=True)

@events.on_precommand
def pre_command_escape(cmd):
    t = "133;C"
    print(t, file=sys.__stdout__, flush=True)

PS2 is less well defined in a prompt_toolkit multiline prompt

@Techcable
Copy link
Author

PS2 is less well defined in a prompt_toolkit multiline prompt

I'm interested on working on this and wondering, when does PS2 come up in a regular prompt? Is it just when you have quotes splitting across multiple lines like

$ echo "Foo 
  > Bar"

where > is $PS2 and the shell expecting you to give more input?

I'm willing to work at this but unfortunately I don't have a very good understanding of traditional shells 馃槈

@gforsyth
Copy link
Collaborator

gforsyth commented Jan 7, 2022

PS2 is the "continuation" prompt, so yes to your example, but also any other command that gets split over many lines using backslashes, e.g.

$ echo multi\
> line\
> command
multilinecommand

for the readline backend we have a continuation prompt, but for prompt_toolkit, the continuation prompt is handled by prompt_toolkit, so it's harder to hook in an event there. I'm also not entirerly sure it's necessary.

@jnoortheen
Copy link
Member

I've created a xontrib for iterm2 integration. It has some issues as commented here. A similar xontrib can be created for kitty as well.

#374 (comment)

@Techcable
Copy link
Author

Techcable commented Jan 8, 2022

@kovidgoyal Don't kitty and iTerm2 use the same escape sequences for shell integration?

If we already have those escape sequences then all we would have to add is completions, right?

@kovidgoyal
Copy link

The prompt marking sequences are the same except that kityt needs less (more dont do any harm) and it marks PS2 which iterm doesnt.

@jnoortheen
Copy link
Member

I have implemented the integration for kitty as well
https://github.com/jnoortheen/xontrib-term-integrations

It sends the PS2 code and has completions support as well.

@Techcable
Copy link
Author

Thanks @jnoortheen ! I'll try and help test and fix any bugs that arise.

Hopefully someday we can get this integrated into xonsh core :)

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

5 participants