Skip to content
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

Problem with ANSI escape color codes on Kitty (Fedora 36 on Sway) and Centos 8 Stream. #2568

Open
od-cea opened this issue May 12, 2023 · 6 comments

Comments

@od-cea
Copy link

od-cea commented May 12, 2023

          Similar problem for me on Kitty (Fedora 36 on Sway).
1mNAME0m
       ls - list directory contents

1mSYNOPSIS0m
       1mls 22m[4mOPTION24m]... [4mFILE24m]...

1mDESCRIPTION0m
       List  information about the FILEs (the current directory by default).  Sort entries alphabetically if none of 1m-cftuvSUX 22mnor 1m--sort 22mis
       specified.

Originally posted by @SaElAh in #2479 (comment)

@od-cea
Copy link
Author

od-cea commented May 12, 2023

For the record, I had this exact problem and I've been able to mitigate it with colorzed-logs package and it's command ansi2txt: export MANPAGER="sh -c 'ansi2txt | col -bx | bat -l man -p'".

It would be great if bat could have an option to pre-filter out all color ANSI codes.

@od-cea od-cea changed the title Similar problem for me on Kitty (Fedora 36 on Sway). problem with ANSI escape color code on Kitty (Fedora 36 on Sway) and Centos 8 Stream. May 12, 2023
@od-cea od-cea changed the title problem with ANSI escape color code on Kitty (Fedora 36 on Sway) and Centos 8 Stream. Problem with ANSI escape color codes on Kitty (Fedora 36 on Sway) and Centos 8 Stream. May 12, 2023
@eth-p
Copy link
Collaborator

eth-p commented May 23, 2023

It would be great if bat could have an option to pre-filter out all color ANSI codes.

I could actually make a PR for this once #2544 is merged. We would have the machinery needed to find (and thus discard) all the types of escape sequences except C0.

@aus-hawk
Copy link

aus-hawk commented Jul 15, 2023

Running with MANROFFOPT="-c" as suggested by the README solved this issue for me.

With MANPAGER="sh -c 'col -bx | bat -l man -p --theme=Nord'"

image

With the previous MANPAGER and MANROFFOPT="-c"

image

I think this is a man problem, not a bat problem, unless the colors are supposed to be different than they are here and I don't remember.

mliszcz added a commit to mliszcz/dotfiles that referenced this issue Oct 27, 2023
Observed on Arch after man/roff update. Set MANROFFOPT as described:
* sharkdp/bat#2568
* sharkdp/bat#2593 (comment)
juanibiapina added a commit to juanibiapina/dotfiles that referenced this issue Dec 7, 2023
@eth-p
Copy link
Collaborator

eth-p commented Feb 12, 2024

I investigated this issue a bit to see if it's something that we can fix on our end, or if it's a problem with man. I set MANPAGER to sh -c 'col -bx | bat -A -p' to see if man was emitting well-formed escape sequences with the MANPAGER recommended by the README:

image

Without ␛[ character before the 4m, those sequences are invalid. Digging further into it, removing col -bx from the pipe fixed the broken sequences:

image

col has two options called -f/--fine (permit half-forward line feeds) and -p/--pass (force unknown control sequences to be passed through unchanged), but neither of those prevented it from mangling ANSI escape sequences:

image

The problem definitely is with col.

Proposed Solution (A)

We could highlight the need for MANROFFOPT in the README.

With this, we should still encourage col to be used, as having MANROFFOPT='-c' inserts backspace characters into the output:

image

Proposed Solution (B)

Alternatively, we could add sed within the pipe to strip away ANSI SGR sequences before they're fed into col.

export MANPAGER="sh -c 'sed -u \"s/`printf \\\\x1B`\[[0-9;]*m//g\" - | col -bx | bat -p -lman'"
#                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The expression itself looks messy when escaped, but what it boils down to is a BSD sed-compatible and POSIX sh-compatible version of sed -E 's/\x1B\[[0-9;]*m//g'.

@eth-p
Copy link
Collaborator

eth-p commented Feb 12, 2024

Further developments on my investigation into this:

  1. @sharkdp found out that the backspaces are inserted by MANROFFOPT='-c' in a process known as "overtyping." Basically, when printing to an automated typewriter, inserting an underline followed by a space would underline the next character. Similarly, inserting a character, followed by a backspace, followed by the same character would make it bold.

  2. less actually interprets this overtyping and prints the appropriate ANSI escape sequence.

     printf "This is b\bbo\bol\bld\bd.\nThis is not bold.\n" | less
  3. MacOS's implementation of man does not support MANROFFOPT, so if Apple ever switches to a version of roff that prints ANSI escape sequences instead of overyping, MANROFFOPT won't be a solution for it.

With that discovered, I propose...

Proposed Solution (C)

Don't use col at all, and replace it entirely with sed.

export MANPAGER="sh -c 'sed -u -e \"s/\\x1B\[[0-9;]*m//g; s/.\\x08//g\" | bat -p -lman'"

That sed command does the following:

  • s/\x1B\[[0-9;]*m//g -- Strips away ANSI SGR sequences (as used by modern versions of Linux man)
  • s/.\x08//g -- Strips away overtyping sequences (some character followed by a backspace)

eth-p added a commit to eth-p/bat-extras that referenced this issue Feb 12, 2024
This follows proposed solution (C) in
sharkdp/bat#2568
@od-cea
Copy link
Author

od-cea commented Mar 7, 2024

@eth-p Thanks ! Your C solution works nicely for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants