mirror of
				https://github.com/taigrr/gopher-os
				synced 2025-01-18 04:43:13 -08:00 
			
		
		
		
	Make TTYs implement io.ByteWriter and add support for TAB/BS chars
This commit is contained in:
		
							parent
							
								
									0154c132ea
								
							
						
					
					
						commit
						d7028cee00
					
				| @ -5,6 +5,7 @@ import "io" | |||||||
| // Tty is implemented by objects that can register themselves as ttys. | // Tty is implemented by objects that can register themselves as ttys. | ||||||
| type Tty interface { | type Tty interface { | ||||||
| 	io.Writer | 	io.Writer | ||||||
|  | 	io.ByteWriter | ||||||
| 
 | 
 | ||||||
| 	// Position returns the current cursor position (x, y). | 	// Position returns the current cursor position (x, y). | ||||||
| 	Position() (uint16, uint16) | 	Position() (uint16, uint16) | ||||||
|  | |||||||
| @ -5,6 +5,7 @@ import "github.com/achilleasa/gopher-os/kernel/driver/video/console" | |||||||
| const ( | const ( | ||||||
| 	defaultFg = console.LightGrey | 	defaultFg = console.LightGrey | ||||||
| 	defaultBg = console.Black | 	defaultBg = console.Black | ||||||
|  | 	tabWidth  = 4 | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // Vt implements a simple terminal that can process LF and CR characters. The | // Vt implements a simple terminal that can process LF and CR characters. The | ||||||
| @ -59,26 +60,47 @@ func (t *Vt) SetPosition(x, y uint16) { | |||||||
| 
 | 
 | ||||||
| // Write implements io.Writer. | // Write implements io.Writer. | ||||||
| func (t *Vt) Write(data []byte) (int, error) { | func (t *Vt) Write(data []byte) (int, error) { | ||||||
| 	attr := t.curAttr |  | ||||||
| 	for _, b := range data { | 	for _, b := range data { | ||||||
| 		switch b { | 		t.WriteByte(b) | ||||||
| 		case '\r': |  | ||||||
| 			t.cr() |  | ||||||
| 		case '\n': |  | ||||||
| 			t.cr() |  | ||||||
| 			t.lf() |  | ||||||
| 		default: |  | ||||||
| 			t.cons.Write(b, attr, t.curX, t.curY) |  | ||||||
| 			t.curX++ |  | ||||||
| 			if t.curX == t.width { |  | ||||||
| 				t.lf() |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return len(data), nil | 	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() | ||||||
|  | 	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 nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // cls clears the terminal. | // cls clears the terminal. | ||||||
| func (t *Vt) clear() { | func (t *Vt) clear() { | ||||||
| 	t.cons.Clear(0, 0, t.width, t.height) | 	t.cons.Clear(0, 0, t.width, t.height) | ||||||
|  | |||||||
| @ -44,7 +44,12 @@ func TestWrite(t *testing.T) { | |||||||
| 
 | 
 | ||||||
| 	vt.Clear() | 	vt.Clear() | ||||||
| 	vt.SetPosition(0, 1) | 	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 | 	// Trigger scroll | ||||||
| 	vt.SetPosition(79, 24) | 	vt.SetPosition(79, 24) | ||||||
| @ -56,9 +61,22 @@ func TestWrite(t *testing.T) { | |||||||
| 	}{ | 	}{ | ||||||
| 		{0, 0, '1'}, | 		{0, 0, '1'}, | ||||||
| 		{1, 0, '2'}, | 		{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'}, | 		{0, 2, '5'}, | ||||||
| 		{1, 2, '6'}, | 		{1, 2, '6'}, | ||||||
|  | 		{2, 2, '8'}, // overwritten by BS | ||||||
| 		{79, 23, '!'}, | 		{79, 23, '!'}, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user