1
0
mirror of https://github.com/taigrr/gopher-os synced 2025-01-18 04:43:13 -08:00

Merge pull request #10 from achilleasa/improve-tty-and-fix-fmt-bugs

Improve tty and fix fmt bugs
This commit is contained in:
Achilleas Anagnostopoulos 2017-05-12 08:16:33 +01:00 committed by GitHub
commit be529349bb
4 changed files with 75 additions and 28 deletions

View File

@ -5,6 +5,7 @@ import "io"
// Tty is implemented by objects that can register themselves as ttys.
type Tty interface {
io.Writer
io.ByteWriter
// Position returns the current cursor position (x, y).
Position() (uint16, uint16)

View File

@ -5,6 +5,7 @@ import "github.com/achilleasa/gopher-os/kernel/driver/video/console"
const (
defaultFg = console.LightGrey
defaultBg = console.Black
tabWidth = 4
)
// Vt implements a simple terminal that can process LF and CR characters. The
@ -59,24 +60,45 @@ func (t *Vt) SetPosition(x, y uint16) {
// Write implements io.Writer.
func (t *Vt) Write(data []byte) (int, error) {
attr := t.curAttr
for _, b := range data {
t.WriteByte(b)
}
return len(data), nil
}
// Write implements io.ByteWriter.
func (t *Vt) WriteByte(b byte) error {
switch b {
case '\r':
t.cr()
case '\n':
t.cr()
t.lf()
default:
t.cons.Write(b, attr, t.curX, t.curY)
case '\b':
if t.curX > 0 {
t.cons.Write(' ', t.curAttr, t.curX, t.curY)
t.curX--
}
case '\t':
for i := 0; i < tabWidth; i++ {
t.cons.Write(' ', t.curAttr, t.curX, t.curY)
t.curX++
if t.curX == t.width {
t.cr()
t.lf()
}
}
default:
t.cons.Write(b, t.curAttr, t.curX, t.curY)
t.curX++
if t.curX == t.width {
t.cr()
t.lf()
}
}
return len(data), nil
return nil
}
// cls clears the terminal.

View File

@ -44,7 +44,12 @@ func TestWrite(t *testing.T) {
vt.Clear()
vt.SetPosition(0, 1)
vt.Write([]byte("12\n3\n4\r56"))
vt.Write([]byte("12\n\t3\n4\r567\b8"))
// Tab spanning rows
vt.SetPosition(78, 4)
vt.WriteByte('\t')
vt.WriteByte('9')
// Trigger scroll
vt.SetPosition(79, 24)
@ -56,9 +61,22 @@ func TestWrite(t *testing.T) {
}{
{0, 0, '1'},
{1, 0, '2'},
{0, 1, '3'},
// tabs
{0, 1, ' '},
{1, 1, ' '},
{2, 1, ' '},
{3, 1, ' '},
{4, 1, '3'},
// tab spanning 2 rows
{78, 3, ' '},
{79, 3, ' '},
{0, 4, ' '},
{1, 4, ' '},
{2, 4, '9'},
//
{0, 2, '5'},
{1, 2, '6'},
{2, 2, '8'}, // overwritten by BS
{79, 23, '!'},
}

View File

@ -7,7 +7,7 @@ var (
errWrongArgType = []byte("%!(WRONGTYPE)")
errNoVerb = []byte("%!(NOVERB)")
errExtraArg = []byte("%!(EXTRA)")
padding = []byte{' '}
padding = byte(' ')
trueValue = []byte("true")
falseValue = []byte("false")
)
@ -62,7 +62,9 @@ func Printf(format string, args ...interface{}) {
}
if blockStart < blockEnd {
hal.ActiveTerminal.Write([]byte(format[blockStart:blockEnd]))
for i := blockStart; i < blockEnd; i++ {
hal.ActiveTerminal.WriteByte(format[i])
}
}
// Scan til we hit the format character
@ -109,7 +111,9 @@ func Printf(format string, args ...interface{}) {
}
if blockStart != blockEnd {
hal.ActiveTerminal.Write([]byte(format[blockStart:blockEnd]))
for i := blockStart; i < blockEnd; i++ {
hal.ActiveTerminal.WriteByte(format[i])
}
}
// Check for unused args
@ -139,23 +143,25 @@ func fmtBool(v interface{}) {
// padding specified by padLen. This function uses hal.ActiveTerminal for its
// output.
func fmtString(v interface{}, padLen int) {
var sval []byte
switch castedVal := v.(type) {
case string:
sval = []byte(castedVal)
fmtRepeat(padding, padLen-len(castedVal))
for i := 0; i < len(castedVal); i++ {
hal.ActiveTerminal.WriteByte(castedVal[i])
}
case []byte:
sval = castedVal
fmtRepeat(padding, padLen-len(castedVal))
hal.ActiveTerminal.Write(castedVal)
default:
hal.ActiveTerminal.Write(errWrongArgType)
return
}
}
for pad := padLen - len(sval); pad > 0; pad-- {
hal.ActiveTerminal.Write(padding)
// fmtRepeat writes count bytes with value ch to the hal.ActiveTerminal.
func fmtRepeat(ch byte, count int) {
for i := 0; i < count; i++ {
hal.ActiveTerminal.WriteByte(ch)
}
hal.ActiveTerminal.Write(sval)
}
// fmtInt prints out a formatted version of v in the requested base, applying the