Made input buffered to support peeking, added WErase

main
noah metz 2024-04-24 19:08:45 -06:00
parent 6b121ac061
commit 14b1c310e7
2 changed files with 49 additions and 20 deletions

@ -2,6 +2,7 @@ package ncurses
import ( import (
"os" "os"
"bufio"
"sync/atomic" "sync/atomic"
) )
@ -10,26 +11,51 @@ func bitmatch(b byte, pattern byte, length int) bool {
return (b ^ pattern) & mask == 0 return (b ^ pattern) & mask == 0
} }
func UTF8Listen(file *os.File, channel chan []byte, active *atomic.Bool) { func UTF8Listen(reader *bufio.Reader, channel chan []byte, active *atomic.Bool) {
b := [4]byte{}
for active.Load() { for active.Load() {
out := make([]byte, 4) out := make([]byte, 4)
file.Read(b[0:1])
if bitmatch(b[0], 0b00000000, 1) { reader.Read(out[0:1])
copy(out, b[0:1])
if out[0] == 0x1B { // Escape sequences
if reader.Buffered() != 0 {
reader.Read(out[1:2])
if out[1] == 0x5B { // CSI
out := []byte{0x1B, 0x5B}
next := [1]byte{}
for true { // TODO: safety
reader.Read(next[0:1])
if (next[0] >= 0x20) && (next[0] <= 0x3F) {
out = append(out, next[0])
} else if (next[0] >= 0x40) && (next[0] <= 0x7F) {
out = append(out, next[0])
break
} else {
break
}
}
channel<-out
}
} else {
channel <- out[0:1]
}
} else if bitmatch(out[0], 0b00000000, 1) {
channel <- out[0:1] channel <- out[0:1]
} else if bitmatch(b[0], 0b11000000, 3) { } else if bitmatch(out[0], 0b11000000, 3) {
file.Read(b[1:2]) if reader.Buffered() >= 1 {
copy(out, b[0:2]) reader.Read(out[1:2])
channel <- out[0:2] channel <- out[0:2]
} else if bitmatch(b[0], 0b11100000, 4) { }
file.Read(b[1:3]) } else if bitmatch(out[0], 0b11100000, 4) {
copy(out, b[0:3]) if reader.Buffered() >= 2 {
channel <- out[0:3] reader.Read(out[1:3])
} else if bitmatch(b[0], 0b11110000, 5) { channel <- out[0:3]
file.Read(b[1:4]) }
copy(out, b[0:4]) } else if bitmatch(out[0], 0b11110000, 5) {
channel <- out[0:4] if reader.Buffered() >= 3 {
reader.Read(out[1:4])
channel <- out[0:4]
}
} }
} }
} }
@ -37,10 +63,11 @@ func UTF8Listen(file *os.File, channel chan []byte, active *atomic.Bool) {
// To cleanup, set active to false then close the channel // To cleanup, set active to false then close the channel
func UTF8Listener(buffer int, file *os.File) (chan []byte, *atomic.Bool) { func UTF8Listener(buffer int, file *os.File) (chan []byte, *atomic.Bool) {
channel := make(chan []byte, buffer) channel := make(chan []byte, buffer)
reader := bufio.NewReader(file)
active := new(atomic.Bool) active := new(atomic.Bool)
active.Store(true) active.Store(true)
go UTF8Listen(file, channel, active) go UTF8Listen(reader, channel, active)
return channel, active return channel, active
} }

@ -70,6 +70,7 @@ var GetMaxY = ncursesFunction[winFP]("getmaxy")
var GetMaxX = ncursesFunction[winFP]("getmaxx") var GetMaxX = ncursesFunction[winFP]("getmaxx")
var WClear = ncursesFunction[winFP]("wclear") var WClear = ncursesFunction[winFP]("wclear")
var WErase = ncursesFunction[winFP]("werase")
type mvwaddstrFP func(window Window, y, x int, str string) int type mvwaddstrFP func(window Window, y, x int, str string) int
var MvWAddStr = ncursesFunction[mvwaddstrFP]("mvwaddstr") var MvWAddStr = ncursesFunction[mvwaddstrFP]("mvwaddstr")
@ -119,5 +120,6 @@ var MvWin = ncursesFunction[wyxFP]("mvwin")
var StdScr = ncursesSymbol[Window]("stdscr") var StdScr = ncursesSymbol[Window]("stdscr")
var CurScr = ncursesSymbol[Window]("curscr") var CurScr = ncursesSymbol[Window]("curscr")
type restarttermFP func(term string, fd int, errret *int) int type curssetFP func(visibility int) int
var RestartTerm = ncursesFunction[restarttermFP]("restartterm") var CursSet = ncursesFunction[curssetFP]("curs_set")