From 4092d2d25ebf49d9d92d1c3378b06d79e166c43d Mon Sep 17 00:00:00 2001 From: Will Madison Date: Tue, 12 Oct 2021 10:54:15 -0400 Subject: [PATCH 1/3] adds the ability to set a custom writer (#5) --- cursor.go | 24 ++++++++++++------ cursor_test.go | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 8 deletions(-) diff --git a/cursor.go b/cursor.go index 5f07f5f..1de91bc 100644 --- a/cursor.go +++ b/cursor.go @@ -4,17 +4,25 @@ package cursor import ( "fmt" + "io" + "os" ) +var target io.Writer = os.Stdout + +func SetTarget(w io.Writer) { + target = w +} + // Up moves the cursor n lines up relative to the current position. func Up(n int) { - fmt.Printf("\x1b[%dA", n) + fmt.Fprintf(target, "\x1b[%dA", n) height += n } // Down moves the cursor n lines down relative to the current position. func Down(n int) { - fmt.Printf("\x1b[%dB", n) + fmt.Fprintf(target, "\x1b[%dB", n) if height-n <= 0 { height = 0 } else { @@ -24,36 +32,36 @@ func Down(n int) { // Right moves the cursor n characters to the right relative to the current position. func Right(n int) { - fmt.Printf("\x1b[%dC", n) + fmt.Fprintf(target, "\x1b[%dC", n) } // Left moves the cursor n characters to the left relative to the current position. func Left(n int) { - fmt.Printf("\x1b[%dD", n) + fmt.Fprintf(target, "\x1b[%dD", n) } // HorizontalAbsolute moves the cursor to n horizontally. // The position n is absolute to the start of the line. func HorizontalAbsolute(n int) { n += 1 // Moves the line to the character after n - fmt.Printf("\x1b[%dG", n) + fmt.Fprintf(target, "\x1b[%dG", n) } // Show the cursor if it was hidden previously. // Don't forget to show the cursor at least at the end of your application. // Otherwise the user might have a terminal with a permanently hidden cursor, until they reopen the terminal. func Show() { - fmt.Print("\x1b[?25h") + fmt.Fprint(target, "\x1b[?25h") } // Hide the cursor. // Don't forget to show the cursor at least at the end of your application with Show. // Otherwise the user might have a terminal with a permanently hidden cursor, until they reopen the terminal. func Hide() { - fmt.Print("\x1b[?25l") + fmt.Fprintf(target, "\x1b[?25l") } // ClearLine clears the current line and moves the cursor to it's start position. func ClearLine() { - fmt.Print("\x1b[2K") + fmt.Fprintf(target, "\x1b[2K") } diff --git a/cursor_test.go b/cursor_test.go index b74902c..3be0e0a 100644 --- a/cursor_test.go +++ b/cursor_test.go @@ -1,6 +1,7 @@ package cursor import ( + "bytes" "fmt" "testing" ) @@ -25,3 +26,71 @@ func TestHeightCannotBeNegative(t *testing.T) { t.Errorf("height is negative: %d", height) } } + +func TestCustomIOWriter(t *testing.T) { + var w bytes.Buffer + SetTarget(&w) + + Up(2) + expected := "\x1b[2A" + actual := w.String() + if expected != actual { + t.Errorf("wanted: %v, got %v", expected, actual) + } + + w.Reset() + Down(2) + expected = "\x1b[2B" + actual = w.String() + if expected != actual { + t.Errorf("wanted: %v, got %v", expected, actual) + } + + w.Reset() + Right(2) + expected = "\x1b[2C" + actual = w.String() + if expected != actual { + t.Errorf("wanted: %v, got %v", expected, actual) + } + + w.Reset() + Left(2) + expected = "\x1b[2D" + actual = w.String() + if expected != actual { + t.Errorf("wanted: %v, got %v", expected, actual) + } + + w.Reset() + Hide() + expected = "\x1b[?25l" + actual = w.String() + if expected != actual { + t.Errorf("wanted: %v, got %v", expected, actual) + } + + w.Reset() + Show() + expected = "\x1b[?25h" + actual = w.String() + if expected != actual { + t.Errorf("wanted: %v, got %v", expected, actual) + } + + w.Reset() + ClearLine() + expected = "\x1b[2K" + actual = w.String() + if expected != actual { + t.Errorf("wanted: %v, got %v", expected, actual) + } + + w.Reset() + HorizontalAbsolute(3) + expected = "\x1b[4G" + actual = w.String() + if expected != actual { + t.Errorf("wanted: %v, got %v", expected, actual) + } +} From dd9fa2016c9709966203199aa6003512a32d5d3c Mon Sep 17 00:00:00 2001 From: Will Madison Date: Wed, 13 Oct 2021 13:43:14 -0400 Subject: [PATCH 2/3] adds godoc comments --- cursor.go | 2 ++ cursor_windows.go | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/cursor.go b/cursor.go index 1de91bc..873b8ac 100644 --- a/cursor.go +++ b/cursor.go @@ -10,6 +10,8 @@ import ( var target io.Writer = os.Stdout +// SetTarget allows for any arbitrary io.Writer to be used +// for cursor movement (will not work on Windows). func SetTarget(w io.Writer) { target = w } diff --git a/cursor_windows.go b/cursor_windows.go index 35a5f77..79a9cf5 100644 --- a/cursor_windows.go +++ b/cursor_windows.go @@ -1,11 +1,17 @@ package cursor import ( + "io" "os" "syscall" "unsafe" ) +// SetTarget allows for any arbitrary io.Writer to be used +// for cursor movement (will not work on Windows). +func SetTarget(w io.Writer) { +} + // Up moves the cursor n lines up relative to the current position. func Up(n int) { move(0, -n) From 3163b8eb30285eace20cfb297446b2d61758ffe6 Mon Sep 17 00:00:00 2001 From: Will Madison Date: Wed, 13 Oct 2021 15:12:35 -0400 Subject: [PATCH 3/3] skipping custom IOWriter tests on Windows --- cursor_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cursor_test.go b/cursor_test.go index 3be0e0a..43c9f20 100644 --- a/cursor_test.go +++ b/cursor_test.go @@ -3,6 +3,7 @@ package cursor import ( "bytes" "fmt" + "runtime" "testing" ) @@ -28,6 +29,10 @@ func TestHeightCannotBeNegative(t *testing.T) { } func TestCustomIOWriter(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("skipping these tests on windows") + } + var w bytes.Buffer SetTarget(&w)