Skip to content

Commit

Permalink
feat: implement cursor functions
Browse files Browse the repository at this point in the history
  • Loading branch information
MarvinJWendt committed Apr 11, 2021
1 parent babd772 commit 59c8382
Show file tree
Hide file tree
Showing 9 changed files with 263 additions and 24 deletions.
2 changes: 1 addition & 1 deletion .github/settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ repository:
# See https://developer.github.com/v3/repos/#edit for all available settings.

# A short description of the repository that will show up on GitHub
description: 🔹 Golang module
description: 🔹 Golang module to utilize ANSI functions, like moving the cursor

# A comma-separated list of topics to set on the repository
topics: atomicgo, go, golang, golang-library
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ gen
### macOS
# General
.DS_Store
experimenting
110 changes: 110 additions & 0 deletions cursor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package cursor

import (
"fmt"
"strings"
)

const (
ansiPrefix = "\x1b["

upTemplate = "%dA"
downTemplate = "%dB"
leftTemplate = "%dD"
rightTemplate = "%dC"

nextLineTemplate = "%dE"
previousLineTemplate = "%dF"

positionTemplate = "%d;%dH"
savePositionTemplate = "s"
restorePositionTemplate = "u"

openAlternativeScreenTemplate = "?1049h"
closeAlternativeScreenTemplate = "?1049l"

clearDisplayTemplate = "%dJ"
clearLineTemplate = "%dK"

showTemplate = "?25h"
hideTemplate = "?25l"
)

// Move cursor.

// Up moves the cursor n cells up. If the cursor is already at the edge of the screen, this has no effect.
func Up(n int) {
fmt.Printf(ansiPrefix+upTemplate, n)
}

// Down moves the cursor n cells down. If the cursor is already at the edge of the screen, this has no effect.
func Down(n int) {
fmt.Printf(ansiPrefix+downTemplate, n)
}

// Left moves the cursor n cells left. If the cursor is already at the edge of the screen, this has no effect.
func Left(n int) {
fmt.Printf(ansiPrefix+leftTemplate, n)
}

// Right moves the cursor n cells right. If the cursor is already at the edge of the screen, this has no effect.
func Right(n int) {
fmt.Printf(ansiPrefix+rightTemplate, n)
}

// Move moves the cursor to a specific row and column.
func Move(row int, column int) {
fmt.Printf(ansiPrefix+positionTemplate, row, column)
}

func NextLine(n int) {
fmt.Printf(ansiPrefix+nextLineTemplate, n)
}

func PrevLine(n int) {
fmt.Printf(ansiPrefix+previousLineTemplate, n)
}

func SavePosition() {
fmt.Print(ansiPrefix + savePositionTemplate)
}

func RestorePosition() {
fmt.Print(ansiPrefix + restorePositionTemplate)
}

// Alternative screen.

func OpenAlternativeScreen() {
fmt.Print(ansiPrefix + openAlternativeScreenTemplate)
}

func CloseAlternativeScreen() {
fmt.Print(ansiPrefix + closeAlternativeScreenTemplate)
}

// Erase

func ClearScreen() {
fmt.Printf(ansiPrefix+clearDisplayTemplate, 2)
Move(1, 1)
}

func ClearLine() {
fmt.Printf(ansiPrefix+clearLineTemplate, 2)
}

func ClearLines(n int) {
clear := fmt.Sprintf(ansiPrefix+clearLineTemplate, 2)
fmt.Print(clear + strings.Repeat(fmt.Sprintf(ansiPrefix+upTemplate, 1)+clear, n))
}

// Show and hide cursor

func Show() {
fmt.Printf(ansiPrefix + showTemplate)
}

func Hide() {
fmt.Printf(ansiPrefix + hideTemplate)
}
144 changes: 144 additions & 0 deletions cursor_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package cursor

import (
"io"
"testing"

"github.com/atomicgo/testutil"
)

func equal(t *testing.T, output string, input func(w io.Writer) error) {
t.Helper()
in, _ := testutil.CaptureStdout(input)
if in != output {
t.Errorf("Input: '%s' is not equal to '%s'", in, output)
}
}

func TestClearLine(t *testing.T) {
equal(t, "\x1b[2K", func(w io.Writer) error {
ClearLine()

return nil
})
}

func TestClearLines(t *testing.T) {
equal(t, "\x1b[2K\x1b[1A\x1b[2K\x1b[1A\x1b[2K\x1b[1A\x1b[2K", func(w io.Writer) error {
ClearLines(3)

return nil
})
}

func TestClearScreen(t *testing.T) {
equal(t, "\x1b[2J\x1b[1;1H", func(w io.Writer) error {
ClearScreen()

return nil
})
}

func TestCloseAlternativeScreen(t *testing.T) {
equal(t, "\x1b[?1049l", func(w io.Writer) error {
CloseAlternativeScreen()

return nil
})
}

func TestDown(t *testing.T) {
equal(t, "\x1b[6B", func(w io.Writer) error {
Down(6)

return nil
})
}

func TestHide(t *testing.T) {
equal(t, "\x1b[?25l", func(w io.Writer) error {
Hide()

return nil
})
}

func TestLeft(t *testing.T) {
equal(t, "\x1b[6D", func(w io.Writer) error {
Left(6)

return nil
})
}

func TestMove(t *testing.T) {
equal(t, "\x1b[6;7H", func(w io.Writer) error {
Move(6, 7)

return nil
})
}

func TestNextLine(t *testing.T) {
equal(t, "\x1b[6E", func(w io.Writer) error {
NextLine(6)

return nil
})
}

func TestOpenAlternativeScreen(t *testing.T) {
equal(t, "\x1b[?1049h", func(w io.Writer) error {
OpenAlternativeScreen()

return nil
})
}

func TestPrevLine(t *testing.T) {
equal(t, "\x1b[6F", func(w io.Writer) error {
PrevLine(6)

return nil
})
}

func TestRestorePosition(t *testing.T) {
equal(t, "\x1b[u", func(w io.Writer) error {
RestorePosition()

return nil
})
}

func TestRight(t *testing.T) {
equal(t, "\x1b[6C", func(w io.Writer) error {
Right(6)

return nil
})
}

func TestSavePosition(t *testing.T) {
equal(t, "\x1b[s", func(w io.Writer) error {
SavePosition()

return nil
})
}

func TestShow(t *testing.T) {
equal(t, "\x1b[?25h", func(w io.Writer) error {
Show()

return nil
})
}

func TestUp(t *testing.T) {
equal(t, "\x1b[6A", func(w io.Writer) error {
Up(6)

return nil
})
}
9 changes: 2 additions & 7 deletions doc.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
/*
Package template is used to generate new AtomicGo repositories.
Write the description of the module here. You can use **markdown**!
This description should clearly explain what the package does.
Example description: https://golang.org/src/encoding/gob/doc.go
Package cursor contains methods to move the cursor inside a terminal.
*/
package template
package cursor
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
module github.com/atomicgo/template
module github.com/atomicgo/cursor

go 1.15

require github.com/atomicgo/testutil v0.0.1 // indirect
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/atomicgo/testutil v0.0.1 h1:3Si1wzSCaGihKYc2w3brYbBDWZ2/4MayjzzzUTL7esA=
github.com/atomicgo/testutil v0.0.1/go.mod h1:/hQIxa6fUSFwnzJd096BeLtDdRBbssw1MZN6FhUCOLs=
6 changes: 0 additions & 6 deletions template.go

This file was deleted.

9 changes: 0 additions & 9 deletions template_test.go

This file was deleted.

0 comments on commit 59c8382

Please sign in to comment.