Skip to content

fix: preserve ANSI colors when piping to pager on Windows#1705

Open
VoidChecksum wants to merge 2 commits intohttpie:masterfrom
VoidChecksum:fix/windows-pager-ansi-passthrough
Open

fix: preserve ANSI colors when piping to pager on Windows#1705
VoidChecksum wants to merge 2 commits intohttpie:masterfrom
VoidChecksum:fix/windows-pager-ansi-passthrough

Conversation

@VoidChecksum
Copy link

Summary

Fixes #799--pretty=all output loses colors when piped to a pager (less -r, more, etc.) on Windows.

Root cause

On Windows, HTTPie wraps stdout through colorama to translate ANSI escape codes into Win32 console API calls. When stdout is piped (not a TTY), colorama detects the non-TTY stream and strips all ANSI escape codes instead of passing them through.

The condition on writer.py line 49 routes through write_stream_with_colors_win() whenever colors are requested on Windows — even when stdout is piped to a pager. That function writes decoded text through colorama's wrapper, which strips the ANSI codes.

The regular write_stream() path writes raw bytes directly to outfile.buffer, bypassing colorama's text-layer stripping entirely — so ANSI codes pass through to the pipe intact.

Fix

Added env.stdout_isatty to the condition:

# Before
if env.is_windows and 'colors' in processing_options.get_prettify(env):

# After
if env.is_windows and env.stdout_isatty and 'colors' in processing_options.get_prettify(env):

write_stream_with_colors_win() is now only used when stdout is an actual terminal. When piped, the standard write_stream() path handles output — writing raw bytes with ANSI codes intact, letting pagers like less -r render colors correctly.

Platform impact

Scenario Before After
Windows, terminal colorama translates ANSI → Win32 No change
Windows, piped to pager colorama strips ANSI codes ANSI codes pass through to pager
Linux/macOS is_windows is False, path never entered No change

Testing

Verified on Windows 10 with less via Git for Windows:

http --pretty=all https://httpbin.org/get | less -r
  • Before: monochrome output, all colors stripped
  • After: fully colored output rendered by less -r

Copilot AI review requested due to automatic review settings March 8, 2026 22:38
When stdout is piped (e.g. `http --pretty=all ... | less -r`),
colorama detects a non-TTY stream and strips all ANSI escape codes.
This makes `--pretty=all` output appear uncolored in pagers on Windows.

Only route through `write_stream_with_colors_win()` when stdout is an
actual terminal. When piped, fall through to `write_stream()` which
writes raw bytes (including ANSI codes) directly to `outfile.buffer`,
bypassing colorama's text-layer stripping.

Fixes httpie#799
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a Windows-specific color handling issue where --pretty=all output loses ANSI colors when stdout is piped to a pager by avoiding the colorama text wrapper when stdout is not a TTY.

Changes:

  • Gate the Windows write_stream_with_colors_win() path behind env.stdout_isatty so it’s only used for real terminals.
  • Allow piped/redirected Windows output to go through write_stream() (raw bytes), preserving ANSI escape sequences for pagers like less -r.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +49 to 52
if env.is_windows and env.stdout_isatty and 'colors' in processing_options.get_prettify(env):
write_stream_with_colors_win(**write_stream_kwargs)
else:
write_stream(**write_stream_kwargs)
Copy link

Copilot AI Mar 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a regression test for this Windows-specific branch selection: when env.is_windows is true, colors are requested (e.g. --pretty=all), and env.stdout_isatty is false (piped/redirected), we should use the raw write_stream() path (and not write_stream_with_colors_win()) so ANSI escape codes are preserved. Without a test, this behavior is easy to accidentally regress and reintroduce the color-stripping issue reported in #799.

Copilot uses AI. Check for mistakes.
Verify that when stdout is piped on Windows (stdout_isatty=False),
write_stream() is used instead of write_stream_with_colors_win(),
ensuring ANSI escape codes pass through to pagers like `less -r`.

Regression test for httpie#799.
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

Successfully merging this pull request may close these issues.

--pretty=all piped to a pager does not work on Windows

2 participants