mirror of
https://github.com/restic/restic.git
synced 2025-12-12 03:22:07 +00:00
termstatus: move cursor handling to terminal package
This commit is contained in:
@@ -33,8 +33,8 @@ import (
|
|||||||
"github.com/restic/restic/internal/options"
|
"github.com/restic/restic/internal/options"
|
||||||
"github.com/restic/restic/internal/repository"
|
"github.com/restic/restic/internal/repository"
|
||||||
"github.com/restic/restic/internal/restic"
|
"github.com/restic/restic/internal/restic"
|
||||||
|
"github.com/restic/restic/internal/terminal"
|
||||||
"github.com/restic/restic/internal/textfile"
|
"github.com/restic/restic/internal/textfile"
|
||||||
"github.com/restic/restic/internal/ui/termstatus"
|
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
|
|
||||||
"github.com/restic/restic/internal/errors"
|
"github.com/restic/restic/internal/errors"
|
||||||
@@ -210,7 +210,7 @@ func stdoutIsTerminal() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func stdoutCanUpdateStatus() bool {
|
func stdoutCanUpdateStatus() bool {
|
||||||
return termstatus.CanUpdateStatus(os.Stdout.Fd())
|
return terminal.CanUpdateStatus(os.Stdout.Fd())
|
||||||
}
|
}
|
||||||
|
|
||||||
func stdoutTerminalWidth() int {
|
func stdoutTerminalWidth() int {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package termstatus
|
package terminal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@@ -8,16 +8,16 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
posixControlMoveCursorHome = "\r"
|
PosixControlMoveCursorHome = "\r"
|
||||||
posixControlMoveCursorUp = "\x1b[1A"
|
PosixControlMoveCursorUp = "\x1b[1A"
|
||||||
posixControlClearLine = "\x1b[2K"
|
PosixControlClearLine = "\x1b[2K"
|
||||||
)
|
)
|
||||||
|
|
||||||
// posixClearCurrentLine removes all characters from the current line and resets the
|
// posixClearCurrentLine removes all characters from the current line and resets the
|
||||||
// cursor position to the first column.
|
// cursor position to the first column.
|
||||||
func posixClearCurrentLine(wr io.Writer, _ uintptr) {
|
func PosixClearCurrentLine(wr io.Writer, _ uintptr) {
|
||||||
// clear current line
|
// clear current line
|
||||||
_, err := wr.Write([]byte(posixControlMoveCursorHome + posixControlClearLine))
|
_, err := wr.Write([]byte(PosixControlMoveCursorHome + PosixControlClearLine))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "write failed: %v\n", err)
|
fmt.Fprintf(os.Stderr, "write failed: %v\n", err)
|
||||||
return
|
return
|
||||||
@@ -25,9 +25,9 @@ func posixClearCurrentLine(wr io.Writer, _ uintptr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// posixMoveCursorUp moves the cursor to the line n lines above the current one.
|
// posixMoveCursorUp moves the cursor to the line n lines above the current one.
|
||||||
func posixMoveCursorUp(wr io.Writer, _ uintptr, n int) {
|
func PosixMoveCursorUp(wr io.Writer, _ uintptr, n int) {
|
||||||
data := []byte(posixControlMoveCursorHome)
|
data := []byte(PosixControlMoveCursorHome)
|
||||||
data = append(data, bytes.Repeat([]byte(posixControlMoveCursorUp), n)...)
|
data = append(data, bytes.Repeat([]byte(PosixControlMoveCursorUp), n)...)
|
||||||
_, err := wr.Write(data)
|
_, err := wr.Write(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "write failed: %v\n", err)
|
fmt.Fprintf(os.Stderr, "write failed: %v\n", err)
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
//go:build !windows
|
//go:build !windows
|
||||||
// +build !windows
|
// +build !windows
|
||||||
|
|
||||||
package termstatus
|
package terminal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
@@ -12,13 +12,13 @@ import (
|
|||||||
|
|
||||||
// clearCurrentLine removes all characters from the current line and resets the
|
// clearCurrentLine removes all characters from the current line and resets the
|
||||||
// cursor position to the first column.
|
// cursor position to the first column.
|
||||||
func clearCurrentLine(_ uintptr) func(io.Writer, uintptr) {
|
func ClearCurrentLine(_ uintptr) func(io.Writer, uintptr) {
|
||||||
return posixClearCurrentLine
|
return PosixClearCurrentLine
|
||||||
}
|
}
|
||||||
|
|
||||||
// moveCursorUp moves the cursor to the line n lines above the current one.
|
// moveCursorUp moves the cursor to the line n lines above the current one.
|
||||||
func moveCursorUp(_ uintptr) func(io.Writer, uintptr, int) {
|
func MoveCursorUp(_ uintptr) func(io.Writer, uintptr, int) {
|
||||||
return posixMoveCursorUp
|
return PosixMoveCursorUp
|
||||||
}
|
}
|
||||||
|
|
||||||
// CanUpdateStatus returns true if status lines can be printed, the process
|
// CanUpdateStatus returns true if status lines can be printed, the process
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
//go:build windows
|
//go:build windows
|
||||||
// +build windows
|
// +build windows
|
||||||
|
|
||||||
package termstatus
|
package terminal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
@@ -15,25 +15,25 @@ import (
|
|||||||
|
|
||||||
// clearCurrentLine removes all characters from the current line and resets the
|
// clearCurrentLine removes all characters from the current line and resets the
|
||||||
// cursor position to the first column.
|
// cursor position to the first column.
|
||||||
func clearCurrentLine(fd uintptr) func(io.Writer, uintptr) {
|
func ClearCurrentLine(fd uintptr) func(io.Writer, uintptr) {
|
||||||
// easy case, the terminal is cmd or psh, without redirection
|
// easy case, the terminal is cmd or psh, without redirection
|
||||||
if isWindowsTerminal(fd) {
|
if isWindowsTerminal(fd) {
|
||||||
return windowsClearCurrentLine
|
return windowsClearCurrentLine
|
||||||
}
|
}
|
||||||
|
|
||||||
// assume we're running in mintty/cygwin
|
// assume we're running in mintty/cygwin
|
||||||
return posixClearCurrentLine
|
return PosixClearCurrentLine
|
||||||
}
|
}
|
||||||
|
|
||||||
// moveCursorUp moves the cursor to the line n lines above the current one.
|
// moveCursorUp moves the cursor to the line n lines above the current one.
|
||||||
func moveCursorUp(fd uintptr) func(io.Writer, uintptr, int) {
|
func MoveCursorUp(fd uintptr) func(io.Writer, uintptr, int) {
|
||||||
// easy case, the terminal is cmd or psh, without redirection
|
// easy case, the terminal is cmd or psh, without redirection
|
||||||
if isWindowsTerminal(fd) {
|
if isWindowsTerminal(fd) {
|
||||||
return windowsMoveCursorUp
|
return windowsMoveCursorUp
|
||||||
}
|
}
|
||||||
|
|
||||||
// assume we're running in mintty/cygwin
|
// assume we're running in mintty/cygwin
|
||||||
return posixMoveCursorUp
|
return PosixMoveCursorUp
|
||||||
}
|
}
|
||||||
|
|
||||||
var kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
var kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package termstatus
|
package terminal
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"syscall"
|
"syscall"
|
||||||
@@ -69,12 +69,12 @@ func New(wr io.Writer, errWriter io.Writer, disableStatus bool) *Terminal {
|
|||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
if d, ok := wr.(fder); ok && CanUpdateStatus(d.Fd()) {
|
if d, ok := wr.(fder); ok && terminal.CanUpdateStatus(d.Fd()) {
|
||||||
// only use the fancy status code when we're running on a real terminal.
|
// only use the fancy status code when we're running on a real terminal.
|
||||||
t.canUpdateStatus = true
|
t.canUpdateStatus = true
|
||||||
t.fd = d.Fd()
|
t.fd = d.Fd()
|
||||||
t.clearCurrentLine = clearCurrentLine(t.fd)
|
t.clearCurrentLine = terminal.ClearCurrentLine(t.fd)
|
||||||
t.moveCursorUp = moveCursorUp(t.fd)
|
t.moveCursorUp = terminal.MoveCursorUp(t.fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
return t
|
return t
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/restic/restic/internal/terminal"
|
||||||
rtest "github.com/restic/restic/internal/test"
|
rtest "github.com/restic/restic/internal/test"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -17,16 +18,16 @@ func TestSetStatus(t *testing.T) {
|
|||||||
|
|
||||||
term.canUpdateStatus = true
|
term.canUpdateStatus = true
|
||||||
term.fd = ^uintptr(0)
|
term.fd = ^uintptr(0)
|
||||||
term.clearCurrentLine = posixClearCurrentLine
|
term.clearCurrentLine = terminal.PosixClearCurrentLine
|
||||||
term.moveCursorUp = posixMoveCursorUp
|
term.moveCursorUp = terminal.PosixMoveCursorUp
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
go term.Run(ctx)
|
go term.Run(ctx)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
cl = posixControlClearLine
|
cl = terminal.PosixControlClearLine
|
||||||
home = posixControlMoveCursorHome
|
home = terminal.PosixControlMoveCursorHome
|
||||||
up = posixControlMoveCursorUp
|
up = terminal.PosixControlMoveCursorUp
|
||||||
)
|
)
|
||||||
|
|
||||||
term.SetStatus([]string{"first"})
|
term.SetStatus([]string{"first"})
|
||||||
|
|||||||
Reference in New Issue
Block a user