2

I have a script, that when run sometimes/often outputs an "unescaped" ANSI escape sequence when encountering this line:

vim -X -u NONE -c "helptags ~/.vim/plugged/vim-fugitive/doc" -c q

The result looks like this:

enter image description here

I have no idea why this happens, as running the command on its own seems to never produce this "garbage". It only ever happens if the line is run; commenting it out removes the issue. Even weirder is the fact that it sometimes does not happen. It could be good, then I do something and it appears. The output of running the script is fine. Once it manifests, though, it seems persistent (* not true, see below) ... opening another terminal tab will usually show the problem.

Any idea what is happening here? Is vim picking up no some terminal setting ($TERM?) and interfering with the output? Or is there something else going on?

My utility functions for colored output is here, should it matter.

EDIT:

  • It turns out that changing the PS1 prompt to something like $ made the issue go away when it materialized, but re-instating the prompt to the colorful one did not bring the issue back, so I have a hard time finding some determinism here.

PS1 prompt setup is done here:

set_prompt(){
    local user=$(green "\u")
    local host=$(dark_yellow "\h")
    local workdir=$(pink "\w")
    local gitbranch=$(dark_red \$\(__git_ps1  "\(%s\)" \))
    local at=$(dark_grey at)
    local in=$(dark_grey in)
    export PS1="\n${user} ${at} ${host} ${in} ${workdir} ${gitbranch}"$'\n\$ '
}

# Now set it. If any of these colors are later overridden, then just rerun `set_prompt`
set_prompt

and uses these utility functions and variables:

# Color escape codes @see http://misc.flogisoft.com/bash/tip_colors_and_formatting
# Use \033 instead of \e. Workes better across platforms
# \e works in PS1 prompts, but not other places
c_X_reset_all='\033[0m' #stop code for color escape
c_X_bold='\033[21m'
c_X_reset_bold='\033[21m'
c_green='\033[01;32m'
c_blue='\033[01;34m'
c_pink='\033[01;35m'
c_dark_grey='\033[90m'

c_dark_yellow='\033[38;5;178m'
c_dark_red='\033[38;5;196m'

green(){
    echo -n  -e  ${c_green}$@${c_X_reset_all}
}

blue(){
    echo -n  -e  ${c_blue}$@${c_X_reset_all}
}

pink(){
    echo -n  -e  ${c_pink}$@${c_X_reset_all}
}

dark_grey(){
    echo -n  -e  ${c_dark_grey}$@${c_X_reset_all}
}

dark_yellow(){
    echo -n  -e  ${c_dark_yellow}$@${c_X_reset_all}
}

dark_red(){
    echo -n  -e  ${c_dark_red}$@${c_X_reset_all}
}

Prompt (pre-changes)

This is the prompt before implementing the changes from the comments:

$ perl -e 'print quotemeta($ENV{PS1})'
\\n\[01\;32m\\u\[0m\ \[90mat\[0m\ \[38\;5\;178m\\h\[0m\ \[90min\[0m\ \[01\;35m\\w\[0m\ \[38\;5\;196m\$\(__git_ps1\ \\\(\%s\\\)\ \)\[0m\
\\\$\

You can see all the \033 bits being gone and replaced with \. That is because it is the octal representation of the ESC character (27 in decimal, 1B in hex) and is now shown as \ in the output (\033[ becomes \]).

Prompt (after introducing escape sequences)

This seems to have fixed the issue

The comments suggested introducing escape sequences around non-printable characters. That seems to have changed things a bit, as the ESC characters are no longer being replaced:

$ perl -e 'print quotemeta($ENV{PS1})'
\\n\\\[\\033\[01\;32m\\\]\\u\ \\\[\\033\[90m\\\]at\ \\\[\\033\[38\;5\;178m\\\]\\h\ \\\[\\033\[90m\\\]in\ \\\[\\033\[01\;35m\\\]\\w\ \\\[\\033\[38\;5\;196m\\\]\(master\)\\\[\\033\[00m\\\]\
\\\$\
8
  • 2
    What happens if you run PS1='$ ' and then try the command again? Is the terminal still garbled? If so, you probably have a syntax error in your PS1 variable.
    – terdon
    Jan 16 at 12:12
  • 1
    See Terminal prompt not wrapping correctly
    – terdon
    Jan 16 at 15:32
  • @terdon I have an issue with determinism when testing this out. The issue can appear with a fresh Terminal and be present in a new fresh tab and then another tab opening the same directory could not show it. So weird. BUT to answer your question: this removed the issue when it appeared. So maybe something to do with escape characters? But again: hard to tell due to the lack of determinism thing.
    – oligofren
    Jan 17 at 13:39
  • Ah, at least we're getting somewhere. I am pretty sure the problem is as described in the answer to the question I linked you to earlier. You need \[ and \] around all non-printing characters such as color codes. It's kind of hard to get exactly what your PS1 is from your code (this approach makes for clean, readable code, but it's tricky to see what the final PS1 will be), but try printf '%s\n' "$PS1" and look for non-printing characters (color codes, most likely) that are not in \[ \].
    – terdon
    Jan 17 at 14:08
  • I refactored the prompt setting to add the escape characters earlier today, so I guess I will know in a few days whether or not the issue is gone :) github.com/fatso83/dotfiles/commit/…
    – oligofren
    Jan 17 at 16:11

0

You must log in to answer this question.

Browse other questions tagged .