Skip to content

Commit

Permalink
Fix multi-parameter println spacing
Browse files Browse the repository at this point in the history
`fmt.Println` will add spaces between elements when there is multiple parameters sent.

When wrapping the colors parameters were combined using `fmt.Sprint(a...)` - which does not space out parameters.

Use `fmt.Sprintln` to combine parameters.

Fixes #218
  • Loading branch information
klauspost committed Apr 8, 2024
1 parent 04994a8 commit 00b1811
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 4 deletions.
13 changes: 9 additions & 4 deletions color.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ func (c *Color) Printf(format string, a ...interface{}) (n int, err error) {
// On Windows, users should wrap w with colorable.NewColorable() if w is of
// type *os.File.
func (c *Color) Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
return fmt.Fprintln(w, c.wrap(fmt.Sprint(a...)))
return fmt.Fprintln(w, c.wrap(sprintln(a...)))
}

// Println formats using the default formats for its operands and writes to
Expand All @@ -278,7 +278,7 @@ func (c *Color) Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
// encountered. This is the standard fmt.Print() method wrapped with the given
// color.
func (c *Color) Println(a ...interface{}) (n int, err error) {
return fmt.Fprintln(Output, c.wrap(fmt.Sprint(a...)))
return fmt.Fprintln(Output, c.wrap(sprintln(a...)))
}

// Sprint is just like Print, but returns a string instead of printing it.
Expand All @@ -288,7 +288,7 @@ func (c *Color) Sprint(a ...interface{}) string {

// Sprintln is just like Println, but returns a string instead of printing it.
func (c *Color) Sprintln(a ...interface{}) string {
return fmt.Sprintln(c.Sprint(a...))
return c.wrap(sprintln(a...)) + "\n"
}

// Sprintf is just like Printf, but returns a string instead of printing it.
Expand Down Expand Up @@ -370,7 +370,7 @@ func (c *Color) SprintfFunc() func(format string, a ...interface{}) string {
// string. Windows users should use this in conjunction with color.Output.
func (c *Color) SprintlnFunc() func(a ...interface{}) string {
return func(a ...interface{}) string {
return fmt.Sprintln(c.Sprint(a...))
return c.wrap(sprintln(a...)) + "\n"
}
}

Expand Down Expand Up @@ -648,3 +648,8 @@ func HiCyanString(format string, a ...interface{}) string { return colorString(f
func HiWhiteString(format string, a ...interface{}) string {
return colorString(format, FgHiWhite, a...)
}

// sprintln is a helper function to format a string with fmt.Sprintln and trim the trailing newline.
func sprintln(a ...interface{}) string {
return strings.TrimSuffix(fmt.Sprintln(a...), "\n")
}
31 changes: 31 additions & 0 deletions color_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -504,3 +504,34 @@ func TestIssue206_2(t *testing.T) {
t.Errorf("Expecting %v, got '%v'\n", expectedResult, result)
}
}

func TestIssue218(t *testing.T) {
// Adds a newline to the end of the last string to make sure it isn't trimmed.
params := []interface{}{"word1", "word2", "word3", "word4\n"}

c := New(FgCyan)
c.Println(params...)

var result = c.Sprintln(params...)
fmt.Println(params...)
fmt.Print(result)

const expectedResult = "\x1b[36mword1 word2 word3 word4\n\x1b[0m\n"

if !bytes.Equal([]byte(result), []byte(expectedResult)) {
t.Errorf("Sprintln: Expecting %v (%v), got '%v (%v)'\n", expectedResult, []byte(expectedResult), result, []byte(result))
}

fn := c.SprintlnFunc()
result = fn(params...)
if !bytes.Equal([]byte(result), []byte(expectedResult)) {
t.Errorf("SprintlnFunc: Expecting %v (%v), got '%v (%v)'\n", expectedResult, []byte(expectedResult), result, []byte(result))
}

var buf bytes.Buffer
c.Fprintln(&buf, params...)
result = buf.String()
if !bytes.Equal([]byte(result), []byte(expectedResult)) {
t.Errorf("Fprintln: Expecting %v (%v), got '%v (%v)'\n", expectedResult, []byte(expectedResult), result, []byte(result))
}
}

0 comments on commit 00b1811

Please sign in to comment.