Skip to content

fix: include escape codes in byte counts from Fprint, Fprintf#282

Merged
fatih merged 1 commit intofatih:mainfrom
qualidafial:fprint-bytes-written
Mar 10, 2026
Merged

fix: include escape codes in byte counts from Fprint, Fprintf#282
fatih merged 1 commit intofatih:mainfrom
qualidafial:fprint-bytes-written

Conversation

@qualidafial
Copy link
Copy Markdown
Contributor

Fix the n byte count returned from Color.Fprint and Color.Fprintf to include the bytes in ANSI escape sequences.

Both methods delegate to SetWriter and UnsetWriter methods to start and stop the excape sequence. Since both these methods are public and do not return the byte counts needed, I extracted private versions of these methods setWriter and unsetWriter, and redirected the Fprint and Fprintf to get accurate byte counts without breaking API compatibility.

Finally, unsetWriter() is no longer deferred. If we encounter an error at any point, stop writing and return the error.

@qualidafial qualidafial force-pushed the fprint-bytes-written branch from 9264c7c to f8f0652 Compare March 5, 2026 01:06
Fix the `n` byte count returned from `Color.Fprint` and
`Color.Fprintf` to include the bytes in ANSI escape sequences.

Both methods delegate to `SetWriter` and `UnsetWriter` methods to
start and stop the excape sequence. Since both these methods are
public and do not return the byte counts needed, I extracted
private versions of these methods `setWriter` and `unsetWriter`,
and redirected the `Fprint` and `Fprintf` to get accurate byte
counts without breaking API compatibility.

Finally, `unsetWriter()` is no longer deferred. If we encounter
an error at any point, stop writing and return the error.
@qualidafial qualidafial force-pushed the fprint-bytes-written branch from f8f0652 to cbda2c3 Compare March 5, 2026 01:09
@qualidafial
Copy link
Copy Markdown
Contributor Author

Ping. Is there any interest in this PR? I came across this bug while trying to migrate some code to FPrint so we can use io.Writer in tests instead of stdout.

@fatih
Copy link
Copy Markdown
Owner

fatih commented Mar 9, 2026

@qualidafial thanks for the test and verification. This looks something we can merge. Did you encountered any issue before? If yes what was the use case you saw ?

@qualidafial
Copy link
Copy Markdown
Contributor Author

We use color to format test results. We were trying to implement our own result.Fprint(w io.Writer) (n int, err error) methods, but were finding in tests that the returned byte count n didn't match the number of bytes actually written tow. The culprit turned out to be Color.Fprint(io.Writer) and Color.Fprintf(io.Writer) neglecting ANSI escape codes in the byte count totals.

As a workaround, I wrapped the passed-in writer on our side in a counting writer implementation, rather than relying on the byte counts from color:

type countingWriter struct {
	writer io.Writer
	N      int
}

func (w *countingWriter) Write(p []byte) (int, error) {
	n, err := w.writer.Write(p)
	w.N += n
	return n, err
}

@fatih fatih merged commit 5dd4072 into fatih:main Mar 10, 2026
1 check passed
@fatih
Copy link
Copy Markdown
Owner

fatih commented Mar 10, 2026

Thank you for the fix @qualidafial.

@qualidafial qualidafial deleted the fprint-bytes-written branch March 10, 2026 15:03
@qualidafial
Copy link
Copy Markdown
Contributor Author

My pleasure! Thanks @fatih for sharing and maintaining this library!

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.

2 participants