-
-
Notifications
You must be signed in to change notification settings - Fork 1k
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
[RFC] Shell integration #3948
Comments
This is great news! I built kitty and ran. I found that when I launch it from the default terminal, mouse positioning doesn't work, but when I launch it from DomTerm, it does. It seems it needs the scripts DomTerm sources to make the cursor posiioning work (at least in my bash setup). For copy paste with the mouse, I understand this is how to do it: https://sw.kovidgoyal.net/kitty/overview/#mouse-features You can middle click to paste from the primary clipboard (on platforms with a primary clipboard)." It appears kitty attempts to write to .bashrc every time it opens. I suggest documenting the shell integration lines needed and letting users decide if they want to add them to their .bashrc or not. |
Thanks for providing this integration. I did some minor testing and the Some other feedback, all done based on
|
On Thu, Aug 19, 2021 at 06:38:23AM -0700, Fladson Gomes wrote:
Thanks for providing this integration. I did some minor testing and the `open last output in less` is great, I just wish we could copy things without the mouse in less, but I am assuming we can change the pager to something else, like we currently have for the scrollback.
It will use whatever you have set as pager in https://sw.kovidgoyal.net/kitty/conf/#opt-kitty.scrollback_pager
Some other feedback, all done based on `fc528941` macos build with `/usr/local/bin/python3.9 setup.py` and running `./kitty/launcher/kitty --config NONE`
- `ctrl+shift+x` is not working for me, I tested on zsh and bash, `ctrl+shit+z` is fine.
You mean if you press ctrl+shift+z to go back a couple of prompts and
then ctrl+shift+x to go forwards, it doesnt work? That works for me on
my macOS machine.
- the prompt re-drawing is still not working for powerlevel10k
<img width="1280" alt="Screenshot 2021-08-19 at 15 24 34" src="https://user-images.githubusercontent.com/554507/130077176-ad587cf0-7196-4f91-960f-eb1dd8c4e5f8.png">
I am not sure what I should do to test this, in this case, I just increased the font size a few times.
Well, this will require input from the powerlevel10k developer. What I
have done is to ensure that the y position of the cursor does not change
with respect to the first line of the prompt due to reflow. So when redrawing a
prompt, there is no longer a race condition and all the shell has to do
is move the cursor up the same number of lines, then move it to the zero
column, erase to the bottom of the screen and then redraw the prompt.
This process should be pretty robust.
- "Click with the mouse anywhere in the current command to move the cursor there" is not working for me
Also works for me. What is it exactly that is not working? Steps I
tried:
1) Type: some test words at the prompt
2) click on the "o" in some, the cursor moved there
|
I can confirm that all integration functions works fine under fish shell and zsh on macOS.
If clicking the mouse fails to move the cursor, please note the new mouse_map default configuration.
However, although it functions properly, I notice that the latency is high, taking several hundred milliseconds from mouse click to cursor position update. May I ask if this is normal? Also, with the fish shell, when creating the second tab, the bell icon appears in the first tab, which is annoying. This does not appear under zsh, and returns to normal after turning off prompt integration with fish shell. ( |
On Thu, Aug 19, 2021 at 06:38:18PM -0700, page-down wrote:
I can confirm that all integration functions works fine under fish shell and zsh on macOS.
> Click with the mouse anywhere in the current command to move the cursor there
If clicking the mouse fails to move the cursor, please note the new mouse_map default configuration.
```
mouse_map left click ungrabbed mouse_handle_click selection link prompt
```
However, although it functions properly, I notice that the latency is high, taking several hundred milliseconds from mouse click to cursor position update. May I ask if this is normal?
Yes, tuneable by: https://sw.kovidgoyal.net/kitty/conf/#opt-kitty.click_interval
Also, with the fish shell, when creating the second tab, the bell icon appears in the first tab, which is annoying.
![kitty_shell_integration_fish_shell_bell](https://user-images.githubusercontent.com/57713011/130164990-174b31c5-e653-4895-84cf-a626b73fc788.png)
This does not appear under zsh, and returns to normal after turning off prompt integration with fish shell. (`shell_integration no-prompt-mark`)
Doesn't happen for me, can you post a minimal fish config to recreate?
|
I built a fresh kitty, and I got the
all the above on Ubuntu 20.04. |
post a minimal bashrc and bash version, so I can debug. All of the above work fine in bash |
bash says it is I started kitty like so: With this, the terminal title was set to |
Never mind, this is a personal configuration issue. However, I have found a minor problem. When running kitty for the first time, the configuration folder does not yet exist because the fish shell has never been run, so an error will be raised.
For configuration file modifications, I personally suggest that it should be explicitly confirmed by the user for the first time and show the file path and the content to be inserted (or symlink). (Just prompt like the quit confirmation. ) Since my configuration has its own structure, I don't want to be silently modified every time I start kitty with File that already existed: I can confirm that everything listed works fine under macOS. version:
|
On Thu, Aug 19, 2021 at 08:08:40PM -0700, John Lenton wrote:
bash says it is `version 5.0.17(1)-release (x86_64-pc-linux-gnu)`.
I started kitty like so: `env - PATH=$PATH HOME=$HOME DISPLAY=$DISPLAY kitty --config NONE bash --norc`
With this, the terminal title was set to `bash`, as expected. I then sourced `kitty.bash` and the terminal title became the current working directory, and my cursor became a bar (should it _always_ be a bar?).
Yes, unless you are in "non-insert" mode, though support for that is
only in zsh not bash.
The cursor moves with clicks, and the terminal title behaviour seems reasonable. I'll work on getting a minimal reproducing bashrc tomorrow (need to sleep now). Looking at the PS1 you get in this, I think my PROMPT_COMMAND setting PS1 is what's breaking at least the title thing. Dunno about the cursor movement / change.
C+S+z/x still do nothing.
Sadly bash doesnt have very good hooks for this, so everything has to go
into PS0/PS1 which is fragile.
|
On Thu, Aug 19, 2021 at 08:18:38PM -0700, page-down wrote:
>> ... the bell icon appears in the first tab ...
>
> Doesn't happen for me, can you post a minimal fish config to recreate?
Never mind, this is a personal configuration issue.
However, I have found a minor problem. When running kitty for the first time, the configuration folder does not yet exist because the fish shell has never been run, so an error will be raised.
```
$ mv ~/.config/fish /tmp/
$ kitty --config=NONE -o shell=/usr/local/bin/fish
Traceback (most recent call last):
...
FileNotFoundError: [Errno 2] No such file or directory: '/Users/me/.config/fish/completions/tmpkxmlt3px.tmp'
```
This is now fixed.
---
For configuration file modifications, I personally suggest that it should be explicitly confirmed by the user for the first time and show the file path and the content to be inserted (or symlink).
(Just prompt like the quit confirmation. )
Since my configuration has its own structure, I don't want to be silently modified every time I start kitty with `kitty --config=NONE`.
You can use
kitty --config=NONE -o shell_integration=enabled\ no-rc
And a first time check is not going to change this, since that check
will happen only once, not every time you run kitty.
File that already existed: `~/.config/fish/conf.d/kitty.fish`(regular file) , were replaced with symlink, resulting in file loss.
Yes that is unfortunate, but I dont see a good way to fix this. I
suppose I could check if the file is a regular file and if so rename it
before creating the symlink.
|
OK, I sat own and went through the shell integration script, and pulled the necessary bits into my |
On Fri, Aug 20, 2021 at 01:41:37AM -0700, John Lenton wrote:
OK, I sat own and went through the shell integration script, and pulled the necessary bits into my `.bashrc`.
Everything works, *except* the C+S+x/C+S+z combos.
Just to be sure I'm not misunderstanding: C+S+h to open the scrollback, and within it C+S+z/C+S+x should move me between prompts, right? I also tried outside of the C+S+h scrollback pager in case I was misunderstanding but that didn't work either.
No the shortcuts work in normal kitty view, not in the scrollback pager.
|
Click on prompt command to move the cursor is very useful. Thank you very much. Is it possible to delete the selected text? I currently use the following custom kitten to delete, although it's not perfect. I need to click first, then go forward and select the text to be deleted, then execute it. from typing import List
from kitty.boss import Boss
from kittens.tui.handler import result_handler
def main(args):
pass
@result_handler(type_of_input='selection', no_ui=True)
def handle_result(args: List[str], text: str, target_window_id: int, boss: Boss) -> None:
w = boss.window_id_map.get(target_window_id)
if w is not None and w.screen.cursor_at_prompt():
lines = w.screen.text_for_selection()
n = len(text or (lines and len(lines) == 1 and lines[0]))
if n > 0:
w.send_text('normal', '\x7f' * n) # Backspace * n Why does the second parameter return How to output debug log when |
On Fri, Aug 20, 2021 at 06:49:01AM -0700, page-down wrote:
Click on prompt command to move the cursor is very useful. Thank you very much.
You are welcome.
Is it possible to delete the selected text?
No, doing that robustly is not really possible, since the selection
could include the prompt, for instance.
I currently use the following custom kitten to delete, although it's not perfect. I need to click first, then go forward and select the text to be deleted, then execute it.
```python
from typing import List
from kitty.boss import Boss
from kittens.tui.handler import result_handler
def main(args):
pass
@result_handler(type_of_input='selection', no_ui=True)
def handle_result(args: List[str], text: str, target_window_id: int, boss: Boss) -> None:
w = boss.window_id_map.get(target_window_id)
if w is not None and w.screen.cursor_at_prompt():
lines = w.screen.text_for_selection()
n = len(text or (lines and len(lines) == 1 and lines[0]))
if n > 0:
w.send_text('normal', '\x7f' * n) # Backspace * n
```
Why does the second parameter return `None` even though the selection is already there? (with ***@***.***_handler(type_of_input='selection')`)
The input is passed to main().
How to output debug log when `no_ui` is True?
|
In my own opinion, the purpose of A tab that doesn't execute any programs, a tab or OS window that has been laid out and has multiple paths open, still has its own value. Just like any other tab-enabled browser or editor software, it doesn't do anything, but it's there when you need it. I would like to use the shell integration features while retaining the ability to prevent OS windows or tabs with multiple window from closing accidentally. Maybe make this new feature as a new |
There are no changes to confirm_on_quit, you have to use negative values |
Sorry, I just saw the latest changes. The above feedback is for code that is a few dozen hours old. Confirm that the positive integer value reverts to its original behavior. |
No worries, I like to avoid making backwards incompatible changes as much as possible. Thus the use of negative numbers, see #3960 for discussion. |
It looks like this might be clobbering Versions of stuff:
I observe correct behavior when I preserve |
There should be no problem with saving and restoring it. Since you |
I went ahead and implemented it: 72e15d8 havent tested it with starship but I verified that the value of $status is preserved before clling _ksi_original_fish_prompt |
Can confirm fix, just pulled new kitty and tested with starship. Sorry I didn't get a patch in; I'd been using
|
Would it be reasonable to ask that, when shell integration is enabled, |
On Thu, Dec 16, 2021 at 05:47:26AM -0800, Martin Kletzander wrote:
I tested this with somewhat non-default configuration and it all seems to work (I did not test confirm-on-quit behaviour) except the cursor shape. The behaviour you describe here (it is changed to beam when editing a command) is enforced even when I explicitly specify 'cursor_shape block' in the config file.
You want
shell_integration enabled no-cursor
I would like to also comment on the usability. I think it is great to have these features (although the mouse ones I will probably never use) but one that is very similar to this and I would love to have is using the output of the last command as a parameter to currently edited command. I think that would be very helpful because even though I can do things like Up, Ctrl-A, Ctrl-K, write new command, space, '(', Ctrl-Y, ')', (or select the previous command and paste it, but that would require using the mouse) it would be way nicer to have something like Ctrl-Shift-<something> to paste (or somehow add a variable that would contain) the full output (or even the last line, which is most commonly used). It would also eliminate the need to run the command again when compared to on of the other solutions.
```
map f1 launch --stdin-source=last_cmd_output --type=background /some/program/that/copies/STDIN/to/clipboard
```
will put the last command output into the clipboard. And you can then
paste it using C-S-v
|
Oh wow! |
Thank you for implementing shell integration in Kitty. I love it! Now, whenever someone complains that their zsh prompt gets messed up when resizing a terminal window, I tell them to try Kitty.
This approach won't enable shell integration in the following cases:
Many users will bump into one or more of these. For shell integration to be useful, it needs to work reliably. I've implemented integration with Kitty in my zsh config. This config is public and has a few users other than myself. My integration doesn't suffer from the downsides listed above. However, since there is no mechanism to opt out from Kitty's native zsh integration, my users will have extra initialization code injected into their shells when/if Kitty's new release enables shell integration. At best it'll make their shell slower [1]. What do you recommend I do? One option would be to detect Kitty's native integration and print a warning asking the user to disable it. Is there a better alternative? Ideally Kitty's integration would be so good that I could disable my own implementation if I detect Kitty's. In practice this seems like a difficult goal to achieve. For example, for Kitty's integration to work over SSH it'll need to do rather invasive things. Improving Kitty's integration is obviously a valuable thing to do [2]; at the same time, it would be great if shells could opt out if they have the means to implement things better. Kitty's integration has to work with all shell configs, while a specific shell config has to solve a more specific, and often easier, problem. When running It would be great if Kitty had something like this. I think it already has a DCS with "kitty", so perhaps piggyback on that? On the other hand, impelementing OSC 1337 will allow shells to provide just one integration for multiple terminals rather than a custom integration for each. [1] I benchmarked with zsh-bench the effect of Kitty's native shell integration on top of my zsh config. The machine is MacBook Pro M1 (2021).
When starting a new shell, Kitty's native integration delays the first prompt by 2.5ms and the first command by 6.8ms. Afterwards it adds 2.1ms delay on every command. This may not sound like a lot but you start noticing lag on every command when it reaches 10ms or so. With a terminal as fast as Kitty the threshold might be even lower. The delay of 2.1ms eats 21% of the whole latency budget. [2] I sent out #4377 with a few small improvements to zsh integration. |
On Mon, Dec 20, 2021 at 04:24:55AM -0800, Roman Perepelitsa wrote:
Thank you for implementing shell integration in Kitty. I love it! Now, whenever someone complains that their zsh prompt gets messed up when resizing a terminal window, I tell them to try Kitty.
Cool :)
> As promised, here is my attempt to avoid having to modify zshrc. [f6e0eb4](f6e0eb4)
This approach won't enable shell integration in the following cases:
- If you manually run `zsh` in an existing interactive shell.
- Perhaps because your login shell is fish but occasionally you want something more POSIX-y.
- Perhaps because you need to create a temporary session with different environment variables.
- Perhaps because you are running `sudo -E zsh` to create an interactive privileged shell.
- If you SSH to a remote host with zsh as login shell.
- If you have `tmux` as login shell and configure it to start zsh.
- The problem here isn't that `tmux` won't propagate OSC 133. Kitty's integration script won't run at all.
- A variation of the above: If you have zsh as login shell and have this at the top of `~/.zshrc`:
```zsh
if [[ -z ${TMUX+X}${ZSH_SCRIPT+X}${ZSH_EXECUTION_STRING+X} ]]; then
exec tmux
fi
```
Many users will bump into one or more of these. For shell integration to be useful, it needs to work reliably.
This is deliberate. I don't want automatic shell integration to be too
invasive, because the user hasn't explicitly opted into it. There is a
section in the documentation that explains how to enable it for these
more involved use cases.
---
I've implemented integration with Kitty in my zsh config. This config is public and has a few users other than myself. My integration doesn't suffer from the downsides listed above. However, since there is no mechanism to opt out from Kitty's native zsh integration, my users will have extra initialization code injected into their shells when/if Kitty's new release enables shell integration. At best it'll make their shell slower [1].
Simply set shell_integration disabled in kitty.conf and kitty will not
try to inject anything into the shell's environment at all. The actual
shell integration will still work if your shell rodces the appropriate
escape codes.
What do you recommend I do? One option would be to detect Kitty's native integration and print a warning asking the user to disable it. Is there a better alternative?
There isn't currently a good way to disable this other than in kitty.conf.
Ideally Kitty's integration would be so good that I could disable my own implementation if I detect Kitty's. In practice this seems like a difficult goal to achieve. For example, for Kitty's integration to work over SSH it'll need to do rather invasive things. Improving Kitty's integration is obviously a valuable thing to do [2]; at the same time, it would be great if shells could opt out if they have the means to implement things better. Kitty's integration has to work with all shell configs, while a specific shell config has to solve a more specific, and often easier, problem.
I'm not sure what would be a good mechanism for this. Perhaps a sentinel
file in the filesystem or some other mechanism.
---
When running `script /dev/null`, Kitty is unable to detect the current working directory. iTerm2 and Apple Terminal can, provided that the shell cooperates. iTerm2 shell integration allows shell to report its current working directory via [OSC 1337](https://iterm2.com/documentation-escape-codes.html). Apple Terminal parses the shell-supplied terminal title and infers the current directory from it. The latter is not as reliable as the former but works most of the time.
It would be great if Kitty had something like this. I think it already has a DCS with "kitty", so perhaps piggyback on that? On the other hand, impelementing OSC 1337 will allow shells to provide just one integration for multiple terminals rather than a custom integration for each.
The canonical way to report working directory is OSC 7 not OSC 1337.
However, I am not a fan of this See some discussion here: https://gitlab.freedesktop.org/terminal-wg/specifications/-/issues/20
The basic problem with using escape codes for this is image if your
shell says cwd is X then you run an editor and do a cd there to Y
the terinal will still think you are in X.
kitty simply gets the working directory of the foreground process from
the kernel and uses that. Works very well in practice.
---
[1] I benchmarked with [zsh-bench](https://github.com/romkatv/zsh-bench) the effect of Kitty's native shell integration on top of my zsh config. The machine is MacBook Pro M1 (2021).
```text
% git clone https://github.com/romkatv/zsh-bench.git ~/zsh-bench
% sudo ~/zsh-bench/zsh-bench --isolation user --iters 64 -- zsh4humans-no-tmux zsh4humans-no-tmux-kitty
==> setting up user zsh-bench with zsh4humans-no-tmux ...
==> benchmarking login shell of user zsh-bench ...
creates_tty=0
has_compsys=1
has_syntax_highlighting=1
has_autosuggestions=1
has_git_prompt=0
first_prompt_lag_ms=16.647
first_command_lag_ms=49.967
command_lag_ms=3.599
input_lag_ms=7.338
exit_time_ms=14.993
==> setting up user zsh-bench with zsh4humans-no-tmux-kitty ...
==> benchmarking login shell of user zsh-bench ...
creates_tty=0
has_compsys=1
has_syntax_highlighting=1
has_autosuggestions=1
has_git_prompt=0
first_prompt_lag_ms=19.130
first_command_lag_ms=56.813
command_lag_ms=5.660
input_lag_ms=6.096
exit_time_ms=17.124
```
When starting a new shell, Kitty's native integration delays the first prompt by 2.5ms and the first command by 6.8ms. Afterwards it adds 2.1ms delay on every command.
This may not sound like a lot but you start noticing lag on every command when it reaches 10ms or so. With a terminal as fast as Kitty the threshold might be even lower. The delay of 2.1ms eats 21% of the whole latency budget.
[2] I sent out #4377 with a few small improvements to zsh integration.
I ma more than happy to improve the performance wherever possible, I
dont see any easy wins, but then I am not a zsh expert. So PRs are most
welcome.
…--
_____________________________________
Dr. Kovid Goyal
https://www.kovidgoyal.net
https://calibre-ebook.com
_____________________________________
|
Just to make sure I understand what you mean by deliberate. Suppose my login shell is zsh. I open a new tab. The shell in it gets shell integration automatically. I run Is this intended? If I send you a PR that makes both of these shells have shell integration, will you reject it because it's deliberate that only the first shell has integration?
You are writing a terminal and you would like its users to have good experience by default regardless of which shell config they use. I'm writing a shell config and I would like its users to have good experience by default regardless of which terminal they use. In order for Kitty users to have good experience you first attempted to modify their shell configs from the terminal. You didn't like doing it and neither would I. Now the table has turned: I need to modify a terminal's config from shell. Feels awful.
The PR I sent you incidentally adds a way for a shell to opt-out with only a minor performance cost. Users can put
Thanks for that link! I already have support for OSC 7 but I thought only VTE understood it. The discussion thread says that Terminal.app does too. I've enabled it and can confirm that it works!
This works as long as the process the user considers foreground is in the same session as the original process spawned by Kitty.
From the user's point of view, Just throwing the idea out there: An escape code for reporting the TTY that the user considers in the foreground. I could send it from zsh quite easily. Then Kitty could use the same algorithm it does now (get the foreground process), but with the right session.
Cool! I'll send you another PR after the first is dealt with. |
On Mon, Dec 20, 2021 at 05:58:02AM -0800, Roman Perepelitsa wrote:
> This is deliberate.
Just to make sure I understand what you mean by deliberate.
Suppose my login shell is zsh. I open a new tab. The shell in it gets shell integration automatically. I run `zsh` to create a new temporary interactive shell in which I'm going to export `CLAGS`, `LDFLAGS`, etc., and do some compiling. This shell does not get shell integration.
Is this intended? If I send you a PR that makes both of these shells have shell integration, will you reject it because it's deliberate that only the first shell has integration?
Yes, it is currently by design that automatic shell integration
only works in the shell run by kitty, not inside a multiplexer or
a sub-shell. This design might change in the future once this feature
has matured more and/or I see how th eecosystem evolves. But for the
moment, it is not going to change.
Users simply have to add a couple of lines to zshrc to enable shell
integration inside sub-shells/multiplexers.
I am hoping that once this feature becomes more widespread shells just
adopt it natively and I can retire the whole shell integration
sub-system in kitty. If however that does not happen, then perhaps we
can revisit this design decision.
> Simply set shell_integration disabled in kitty.conf and kitty will not try to inject anything into the shell's environment at all. There isn't currently a good way to disable this other than in kitty.conf.
You are writing a terminal and you would like its users to have good experience by default regardless of which shell config they use. I'm writing a shell config and I would like its users to have good experience by default regardless of which terminal they use. In order for Kitty users to have good experience you first attempted to modify their shell configs from the terminal. You didn't like doing it and neither would I. Now the table has turned: I need to modify a terminal's config from shell. Feels awful.
I'm not suggesting you do it. I'm just saying that's the only way
currently.
> I'm not sure what would be a good mechanism for this. Perhaps a sentinel file in the filesystem or some other mechanism.
The PR I sent you incidentally adds a way for a shell to opt-out with only a minor performance cost. Users can put `unset KITTY_SHELL_INTEGRATION` in `~/.zshenv`. Would you consider this a supported opt-out mechanism?
Sounds OK to me, though I haven't looked at your PR yet. I would like
a more general approach though not just a zsh specific one.
> kitty simply gets the working directory of the foreground process from the kernel and uses that. Works very well in practice.
This works as long as the process the user considers foreground is in the same session as the original process spawned by Kitty. `script /dev/null` results in a process tree like this:
```text
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
0 9557 9557 9557 pts/0 14586 Ss 0 0:00 zsh
9557 14586 14586 9557 pts/0 14586 S+ 0 0:00 \_ script /dev/null
14586 14587 14587 14587 pts/1 14592 Ss 0 0:00 \_ zsh -i
```
From the user's point of view, `zsh -i` with PID 14587 is the foreground process. It has a different session id from the original shell, so Kitty won't look at it. Kitty will think `zsh` with PID 9557 is the foreground process.
kitty use tcgetpgrp(), that returns which process group the kernel believes is
the foreground group for the tty. To me, a method that causes the users'
and the kernel's beliefs on this to diverge seems a mis-feature that
should not be used.
Just throwing the idea out there: An escape code for reporting the TTY that the user considers in the foreground. I could send it from zsh quite easily. Then Kitty could use the same algorithm it does now (get the foreground process), but with the right session.
Seems easier for whatever process is trying to take over the tty to call
tcsetpgrp() then both the kernel and kitty will know what the foreground
PG is.
> PRs are most welcome.
Cool! I'll send you another PR after the first is dealt with.
I will get around to reviewing it asap.
|
Each process belongs to a group. Each group belongs to a session. Each session may have one controlling terminal (or zero). Each terminal may be a controlling terminal of one session (or zero). When Kitty is looking for a foreground process, it goes like this: TTY => session => foreground group => group leader. Note that kitty's TTY is always the controlling terminal of the final process. When I run |
On Mon, Dec 20, 2021 at 06:58:22AM -0800, Roman Perepelitsa wrote:
> Seems easier for whatever process is trying to take over the tty to call tcsetpgrp() then both the kernel and kitty will know what the foreground PG is.
Each process belongs to a group. Each group belongs to a session. Each session may have one controlling terminal (or zero). Each terminal may be a controlling terminal of one session (or zero).
When Kitty is looking for a foreground process, it goes like this: TTY => session => foreground group => group leader. Note that kitty's TTY is always the controlling terminal of the final process.
When I run `script`, it creates another session, with another controlling terminal. Zsh process that I, as a user, consider foreground, is a leader of the foreground group of the new session and it has the new TTY as controlling terminal. I cannot use `tcsetpgrp(kitty_tty, zsh_gid)` because zsh process group doesn't belong to Kitty's session.
So dont use script? What is it that you are hoping to achieve by
creating a new process group via script? Generally you create a new
process group/session when you want to isolate the process from its
original environment, the canonical example being creating a daemon
process. It is correct behavior for the terminal to ignore the working
directory of a new process group that is not freground on the tty device
the terminal controls.
Note that, in your scenario you have one process that is foreground on
the tty and another that is not foreground but that it still outputting
to the terminal. This is, generally speaking a recipe for disaster,
unless the two processes are co-operating. In which case, the correct
solution os for process 2 to inform process 1 of a change of directory
and process 1 to change its own cwd accordingly.
|
I use script for its intended purpose -- to log my session. Script achieves this by creating a TTY. The side effect of creating a TTY is the creation of a new session. There is no other way, is there?
It depends on what you mean by "correct" and "ignore". iTerm and Terminal.app pick up the current directory from
That's right.
That's not right. Only processes from the foreground group can write to the TTY. If any other process attempts it, it'll get killed with
|
On Mon, Dec 20, 2021 at 07:37:06AM -0800, Roman Perepelitsa wrote:
> What is it that you are hoping to achieve by creating a new process group via script?
I use script for its intended purpose -- to log my session. Script achieves this by creating a TTY. The side effect of creating a TTY is the creation of a new session. There is no other way, is there?
Use something that both creates a new tty and also updates its working
directory when the cwd of the child process changes.
> It is correct behavior for the terminal to ignore the working directory of a new process group that is not freground on the tty device the terminal controls.
It depends on what you mean by "correct" and "ignore". iTerm and Terminal.app pick up the current directory from `script`. They display it in the title and use it when I open a new tab. Maybe it's incorrect but I like it.
Yeah it works in this case and fails in the case I outlined before, of
opening an editor and doing a cd in it. Pick your poison.
> and another that is not foreground but that it still outputting to the terminal.
That's not right. Only processes from the foreground group can write to the TTY. If any other process attempts it, it'll get killed with `SIGTTOU`.
Yeah it is outputting to the terminal via the *co-operating* parent
process. So it should be the parent processes job to update its working
directory when that of the child process does so.
If the parent process does that, there is no issue. And no need to use
hacks like OSC 7
|
At least on Linux this cannot be done. I don't know BSDs and macOS well enough to say whether it can be done there. The problem arises in the following situation. Suppose I run mount ... /mnt/blah
cd /mnt/blah
sleep 1
cd /
umount /mnt/blah The last command will most likely fail with "target is busy" because
Hence the idea: Add an OSC that would allow shell to tell the terminal which TTY is the foreground one. Are there cases where it won't work? P.S. I actually have a workaround that I use with Kitty but it's rather ugly. Within |
OK, it cannot be done anywhere with file permissions. The parent process is not guaranteed to have permissions to |
On Mon, Dec 20, 2021 at 07:59:55AM -0800, Roman Perepelitsa wrote:
Hence the idea: Add an OSC that would allow shell to tell the terminal which TTY is the foreground one. Are there cases where it won't work?
It suffers from the same limitation as OSC 7. Basically every program
you run has to be aware of it or you end up in situations where a parent
program sets it, then runs a child program that is not aware of the
protocol and the child program cds and then the terminal has the wrong
current directory. Here is a failure scenario:
1) parent process spawns a child with its own tty
2) child sets the tty via escape code and then cds
3) parent suspends child for whatever reason (say user presses ctrl-z or
equivalent)
4) terminal now has incorrect working dir
As far as the parent process not being able to cd for permissions,
that is an extreme corner case, and not worth worrying about, IMO.
If the parent doesn't have permissions to cd its highly unlikely the
termial or shells it launches in the future will have that permission
either.
|
And as for session recording, kitty already has --dump-bytes that records half of it (the data received over the tty). It should not be hard to extend it to implement script and scriptreplay robustly. Though I dont know why one would want to repay a terminal session for anything other than debug purposes. |
The difference between the proposed protocol and OSC 7 is that very few programs need to be aware of it. Only those that proxy data between TTYs: script, screen, tmux and unbuffer. Maybe I've missed one. [1] Each of these will need to send the name of the inner TTY to the parent TTY on start. Doing it just in tmux will likely cover the vast majority of cases where currently the terminal's idea of a foreground process doesn't match the user's idea.
It's a good point that Pressing Ctrl-Z or equivalent won't do it. Ctrl-Z is a shell binding. If you press it while running
I agree. The other issue is more severe because it'll break user programs. It would suck if programs that doesn't even use a terminal would fail when executed under
That's good to know. I might use it for other purposes. To be completely honest, I was a bit coy about my use case with [1] Maybe |
:) script is more compelling use case to me than tmux. It is one of the kitty goals to make terminal multiplexers obsolete. My views on it are well known, and I wont repeat them here. In any case, if you wish to continue this discussion please do so in a separate discussion post, as this is straying far form the topic of this issue. I do agree that your proposal is better than OSC 7 (although I think you have sadly underestimated the number of multiplexers out there, I am personally aware of at least 3-4 more). |
I'm well aware 😁
If even you know fewer than a dozen TTY proxies (some of which are multiplexers), the number must be small (compared to the number of all programs that people run in a TTY, that is).
Fair enough. Let's end this discussion then. I won't be opening an issue for it. It was just a random idea. Going back to the real topic of this issue, I'm working on improving zsh integration in Kitty. Will send a PR within a day or two. |
Sent #4386.
There is one more case, which might be the most common. Zsh users (and perhaps other shell users although I'm less familiar with their practices) often apply rc file changes to the current shell with I understand that it is your intention to turn off shell integration whenever users create a new shell but I cannot help but think it'll be very confusing. Sometimes prompt title will update, sometimes it won't. Sometimes cursor shape will change based on keymap and sometimes it wont. Sometimes key shortcuts that depend on shell integration will work and sometimes they won't. It's not going to be easy for users to figure out the exact conditions under which features work or don't work, and what they can do to make them either either consistently work or consistently not work. The thought that |
Closing as this has now been released |
For bash users: I have now implemented shell integration for bash without the need to modify .bashrc. Please test using the nightly build. For an overview of how it works, see |
Great! I think this is still nice, but this doesn't work for the child Bash sessions started by the command |
Yes, just as with the other shells, if you want integration in |
I have no kitty.app but ~/.nix-profile/bin/kitt@ |
this was released over a year ago. Use the official kitty binaries if your distro kitty package is out of date. |
I just finished working on shell integration for kitty. Before releasing, I'd like some testing/feedback from the community.
In brief, shell integration enables features such as:
Open the output of the last command in a pager such as less
(ctrl+shift+g)
Jump to the previous/next prompt in the scrollback
(ctrl+shit+z/ctrl+shift+x)
Click with the mouse anywhere in the current command to move the cursor there
The current working directory or the command being executed are automatically
displayed in the kitty window titlebar/tab title.
The text cursor is changed to a bar when editing commands at the shell prompt
Glitch free window resizing even with complex prompts. Achieved by erasing
the prompt on resize and allowing the shell to redraw it cleanly.
Sophisticated completion for the kitty command in the shell
When using confirm on quit windows that contain a shell sitting at the prompt doing nothing are optionally ignored (if you use negative numbers for confirm_on_quit)
It's currently implemented for the zsh, fish and bash shells.
It works by installing hooks into the shell that inform kitty of changes
in the shell state, via escape codes allowing kitty to know various
things about the shell such as the
location of the prompt, the command being run, etc. kitty then uses this
information to enable the above features.
What I would like is:
Testing, especially if you already use some kind of fancy prompt
setup, does the integration work with it/break it?
Comments on how well the functionality works/how useful it is
Details on how it works and how to configure it are in
docs/shell-integration.rst
To try it out use a nightly build of kitty
curl -L https://github.com/kovidgoyal/kitty/raw/master/docs/installer.sh | sh /dev/stdin \ installer=nightly dest=/some/other/location
or build from source.
Running it should automatically enable shell integration if you use one
of the supported shells. To turn it off simply set
in kitty.conf
Note that shell integration for bash only will write three lines at the end of your
.bashrc. These are safe to remove at any time, and will have no
effect unless you are running kitty with shell integration enabled. This is needed because bash is the only shell that provides no way for the invoking program to inject code into it robustly.
Thanks, and enjoy!
The text was updated successfully, but these errors were encountered: