JanDeDobbeleer / oh-my-posh

The most customisable and low-latency cross platform/shell prompt renderer
https://ohmyposh.dev
MIT License
16.79k stars 2.35k forks source link

WSL, SSH and tmux oddities #1308

Closed bozho closed 2 years ago

bozho commented 2 years ago

Code of Conduct

What happened?

I run oh-my-posh both in my PowerShell 5.1 (installed as a module) and in my WSL Debian installation, in bash. They both share the theme below. I use Windows Terminal.

The theme works as expected in PS 5.1 (oh-my-posh module v5.8.0). In a directory with a git repository, running an elevated instance of Windows Terminal, I see something like this:

image

There are strange thing happening in WSL, with oh-my-posh 6.14.0 installed.

When I open WSL bash shell directly and go the the same directory, I don't see the git segment:

image

Notice that OS detection is detecting WSL/Debian. Free disk space segment is not shown, as expected.

When I run tmux, nothing changes.

When I ssh into my WSL/Debian, git segment appears:

image

However, if I then start tmux in the ssh session, powerline symbols are not shown correctly:

image

To add to the strangeness, if I start tmux in my "direct" WSL/Debian shell first (and lose the git segment), and then start tmux in my ssh session, the prompt in tmux ssh session will also not show the git segment. bash TERM variable is set to screen when tmux runs. Manually changing it to xterm-256color in a tmux session (local or remote) has no effect.

Running oh-my-posh --debug --shell uni --config="$POSH_THEME" in the local WSL/Debian session, it looks like git segment is looking for git.exe, not git:

2021/11/25 10:40:13 getcwd duration: 300ns, args:
2021/11/25 10:40:13 error: hasCommand
exec: "git.exe": executable file not found in $PATH
2021/11/25 10:40:13 hasCommand duration: 1.8312ms, args: git.exe
2

Running the same command while ssh'd into my WSL/Debian, it finds git:

2021/11/25 10:40:20 getenv duration: 1.8µs, args: WSL_DISTRO_NAME
2021/11/25 10:40:20 isWsl duration: 5µs, args:
2021/11/25 10:40:20 hasCommand duration: 42.9µs, args: git
2021/11/25 10:40:20 getcwd duration: 300ns, args:
2021/11/25 10:40:20 hasParentFilePath duration: 14.3µs, args: .git
2021/11/25 10:40:20 getRuntimeGOOS duration: 200ns, args:
2021/11/25 10:40:20 debug: getenv

If I start tmux in my SSH session after tmux has been started in the local session, OS detection changes from Debian to WSL - Debian, and the debug command is again looking for git.exe

Theme

{
  "$schema": "https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json",
  "final_space": false,
  "osc99": false,
  "console_title": false,
  "blocks": [
    {
      "type": "prompt",
      "alignment": "left",
      "horizontal_offset": 0,
      "vertical_offset": 0,
      "segments": [
        {
          "type": "root",
          "style": "plain",
          "foreground": "#ce0404",
          "properties": {
            "root_icon": "\uf740"
          }
        },
        {
          "type": "os",
          "style": "plain",
          "foreground": "#26C6DA",
          "properties": {
          }
        },
        {
          "type": "time",
          "style": "plain",
          //"foreground": "#007ACC",
          "foreground": "lightBlue",
          "properties": {
            "time_format": "15:04"
          }
        },
        {
          "type": "text",
          "style": "plain",
          "foreground": "lightYellow",
          "properties": {
            "prefix": "",
            "postfix": "",
            "text": "["
          }
        },
        {
          "type": "path",
          "style": "plain",
          "foreground": "lightYellow",
          "properties": {
            "prefix": "",
            "postfix": "",
            "style": "full",
            "mapped_locations": {
              "F:\\Temp\\": "\ue799",
              "/tmp/": "\ue799",
            }
          }
        },
        {
          "type": "text",
          "style": "plain",
          "foreground": "lightYellow",
          "properties": {
            "prefix": "",
            "postfix": "",
            "text": "]"
          }
        },
        {
          "type": "git",
          "style": "plain",
          "foreground": "#1cb3e0",
          "properties": {
            "prefix": "<#ffffff> [</>",
            "postfix": "<#ffffff>]</>",
            "display_status": true,
            "display_branch_status": true,
            "display_status_detail": true,
            "display_stash_count": true,
            "display_worktree_count": false,
            "display_upstream_icon": true,
            "branch_max_length": 0,
            "status_colors_enabled": true,
            "color_background": false,
            "local_changes_color": "lightRed",
            "ahead_and_behind_color": "lightYellow",
            "behind_color": "lightRed",
            "ahead_color": "lightGreen",
            "working_color": "lightRed",
            "staging_color": "green"
          }
        },
        {
          "type": "python",
          "style": "plain",
          "powerline_symbol": "\uE0B0",
          "foreground": "#906cff",
          "properties": {
            "home_enabled": true,
            "display_mode": "environment",
            "prefix": " {\ue606 ",
            "postfix": "}"
          }
        },
        {
          "type": "envvar",
          "style": "plain",
          "foreground": "green",
          "properties": {
            "var_name": "POSH_FREE_DISK",
            "prefix": " (",
            "postfix": ")"
          }
        },
        {
          "type": "text",
          "style": "plain",
          "foreground": "white",
          "properties": {
            "prefix": " ",
            "postfix": "",
            "text": ">"
          }
        }
      ]
    }
  ]
}

What OS are you seeing the problem on?

Linux

Which shell are you using?

bash

Log output

Local WSL/Debian session, no tmux running:

Version: 6.14.0

Segments:

ConsoleTitle(false) -   0 ms - 
root(false)   -   0 ms - 
os(true)      -  90 ms -  WSL - ??? 
time(true)    -   0 ms -  10:45 
text(true)    -   0 ms - [
path(true)    -   0 ms - <redacted>
text(true)    -   0 ms - ]
git(false)    -   1 ms - 
python(false) -   0 ms - 
envvar(false) -   0 ms - 
text(true)    -   0 ms -  >

Run duration: 93.3891ms

Logs:

2021/11/25 10:45:50 debug: getenv

2021/11/25 10:45:50 getenv duration: 8.1??s, args: XDG_CACHE_HOME
2021/11/25 10:45:50 getCachePath duration: 102.2??s, args: 
2021/11/25 10:45:50 getArgs duration: 300ns, args: 
2021/11/25 10:45:50 getArgs duration: 200ns, args: 
2021/11/25 10:45:50 getShellName duration: 400ns, args: 
2021/11/25 10:45:50 debug: getenv

2021/11/25 10:45:50 getenv duration: 2??s, args: OMP_CACHE_DISABLED
2021/11/25 10:45:50 isRunningAsRoot duration: 1.4??s, args: 
2021/11/25 10:45:50 getcwd duration: 32.9??s, args: 
2021/11/25 10:45:50 getPathSeperator duration: 300ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 300ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 300ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 300ns, args: 
2021/11/25 10:45:50 getShellName duration: 300ns, args: 
2021/11/25 10:45:50 getCurrentUser duration: 400ns, args: 
2021/11/25 10:45:50 getHostName duration: 2.2??s, args: 
2021/11/25 10:45:50 getcwd duration: 300ns, args: 
2021/11/25 10:45:50 isRunningAsRoot duration: 400ns, args: 
2021/11/25 10:45:50 getcwd duration: 200ns, args: 
2021/11/25 10:45:50 getRuntimeGOOS duration: 300ns, args: 
2021/11/25 10:45:50 debug: getenv
Debian
2021/11/25 10:45:50 getenv duration: 1.4??s, args: WSL_DISTRO_NAME
2021/11/25 10:45:50 getcwd duration: 500ns, args: 
2021/11/25 10:45:50 getcwd duration: 300ns, args: 
2021/11/25 10:45:50 isRunningAsRoot duration: 500ns, args: 
2021/11/25 10:45:50 getcwd duration: 300ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 300ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 300ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 300ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 300ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 300ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getShellName duration: 400ns, args: 
2021/11/25 10:45:50 getCurrentUser duration: 500ns, args: 
2021/11/25 10:45:50 getHostName duration: 1.8??s, args: 
2021/11/25 10:45:50 getcwd duration: 300ns, args: 
2021/11/25 10:45:50 getcwd duration: 200ns, args: 
2021/11/25 10:45:50 getArgs duration: 300ns, args: 
2021/11/25 10:45:50 getcwd duration: 200ns, args: 
2021/11/25 10:45:50 getRuntimeGOOS duration: 300ns, args: 
2021/11/25 10:45:50 getRuntimeGOOS duration: 200ns, args: 
2021/11/25 10:45:50 getRuntimeGOOS duration: 200ns, args: 
2021/11/25 10:45:50 getRuntimeGOOS duration: 200ns, args: 
2021/11/25 10:45:50 getRuntimeGOOS duration: 300ns, args: 
2021/11/25 10:45:50 getRuntimeGOOS duration: 300ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 300ns, args: 
2021/11/25 10:45:50 getRuntimeGOOS duration: 300ns, args: 
2021/11/25 10:45:50 getcwd duration: 200ns, args: 
2021/11/25 10:45:50 isRunningAsRoot duration: 400ns, args: 
2021/11/25 10:45:50 getcwd duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 300ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 300ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 300ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 300ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 300ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 300ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getShellName duration: 300ns, args: 
2021/11/25 10:45:50 getCurrentUser duration: 400ns, args: 
2021/11/25 10:45:50 getHostName duration: 1.1??s, args: 
2021/11/25 10:45:50 getcwd duration: 300ns, args: 
2021/11/25 10:45:50 getRuntimeGOOS duration: 200ns, args: 
2021/11/25 10:45:50 debug: getenv
Debian
2021/11/25 10:45:50 getenv duration: 2??s, args: WSL_DISTRO_NAME
2021/11/25 10:45:50 isWsl duration: 5.3??s, args: 
2021/11/25 10:45:50 getcwd duration: 300ns, args: 
2021/11/25 10:45:50 error: hasCommand
exec: "git.exe": executable file not found in $PATH
2021/11/25 10:45:50 hasCommand duration: 1.5151ms, args: git.exe
2021/11/25 10:45:50 getcwd duration: 200ns, args: 
2021/11/25 10:45:50 getcwd duration: 200ns, args: 
2021/11/25 10:45:50 debug: getenv

