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:
commit
be529349bb
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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, '!'},
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user