wez / wezterm

A GPU-accelerated cross-platform terminal emulator and multiplexer written by @wez and implemented in Rust
https://wezfurlong.org/wezterm/
Other
14.91k stars 674 forks source link

Shell Integration and beyond #115

Open wez opened 4 years ago

wez commented 4 years ago

This issue is a placeholder/umbrella for some things that are not super well defined today. We may or may not implement some or all of these features. I'm just collecting these together for later review in depth.

Ghost-Terms commented 4 years ago

How about starship integration? It's also coded in Rust.

Though I'm not sure if integration in this context means embedding your own version, or making them work harmoniously.

wez commented 4 years ago

starship and powerline and utilities in that category customize your shell to show contextual or system information (and don't really care much about the terminal really) but this issue more about making the terminal understand the semantics of what is being output, rather than just dealing with the bytes.

The linked semantic escapes featureset has escape sequences that the shell can output and allow iTerm2 to define a keyboard shortcut to jump to the start/end of a previous command's output, rather than just by scrolling/paging backwards.

DomTerm uses the additional information to render your prompt area with different styling and gutter to make it much more visually apparent where the output and input begin and end.

Those escapes open things up for some interesting/useful additional functions; for example, rather than manually dragging to select the output from the last command, if the terminal knew its boundaries, then we could eg: offer a keyboard shortcut to copy the entire output from the last command.

Ghost-Terms commented 4 years ago

My mistake, I keep getting wzsh and wezterm conflated in my head.

dfrankland commented 4 years ago

Has anyone tested OSC 7 CWD and tabs for macOS? I use fish shell which supports it natively, but it doesn't seem to work for me.

wez commented 4 years ago

@dfrankland it's working for me using https://wezfurlong.org/wezterm/shell-integration.html#osc-7-escape-sequence-to-set-the-working-directory (and some more elaborate variations of this).

I'd suggest running RUST_LOG=trace /path/to/wezterm and then changing the directory in your fish shell a couple of times. The stderr should capture the parsed version of the escape sequences and we go from there.

dfrankland commented 3 years ago

I finally figured it out! I found how fish is updating the OSC 7 CWD and realized that if I set the VTE_VERSION it would work:

return {
  set_environment_variables = {
    VTE_VERSION = '6003',
  },
}
Without setting `VTE_VERSION`, the following would have to be added to `fish_prompt`, copied from `__fish_config_interactive.fish` ```fish function fish_prompt printf \e\]7\;file://%s%s\a $hostname (string escape --style=url $PWD) printf '%s%s%s@%s %s%s%s>' \ (set_color $fish_color_cwd) \ (whoami) \ (set_color normal) \ (hostname | cut -d . -f 1) \ (set_color $fish_color_cwd) \ (prompt_pwd) \ (set_color normal) end ```
wez commented 3 years ago

@dfrankland thanks for that; I've opened a PR to have fish detect wezterm so that this should be more automatic in a future release of fish!

wez commented 3 years ago

@dfrankland BTW, we've since grown https://github.com/wez/wezterm/blob/master/assets/shell-integration/wezterm.sh with deeper integration for bash and zsh. In addition to OSC 7 there are some OSC 133 sequences that can be used to semantically markup the prompt "chrome", the input text you write into the shell prompt and the output text from a command so that WezTerm knows what kind of output is where in the scrollback. WezTerm can use those annotations to "page up" and jump to the start of each command output, or to eg: change triple-click to select the entire command output.

I don't know if any of that is of interest to you, or if you fancy taking a crack at applying that to your fish config. There's a little bit more documentation in https://wezfurlong.org/wezterm/shell-integration.html that links to relevant config options to take advantage of it, but it could do with a bit more exposition.

Strykar commented 3 years ago

So how do I integrate https://github.com/wez/wezterm/blob/main/assets/shell-integration/wezterm.sh with wezterm?

wez commented 3 years ago

So how do I integrate https://github.com/wez/wezterm/blob/main/assets/shell-integration/wezterm.sh with wezterm?

The Fedora and Debian packages install that file to /etc/profile.d which should cause bash/zsh to source it on startup.

If you're not using those packages/systems, you can manually source that file from your shell startup files (eg: .bashrc)

Strykar commented 3 years ago

If you're not using those packages/systems, you can manually source that file from your shell startup files (eg: .bashrc)

I'm on Arch linux, I only wish to source it for wezterm, not any other terminals I use.

wez commented 3 years ago

If you're not using those packages/systems, you can manually source that file from your shell startup files (eg: .bashrc)

I'm on Arch linux, I only wish to source it for wezterm, not any other terminals I use.

The packaging for arch doesn't distribute those files today. https://matrix.to/#/!PirwUBcuIlTXwNveYz:matrix.org/$GKCp1cALTteojKA0Uz6ycCgyJKwX4MnEUJdJA9hXp7c?via=matrix.org&via=butterfly.zone&via=kwatra.me is a discussion and a patch set for adding it to the AURs.

You can however download that shell script and source it for yourself.

goyalyashpal commented 1 year ago

will hide this comment myself

semantic prompts; see it visualized here.

The main idea is that the shell sends extra escape sequences to mark the various parts of a command: prompt, input, and output.

This above idea of "semantic prompts" is awesome, i've been thinking about something like this for quite a while, but didnt know about it. nice to know.

rodolf0 commented 1 year ago

Hi, I like the idea of semantic prompts :D wondering if there's any prototype work being done in that realm.

It'd be really nice to be able to shade background of different commands slightly different. Or being able to jump-scroll across large command outputs. I currently hack this by making my PS1 output a non visible unlikely char and back search for that, but first class support would be really nice.

wez commented 1 year ago

@rodolf0 if you source that wezterm.sh file then you will have working semantic prompts as mentioned at the top of https://wezfurlong.org/wezterm/shell-integration.html#shell-integration

rodolf0 commented 1 year ago

Nice! I'll try that out. Does each semantic section have access to any variables bound to their value at the time of execution? (I mean probably not, I'm just thinking about how I'd like to use it).

For example if the PWD at the time of execution is captured it enable interesting things for hyperlinks, like completing relative paths.

Other variables that would be useful are timestamp of start/end, pipeline-status exit codes, user, maybe some other en vars

On Mon, Sep 12, 2022, 9:22 AM Wez Furlong @.***> wrote:

@rodolf0 https://github.com/rodolf0 if you source that wezterm.sh file then you will have working semantic prompts as mentioned at the top of https://wezfurlong.org/wezterm/shell-integration.html#shell-integration

— Reply to this email directly, view it on GitHub https://github.com/wez/wezterm/issues/115#issuecomment-1243736284, or unsubscribe https://github.com/notifications/unsubscribe-auth/AACMOLKPVQHFTUIT3BVZ4BDV54VCTANCNFSM4KFVW3HQ . You are receiving this because you were mentioned.Message ID: @.***>

wez commented 1 year ago

wezterm currently only captures the zone type into the data model.

kaddkaka commented 1 year ago

What part of semantic prompts is missing for this to be closed?

wez commented 1 year ago

Are you volunteering? There's some stuff around capturing and recording process status and some other metadata. Maybe it's not worth capturing but it needs some thought that I don't have time for right now.

alexjuda commented 1 year ago

So how do I integrate https://github.com/wez/wezterm/blob/main/assets/shell-integration/wezterm.sh with wezterm?

The Fedora and Debian packages install that file to /etc/profile.d which should cause bash/zsh to source it on startup.

If you're not using those packages/systems, you can manually source that file from your shell startup files (eg: .bashrc)

Thanks so much for this tip! I couldn't make wezterm remember my working dir when opening new tabs. My set up: wezterm installed by flatpak, Fedora 37, bash. To make matters worse, the docs section about escape sequences was a red herring: I've already had /etc/profile.d/vte.sh in place, but it exited quickly because $VTE_VERSION wasn't set.

Manually copying and pasting wezterm.sh under /etc/profile.d/ fixed it!

ValentinLeTallec commented 1 year ago

Any thought on adding DomTerm's shell-integration.fish to https://github.com/wez/wezterm/blob/main/assets/shell-integration ?

I wanted to make SelectTextAtMouseCursor 'SemanticZone' work with fish and the documentation for shell-integration mentioned DomTerm. Looking around in DomTerm's repo I found the file in question and sourcing it does enable SemanticZone to work properly. I think it could be cool to have it work out of the box for other users.

(The license is also pretty loose https://github.com/PerBothner/DomTerm/blob/master/COPYING)

wez commented 1 year ago

I don't use fish, haven't looked at it, and am unlikely to spend the time on fish myself. I am open to reviewing a PR that adds fish shell integration with equivalent functionality to that of the zsh/bash integration.

eugenesvk commented 1 year ago

FYI I've added these integrations to the python-based xonsh shell, https://github.com/jnoortheen/xontrib-term-integrations/pull/6 (this plugin is terminal-agnostic, so you can use the same shell config in iTerm and WezTerm), with all the 3 document escape code types for WezTerm Works with a few bugs (filed with the weterm/xonsh's projects)

eugenesvk commented 1 year ago

As a follow-up from this discussion https://github.com/wez/wezterm/discussions/3130, would you please keep track of the following feature in the semantic zone implementation:

mkpaz commented 11 months ago

FYI. wezterm.sh breaks Konsole + starship integration. I spent an hour to find out where this thin vertical line comes from, cause I had no idea wezterm installs anything to /etc/profile.d/. Thanks for the envs to bypass, but I'd be good either to apply such integration to wezterm only or make it manual (enable bypass by default) to make users aware of its existence and potential issues like this one.

image

wez commented 11 months ago

@mkpaz I suspect that is Konsole marking up the output regions based on the semantic zones. I don't think it is broken per-se, but perhaps just not what you expected? In other words, I think Konsole also supports the same sequences, but the appearance of their effects is surprising to you.

You can disable it if you wish; see the comments in the shell integration itself:

https://github.com/wez/wezterm/blob/b54b0ce40428a8f910cd7c6fd94fd58e2f0ff88b/assets/shell-integration/wezterm.sh#L6-L15

ninjalj commented 11 months ago

In Konsole, this is under profile configuration, on General → Semantic Integration → Alternating bars

curable-online commented 6 months ago

Any thought on adding DomTerm's shell-integration.fish to https://github.com/wez/wezterm/blob/main/assets/shell-integration ?

I wanted to make SelectTextAtMouseCursor 'SemanticZone' work with fish and the documentation for shell-integration mentioned DomTerm. Looking around in DomTerm's repo I found the file in question and sourcing it does enable SemanticZone to work properly. I think it could be cool to have it work out of the box for other users.

(The license is also pretty loose https://github.com/PerBothner/DomTerm/blob/master/COPYING)

Thanks for mentioning… Fish already had all features that I was setting up before in Bash and Zsh with a lot of effort, natively; but lacking semantic prompts was not acceptable… Your comment here was the only clue on the entire internet to tell me how to enable semantic prompts for Fish, and that little old Fish script from PerBothner did all of it…

arthurgeek commented 5 months ago

@curable-online have you got it working? I sourced the script above and I can see OSC 133 sequences are set, but can't get wezterm to select according to a semantic zone.

~ $ fish_prompt | cat -v
^[[38;2;249;226;175m~^[(B^[[m ^[(B^[[m$ 
~ $ source semantic-prompt.fish
~ $ fish_prompt | cat -v
^[]133;P;k=i^G^[[38;2;249;226;175m~^[(B^[[m ^[(B^[[m$ ^[]133;B^G
~ $

wezterm.lua:

config.mouse_bindings = {
    {
        event = { Down = { streak = 3, button = "Left" } },
        action = wezterm.action.SelectTextAtMouseCursor("SemanticZone"),
        mods = "NONE",
    },
}
curable-online commented 5 months ago

I can scroll through semantic zones properly, and also select the whole semantic zone between prompts. I have set it to four left mouse clicks. You do not need to source anything, just put it in /etc/fish/config.d/ with any filename with .fish extension.

curable-online commented 5 months ago
config.mouse_bindings = {
  { event = { Down = { streak = 4, button = 'Left' } }, mods = 'NONE', action = act.SelectTextAtMouseCursor 'SemanticZone', }`
}
curable-online commented 5 months ago

@arthurgeek

config.mouse_bindings = {
  { event = { Down = { streak = 4, button = 'Left' } }, mods = 'NONE', action = act.SelectTextAtMouseCursor 'SemanticZone', }`
}

Where act is defined with local act = wezterm.action in the file, previously.

arthurgeek commented 5 months ago

@curable-online thanks! It's just like I have it.

You do not need to source anything, just put it in /etc/fish/config.d/ with any filename with .fish extension.

Yeah, I know, I sourced it in my output because I wanted to show that it didn't had any sequences prior to it.

I can scroll through semantic zones properly, and also select the whole semantic zone between prompts.

Can you let me know how do you scroll through those zones and select them? Perhaps I'm doing something wrong 😕. With that mouse binding, my expectation is that a 3 left mouse click (I'm actually using a trackpad, but if I change from SemanticZone to Line, it works, so I don't think this is the issue also) in any word/letter in the output of a command would copy the full output. is that correct? I'm testing with a simple curl -v http://ifconfig.me command and then, then a 3 left mouse clicks on any part of the output. I'm using wezterm nightly (20240111-073635-6c36a4dd).

I also loaded zsh and wezterms's shell integration to see if it was an issue with fish, but it also doesn't work.

Finally, in fish I use starship, and when testing in ZSH, my ZSH config was entirely blank, but I confirmed that OSC 133 sequences were being set after sourcing wezterm's shell integration.

curable-online commented 5 months ago

@arthurgeek Sorry for delay.

First of all, let's see if we are both using the same code. Follow is the code that I use to enable semantic reporting in fish:

#!/usr/bin/fish
# SPDX-License-Identifier: CC0-1.0
if status --is-interactive
  set _fishprompt_aid "fish"$fish_pid
  set _fishprompt_started 0
  # empty if running; or a numeric exit code; or CANCEL
  set _fishprompt_postexec ""

  functions -c fish_prompt _fishprompt_saved_prompt
  set _fishprompt_prompt_count 0
  set _fishprompt_disp_count 0
  function _fishprompt_start --on-event fish_prompt
    set _fishprompt_prompt_count (math $_fishprompt_prompt_count + 1)
# don't use post-exec, because it is called *before* omitted-newline output
    if [ -n "$_fishprompt_postexec" ]
      printf "\033]133;D;%s;aid=%s\007" "$_fishprompt_postexec" $_fishprompt_aid
    end
    printf "\033]133;A;aid=%s;cl=m\007" $_fishprompt_aid
  end

  function fish_prompt
    set _fishprompt_disp_count (math $_fishprompt_disp_count + 1)
    printf "\033]133;P;k=i\007%b\033]133;B\007" (string join "\n" (_fishprompt_saved_prompt))
    set _fishprompt_started 1
    set _fishprompt_postexec ""
  end

  function _fishprompt_preexec --on-event fish_preexec
    if [ "$_fishprompt_started" = "1" ]
      printf "\033]133;C;\007"
    end
    set _fishprompt_started 0
  end

  function _fishprompt_postexec --on-event fish_postexec
     set _fishprompt_postexec $status
    _fishprompt_start
  end

  function __fishprompt_cancel --on-event fish_cancel
     set _fishprompt_postexec CANCEL
    _fishprompt_start
  end

  function _fishprompt_exit --on-process %self
    if [ "$_fishprompt_started" = "1" ]
      printf "\033]133;Z;aid=%s\007" $_fishprompt_aid
    end
  end

  if functions -q fish_right_prompt
    functions -c fish_right_prompt _fishprompt_saved_right_prompt
    function fish_right_prompt
       printf "\033]133;P;k=r\007%b\033]133;B\007" (string join "\n" (_fishprompt_saved_right_prompt))
    end
  end
 end

I save this in this file /etc/fish/conf.d/shell-integration.fish.

Now, When I click on a text between two prompts, four times (as my configuration), The whole text between the upper prompt, and it's issued shell and next prompt will be selected. Like the following picture: Screenshot from 2024-01-22 00-36-39 As you can see, prompts and commands are not selected, but only the entire text between the upper prompt and its executed command, and the next prompt will be selected.

Scrolling also works the same, it brings you to next/previous prompt when you scroll between semantics.

mgpinf commented 5 months ago

@arthurgeek I guess the issue for you is because of where the starship init code is being called. Based on where it is called, the shell integration script is sourced before or after it.

In the shell integration script, the fish_prompt function is defined. In the starship init script, the fish_prompt function is defined as well.

Source the starship init code first, then the shell integration script.

By sourcing the starship init code first, the fish_prompt function is now the one as defined by starship init code.

Upon sourcing the shell integration script, it makes a copy of the fish_prompt function to _fishprompt_saved_prompt function, and then redefines the fish_prompt function and internally calls _fishprompt_saved_prompt and adds shell integration escape sequences around it.

You can call shell integration code after starship code in these ways:

Thanks a lot for mentioning that you use starship, else I don't think I would have been able to figure why selecting semantic zone is not working in fish shell.

I was able to doubt that it could be caused by where starship code was called, since shell integration script was working perfectly for @curable-online.

I had been facing the same issue and took quite a while to figure this out.

Hope this helps those using wezterm with fish shell :)

ArchWand commented 4 weeks ago

Hi, are there any plans to add a "jump cursor on mouse click" functionality like iTerm2 or kitty? Clicking on the input should send a bunch of left (or right) arrow key presses to the shell to move the cursor to where the mouse clicked. Is this possible with the current version of wezterm?