2021/11/25 10:45:50 getenv duration: 1.7??s, args: VIRTUAL_ENV
2021/11/25 10:45:50 debug: getenv

2021/11/25 10:45:50 getenv duration: 1.3??s, args: CONDA_ENV_PATH
2021/11/25 10:45:50 debug: getenv

2021/11/25 10:45:50 getenv duration: 1.3??s, args: CONDA_DEFAULT_ENV
2021/11/25 10:45:50 debug: getenv

2021/11/25 10:45:50 getenv duration: 1.2??s, args: PYENV_VERSION
2021/11/25 10:45:50 getcwd duration: 200ns, args: 
2021/11/25 10:45:50 debug: getenv

2021/11/25 10:45:50 getenv duration: 1.2??s, args: POSH_FREE_DISK
2021/11/25 10:45:50 getcwd duration: 300ns, args: 
2021/11/25 10:45:50 isRunningAsRoot duration: 400ns, args: 
2021/11/25 10:45:50 getcwd duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 300ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 300ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 300ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 300ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getPathSeperator duration: 200ns, args: 
2021/11/25 10:45:50 getShellName duration: 300ns, args: 
2021/11/25 10:45:50 getCurrentUser duration: 300ns, args: 
2021/11/25 10:45:50 getHostName duration: 1.3??s, args:
JanDeDobbeleer commented 2 years ago

