Implement sen text from stdin for the tty backend
This commit is contained in:
parent
85169c989f
commit
cb452ba9fc
@ -17,16 +17,18 @@ import (
|
|||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
|
|
||||||
"github.com/jamesruan/go-rfc1924/base85"
|
|
||||||
"kitty"
|
"kitty"
|
||||||
"kitty/tools/cli"
|
"kitty/tools/cli"
|
||||||
"kitty/tools/crypto"
|
"kitty/tools/crypto"
|
||||||
"kitty/tools/tty"
|
"kitty/tools/tty"
|
||||||
"kitty/tools/tui"
|
"kitty/tools/tui"
|
||||||
|
"kitty/tools/tui/loop"
|
||||||
"kitty/tools/utils"
|
"kitty/tools/utils"
|
||||||
|
|
||||||
|
"github.com/jamesruan/go-rfc1924/base85"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ProtocolVersion [3]int = [3]int{0, 20, 0}
|
var ProtocolVersion [3]int = [3]int{0, 26, 0}
|
||||||
|
|
||||||
func add_bool_set(cmd *cobra.Command, name string, short string, usage string) *bool {
|
func add_bool_set(cmd *cobra.Command, name string, short string, usage string) *bool {
|
||||||
if short == "" {
|
if short == "" {
|
||||||
@ -143,7 +145,7 @@ type rc_io_data struct {
|
|||||||
cmd *cobra.Command
|
cmd *cobra.Command
|
||||||
rc *utils.RemoteControlCmd
|
rc *utils.RemoteControlCmd
|
||||||
serializer serializer_func
|
serializer serializer_func
|
||||||
send_keypresses bool
|
on_key_event func(lp *loop.Loop, ke *loop.KeyEvent) error
|
||||||
string_response_is_err bool
|
string_response_is_err bool
|
||||||
timeout time.Duration
|
timeout time.Duration
|
||||||
multiple_payload_generator func(io_data *rc_io_data) (bool, error)
|
multiple_payload_generator func(io_data *rc_io_data) (bool, error)
|
||||||
@ -184,6 +186,11 @@ func get_response(do_io func(io_data *rc_io_data) ([]byte, error), io_data *rc_i
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(serialized_response) == 0 {
|
if len(serialized_response) == 0 {
|
||||||
|
if io_data.rc.NoResponse {
|
||||||
|
res := Response{Ok: true}
|
||||||
|
ans = &res
|
||||||
|
return
|
||||||
|
}
|
||||||
err = fmt.Errorf("Received empty response from kitty")
|
err = fmt.Errorf("Received empty response from kitty")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,11 +6,16 @@ import (
|
|||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
|
"kitty/tools/tui/loop"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var end_reading_from_stdin = errors.New("end reading from STDIN")
|
||||||
|
var waiting_on_stdin = errors.New("wait for key events from STDIN")
|
||||||
|
|
||||||
func parse_send_text(io_data *rc_io_data, args []string) error {
|
func parse_send_text(io_data *rc_io_data, args []string) error {
|
||||||
|
io_data.rc.NoResponse = true
|
||||||
generators := make([]func(io_data *rc_io_data) (bool, error), 0, 1)
|
generators := make([]func(io_data *rc_io_data) (bool, error), 0, 1)
|
||||||
|
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
@ -44,6 +49,39 @@ func parse_send_text(io_data *rc_io_data, args []string) error {
|
|||||||
generators = append(generators, file_gen)
|
generators = append(generators, file_gen)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if options_send_text.stdin {
|
||||||
|
pending_key_events := make([]string, 0, 1)
|
||||||
|
|
||||||
|
io_data.on_key_event = func(lp *loop.Loop, ke *loop.KeyEvent) error {
|
||||||
|
ke.Handled = true
|
||||||
|
if ke.MatchesPressOrRepeat("ctrl+d") {
|
||||||
|
return end_reading_from_stdin
|
||||||
|
}
|
||||||
|
bs := "kitty-key:" + base64.StdEncoding.EncodeToString([]byte(ke.AsCSI()))
|
||||||
|
pending_key_events = append(pending_key_events, bs)
|
||||||
|
if ke.Text != "" {
|
||||||
|
lp.QueueWriteString(ke.Text)
|
||||||
|
} else if ke.MatchesPressOrRepeat("backspace") {
|
||||||
|
lp.QueueWriteString("\x08\x1b[P")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
key_gen := func(io_data *rc_io_data) (bool, error) {
|
||||||
|
if len(pending_key_events) > 0 {
|
||||||
|
payload := io_data.rc.Payload.(send_text_json_type)
|
||||||
|
payload.Exclude_active = true
|
||||||
|
io_data.rc.Payload = payload
|
||||||
|
set_payload_data(io_data, pending_key_events[0])
|
||||||
|
pending_key_events = pending_key_events[1:]
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
return false, waiting_on_stdin
|
||||||
|
}
|
||||||
|
generators = append(generators, key_gen)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
io_data.multiple_payload_generator = func(io_data *rc_io_data) (bool, error) {
|
io_data.multiple_payload_generator = func(io_data *rc_io_data) (bool, error) {
|
||||||
if len(generators) == 0 {
|
if len(generators) == 0 {
|
||||||
set_payload_data(io_data, "text:")
|
set_payload_data(io_data, "text:")
|
||||||
|
|||||||
@ -46,6 +46,9 @@ func do_chunked_io(io_data *rc_io_data) (serialized_response []byte, err error)
|
|||||||
if state != WAITING_FOR_RESPONSE && state != WAITING_FOR_STREAMING_RESPONSE {
|
if state != WAITING_FOR_RESPONSE && state != WAITING_FOR_STREAMING_RESPONSE {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
if io_data.on_key_event != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
time_since_last_received_data := time.Now().Sub(last_received_data_at)
|
time_since_last_received_data := time.Now().Sub(last_received_data_at)
|
||||||
if time_since_last_received_data >= io_data.timeout {
|
if time_since_last_received_data >= io_data.timeout {
|
||||||
return os.ErrDeadlineExceeded
|
return os.ErrDeadlineExceeded
|
||||||
@ -77,6 +80,9 @@ func do_chunked_io(io_data *rc_io_data) (serialized_response []byte, err error)
|
|||||||
chunk, err := io_data.next_chunk()
|
chunk, err := io_data.next_chunk()
|
||||||
wants_streaming = io_data.rc.Stream
|
wants_streaming = io_data.rc.Stream
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if err == waiting_on_stdin {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
queue_escape_code(chunk)
|
queue_escape_code(chunk)
|
||||||
@ -93,6 +99,9 @@ func do_chunked_io(io_data *rc_io_data) (serialized_response []byte, err error)
|
|||||||
}
|
}
|
||||||
chunk, err := io_data.next_chunk()
|
chunk, err := io_data.next_chunk()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if err == waiting_on_stdin {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
queue_escape_code(chunk)
|
queue_escape_code(chunk)
|
||||||
@ -111,6 +120,29 @@ func do_chunked_io(io_data *rc_io_data) (serialized_response []byte, err error)
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lp.OnKeyEvent = func(event *loop.KeyEvent) error {
|
||||||
|
if io_data.on_key_event == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
err := io_data.on_key_event(lp, event)
|
||||||
|
if err == end_reading_from_stdin {
|
||||||
|
lp.Quit(0)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
chunk, err := io_data.next_chunk()
|
||||||
|
if err != nil {
|
||||||
|
if err == waiting_on_stdin {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
queue_escape_code(chunk)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
lp.OnRCResponse = func(raw []byte) error {
|
lp.OnRCResponse = func(raw []byte) error {
|
||||||
if state == WAITING_FOR_STREAMING_RESPONSE && is_stream_response(raw) {
|
if state == WAITING_FOR_STREAMING_RESPONSE && is_stream_response(raw) {
|
||||||
state = SENDING
|
state = SENDING
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user