Search code examples
fish

fish shell: Prompt changing to '>'


I recently switched to fish and modified one of the prompts available from fish_config to look like this.

function fish_greeting
    fortune
end

function fish_prompt

    echo

    set -l retc brblack
    test $status = 0; and set retc bryellow

    set -q __fish_git_prompt_showupstream
    or set -g __fish_git_prompt_showupstream auto

    function _nim_prompt_wrapper
        set retc $argv[1]
        set cust $argv[4]
        set field_name $argv[2]
        set field_value $argv[3]

        set_color normal
        set_color $retc
        echo
        echo -n ' ├─'
        echo -n '[ '

        set_color normal
        test -n $field_name
        and echo -n $field_name

        set_color -o brblack
        echo -n ' ▶ '

        set_color $retc
        set_color $cust
        echo -n $field_value

        set_color $retc
        echo -n ' ]'
    end

    set_color $retc
    echo -n '─┬─'
    echo -n '[ '

    set_color -o red
    echo -n (prompt_hostname)
    echo -n ': '

    if test "$USER" = root -o "$USER" = toor
        set_color -o brred
    else
        set_color -o brwhite
    end
    echo -n $USER

    set_color -o brblack
    echo -n ' ▶ '

    set_color -o brcyan
    echo -n (pwd)

    set_color $retc
    echo -n ' ]'

    # Virtual Environment
    set -q VIRTUAL_ENV_DISABLE_PROMPT
    or set -g VIRTUAL_ENV_DISABLE_PROMPT true
    set -q VIRTUAL_ENV
    and _nim_prompt_wrapper $retc '🐍 ' (basename "$VIRTUAL_ENV") cyan

    # git
    set prompt_git (fish_git_prompt | string trim -c ' ()')
    test -n "$prompt_git"
    and _nim_prompt_wrapper $retc (basename -s .git (git config --get remote.origin.url) 2> /dev/null) $prompt_git

    # New line
    echo

    # Background jobs
    set_color normal
    for job in (jobs)
        set_color $retc
        echo -n ' │ '
        set_color brown
        echo $job
    end
    set_color normal
    set_color $retc
    echo -n ' ╰─> '
    set_color normal
end

The general layout of my prompt:

─┬─[ hostname: user ▶ pwd ]
 ╰─> _

And blow is what I want instead of >:

─┬─[ hostname: user ]
 ├─[ pwd ]
 ╰─> _

OR

─┬─[ hostname: username ]
 ├─⎡ as_much_as_possible ⎤
 ├─⎣ the_rest_of_PWD     ⎦
 ╰─> _

But, when $PWD is longer than the window's column size, the whole prompt is just >. I feel that using $COLUMNS should work, but I don't know how I can check the length of pwd before echoing it.

I DO NOT WANT TO USE prompt_pwd.

Thanks in advance! ;)


Solution

  • You can store whatever you want in a variable and then check it, modify it however you want and then echo it.

    Here's a rough sketch:

    set -l firstline '─┬─[' (prompt_hostname): $USER ▶ $PWD ']'
    set -l secondline
    if test (string length -- "$firstline") -gt $COLUMNS
         # move $PWD to the second line
         set firstline '─┬─[' (prompt_hostname): $USER ']'
         set secondline '├─[' $PWD ']'
    end
    echo $firstline
    echo $secondline
    

    I DO NOT WANT TO USE prompt_pwd.

    You very possibly do. It handles replacing $HOME with ~ (which saves quite a few columns) and does shortening to $fish_prompt_pwd_dir_length characters, or no shortening other than ~ if that's set to 0.

    You can even adapt the shortening to $COLUMNS. From my prompt:

    # Shorten pwd if prompt is too long
    set -l pwd (prompt_pwd)
    # 0 means unshortened
    for i in $fish_prompt_pwd_dir_length 0 10 9 8 7 6 5 4 3 2 1
        set pwd (fish_prompt_pwd_dir_length=$i prompt_pwd)
        set -l len (string length -- $prompt_host_nocolor$pwd$last_status$delim' ')
        if test $len -lt $COLUMNS
            break
        end
    end