@bozho we fallback to git.exe when the repo is on a shared drive (as otherwise it can't handle the location). The rule is as follows:

Depending on how you enter, those conditions will not be met (and thus for those paths the segment will not show).

bozho commented 2 years ago

@JanDeDobbeleer When you say "can't handle the location" - do you mean that Linux git would not be able to handle the repo on a shared drive?

I did a bit more testing and it looks like each tmux session inherits existing tmux sessions' env variables.

If I start tmux from a local WSL/Debian session first, it will have WSL_DISTRO_NAME env variable defined. If I then start another tmux session from an SSH session to WSL/Debian, that tmux will inherit environment from the already running (local) tmux sesison, and oh-my-posh will also look for git.exe.

However, if I first start tmux in the remote SSH session, it will not have WSL_DISTRO_NAME env variable defined, and git segment will work. If I then start another tmux in the local WSL/Debian session, it will inherit remote tmux environment (without WSL_DISTRO_NAME env variable), and git segment will work. When I run oh-my-posh --debug ... command, it shows that it looks and find native git command, so it looks like native git can handle repos on shared drives.

Any idea about messed up powerline symbols on remote tmux sessions?

JanDeDobbeleer commented 2 years ago

The messed up symbols is something I have no idea about. My bet is that tmux ruins your terminal's encoding (or font rendering) I seem to remember there being a Windows Terminal issue about tmux ruining certain things, but that's definitely not oh-my-posh as it can't influence that.

@lnu do you remember why we fall back to git.exe on shared WSL drives? Otherwise I'll look through the history.

bozho commented 2 years ago

The strange thing about tmux messing up the symbols is that it only happens for for remote sessions. The prompt is fine in tmux on a local session, as well as when I SSH into my WSL distro. The combination of ssh + tmux seems to mess things up.

lnu commented 2 years ago

The messed up symbols is something I have no idea about. My bet is that tmux ruins your terminal's encoding (or font rendering) I seem to remember there being a Windows Terminal issue about tmux ruining certain things, but that's definitely not oh-my-posh as it can't influence that.

@lnu do you remember why we fall back to git.exe on shared WSL drives? Otherwise I'll look through the history.

https://github.com/JanDeDobbeleer/oh-my-posh/pull/509

bozho commented 2 years ago

Eh, the above seems to be interplay between ssh setting LC_ALL to C. Starting tmux as tmux -u fixes the problem. I suppose fixing the locale for ssh sessions would fix that, too.

lnu commented 2 years ago

here's the diff when using git vs git.exe for windows mounted folders: image

bozho commented 2 years ago

@lnu What is the difference? Refresh index: ... bit?

I tried running both native and Windows git(.exe) status on a shared dir on my machine, and the output is exactly the same.

Windows git is 2.34.0.windows.1, WSL/Debian is on 2.33

JanDeDobbeleer commented 2 years ago

@lnu we're always blocked by the speed issues on mounted drives it seems 😅

lnu commented 2 years ago

@lnu What is the difference? Refresh index: ... bit?

I tried running both native and Windows git(.exe) status on a shared dir on my machine, and the output is exactly the same.

Windows git is 2.34.0.windows.1, WSL/Debian is on 2.33

it always does this if I do a git status on windows mounted drive in wsl2(tested with several repos).

https://stackoverflow.com/questions/59061816/git-forces-refresh-index-after-switching-between-windows-and-linux

lnu commented 2 years ago

@lnu we're always blocked by the speed issues on mounted drives it seems 😅

One should never work on a mounted drive. If you want to work in wsl2, the git repo should be cloned is wsl2. I had too many issues in the past with that.

bozho commented 2 years ago

Ah, I'm on WSL1 - mostly due to shared disk performance :)

lnu commented 2 years ago

That explains the refresh index case

Sent from mobile

On 25 Nov 2021, at 12:24, Marko Bozikovic @.***> wrote:

 Ah, I'm on WSL1 - mostly due to shared disk performance :)

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe. Triage notifications on the go with GitHub Mobile for iOS or Android.

bozho commented 2 years ago

@lnu Ok, so if I understood correctly, this all works as intended, since you coded git segment a bit defensively when running under WSL, considering issues with native git command and repos on shared volumes, right?

lnu commented 2 years ago

yes, it was all about performance on wsl2.

JanDeDobbeleer commented 2 years ago

@bozho @lnu what's the output of wsl -l -v? I want to see if we can make it a bit smarter and only default to git.exe on WSL2 and not 1.

lnu commented 2 years ago

I was checking already. But you have to detect it from wsl itself. You can do it by executing uname -r. The wsl2 version will contain wsl2. image vs image

bozho commented 2 years ago

Thank you both!

lnu commented 2 years ago

tested and works fine on my side: image vs image

bozho commented 2 years ago

Updated both WSL/Debian and PS module, can confirm.

github-actions[bot] commented 6 months ago

This issue has been automatically locked since there has not been any recent activity (i.e. last half year) after it was closed. It helps our maintainers focus on the active issues. If you have found a problem that seems similar, please open a discussion first, complete the body with all the details necessary to reproduce, and mention this issue as reference.