Wire up a bunch of callbacks

This commit is contained in:
Kovid Goyal 2022-08-23 20:08:04 +05:30
parent e18b6638bb
commit 526a331f47
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 91 additions and 19 deletions

View File

@ -118,11 +118,12 @@ func do_io(device IOAbstraction, input utils.Reader, no_response bool, response_
response_received := false
cmd_prefix := []byte("@kitty-cmd")
handle_dcs := func(b []byte) {
handle_dcs := func(b []byte) error {
if bytes.HasPrefix(b, cmd_prefix) {
response_received = true
}
serialized_response = b[len(cmd_prefix):]
return nil
}
var p utils.EscapeCodeParser = utils.EscapeCodeParser{HandleDCS: handle_dcs}

View File

@ -6,21 +6,56 @@ import (
"kitty/tools/tty"
"os"
"time"
"kitty/tools/utils"
)
type TerminalState struct {
alternate_screen, grab_mouse bool
type Loop struct {
controlling_term *tty.Term
terminal_options TerminalStateOptions
escape_code_parser utils.EscapeCodeParser
keep_going bool
flush_write_buf bool
write_buf []byte
}
type Loop struct {
controlling_term *tty.Term
keep_going bool
flush_write_buf bool
write_buf []byte
func (self *Loop) handle_csi(raw []byte) error {
return nil
}
func (self *Loop) handle_osc(raw []byte) error {
return nil
}
func (self *Loop) handle_dcs(raw []byte) error {
return nil
}
func (self *Loop) handle_apc(raw []byte) error {
return nil
}
func (self *Loop) handle_sos(raw []byte) error {
return nil
}
func (self *Loop) handle_pm(raw []byte) error {
return nil
}
func (self *Loop) handle_rune(raw rune) error {
return nil
}
func CreateLoop() (*Loop, error) {
l := Loop{controlling_term: nil}
l.escape_code_parser.HandleCSI = l.handle_csi
l.escape_code_parser.HandleOSC = l.handle_osc
l.escape_code_parser.HandleDCS = l.handle_dcs
l.escape_code_parser.HandleAPC = l.handle_apc
l.escape_code_parser.HandleSOS = l.handle_sos
l.escape_code_parser.HandlePM = l.handle_pm
l.escape_code_parser.HandleRune = l.handle_rune
return &l, nil
}
@ -51,6 +86,7 @@ func (self *Loop) Run() (err error) {
if err != nil {
return err
}
tty_fd := controlling_term.Fd()
self.controlling_term = controlling_term
defer func() {
self.controlling_term.RestoreAndClose()
@ -63,18 +99,29 @@ func (self *Loop) Run() (err error) {
var selector Select
selector.RegisterRead(int(signal_read_file.Fd()))
selector.RegisterRead(controlling_term.Fd())
selector.RegisterRead(tty_fd)
self.keep_going = true
self.flush_write_buf = true
self.queue_write_to_tty(self.terminal_options.SetStateEscapeCodes())
defer func() {
if self.flush_write_buf {
self.flush()
}
self.write_buf = self.write_buf[:]
self.queue_write_to_tty(self.terminal_options.ResetStateEscapeCodes())
self.flush()
}()
read_buf := make([]byte, utils.DEFAULT_IO_BUFFER_SIZE)
self.escape_code_parser.Reset()
for self.keep_going {
if len(self.write_buf) > 0 {
selector.RegisterWrite(tty_fd)
} else {
selector.UnRegisterWrite(tty_fd)
}
num_ready, err := selector.WaitForever()
if err != nil {
return fmt.Errorf("Failed to call select() with error: %w", err)
@ -82,12 +129,36 @@ func (self *Loop) Run() (err error) {
if num_ready == 0 {
continue
}
if len(self.write_buf) > 0 && selector.IsReadyToWrite(tty_fd) {
err := self.write_to_tty()
if err != nil {
return err
}
}
if selector.IsReadyToRead(tty_fd) {
read_buf = read_buf[:cap(read_buf)]
num_read, err := self.controlling_term.Read(read_buf)
if err != nil {
return err
}
if num_read == 0 {
return io.EOF
}
err = self.escape_code_parser.Parse(read_buf[:num_read])
if err != nil {
return err
}
}
}
return nil
}
func (self *Loop) write() error {
func (self *Loop) queue_write_to_tty(data []byte) {
self.write_buf = append(self.write_buf, data...)
}
func (self *Loop) write_to_tty() error {
if len(self.write_buf) == 0 || self.controlling_term == nil {
return nil
}
@ -125,7 +196,7 @@ func (self *Loop) flush() error {
return err
}
if num_ready > 0 && selector.IsReadyToWrite(self.controlling_term.Fd()) {
err = self.write()
err = self.write_to_tty()
if err != nil {
return err
}

View File

@ -73,9 +73,9 @@ const (
FULL_MOUSE_TRACKING
)
type TerminalState struct {
alternate_screen, kitty_keyboard_mode bool
mouse_tracking MouseTracking
type TerminalStateOptions struct {
alternate_screen, no_kitty_keyboard_mode bool
mouse_tracking MouseTracking
}
func set_modes(sb *strings.Builder, modes ...Mode) {
@ -90,7 +90,7 @@ func reset_modes(sb *strings.Builder, modes ...Mode) {
}
}
func (self *TerminalState) SetStateEscapeCodes() []byte {
func (self *TerminalStateOptions) SetStateEscapeCodes() []byte {
var sb strings.Builder
sb.Grow(256)
sb.WriteString(S7C1T)
@ -107,10 +107,10 @@ func (self *TerminalState) SetStateEscapeCodes() []byte {
set_modes(&sb, ALTERNATE_SCREEN)
sb.WriteString(CLEAR_SCREEN)
}
if self.kitty_keyboard_mode {
sb.WriteString("\033[>31u")
} else {
if self.no_kitty_keyboard_mode {
sb.WriteString("\033[>u")
} else {
sb.WriteString("\033[>31u")
}
if self.mouse_tracking != NO_MOUSE_TRACKING {
sb.WriteString(MOUSE_SGR_PIXEL_MODE.EscapeCodeToSet())
@ -126,7 +126,7 @@ func (self *TerminalState) SetStateEscapeCodes() []byte {
return []byte(sb.String())
}
func (self *TerminalState) ResetStateData() []byte {
func (self *TerminalStateOptions) ResetStateEscapeCodes() []byte {
var sb strings.Builder
sb.Grow(64)
sb.WriteString("\033[<u")