Skip to content

Commit

Permalink
feat(term): integrate cancelreader for terminal input
Browse files Browse the repository at this point in the history
  • Loading branch information
nullswan committed Nov 3, 2024
1 parent e9022a7 commit 3bd04e1
Showing 1 changed file with 20 additions and 8 deletions.
28 changes: 20 additions & 8 deletions internal/term/terminal.go
Original file line number Diff line number Diff line change
@@ -1,28 +1,32 @@
package term

// From: https://github.com/ollama/ollama/blob/main/readline/readline.go

import (
"bufio"
"fmt"
"io"
"os"

"github.com/muesli/cancelreader"
)

type Terminal struct {
outchan chan rune
done chan struct{}
rawmode bool
termios any
reader *bufio.Reader
reader cancelreader.CancelReader
}

func NewTerminal() (*Terminal, error) {
reader, err := cancelreader.NewReader(os.Stdin)
if err != nil {
return nil, fmt.Errorf("failed to create cancelable reader: %w", err)
}
t := &Terminal{
outchan: make(chan rune),
done: make(chan struct{}),
rawmode: false,
termios: nil,
reader: bufio.NewReader(os.Stdin),
reader: reader,
}

go t.ioloop()
Expand All @@ -40,6 +44,7 @@ func (t *Terminal) Read() (rune, error) {
}

func (t *Terminal) Close() error {
t.reader.Close()
close(t.outchan)
close(t.done)
return nil
Expand All @@ -55,24 +60,31 @@ func (t *Terminal) Closed() bool {
}

func (t *Terminal) ioloop() {
// This is where we recover from panics
defer func() {
recover() // nolint:errcheck
if rec := recover(); rec != nil {
fmt.Println("Recovered from panic:", rec)
}
}()

for {
select {
case <-t.done:
return
default:
r, _, err := t.reader.ReadRune()
buf := make([]byte, 1)
n, err := t.reader.Read(buf)
if err != nil {
return
}
if n == 0 {
continue
}

select {
case <-t.done:
return
case t.outchan <- r:
case t.outchan <- rune(buf[0]):
}
}
}
Expand Down

0 comments on commit 3bd04e1

Please sign in to comment.