Work on conversion of args parsing to go code

This commit is contained in:
Kovid Goyal
2022-08-30 00:21:59 +05:30
parent 441e4edfb2
commit 79c8862d4c
32 changed files with 274 additions and 66 deletions

20
tools/cmd/at/env.go Normal file
View File

@@ -0,0 +1,20 @@
// License: GPLv3 Copyright: 2022, Kovid Goyal, <kovid at kovidgoyal.net>
package at
import (
"kitty/tools/utils"
)
func parse_key_val_args(args []string) map[string]string {
ans := make(map[string]string, len(args))
for _, arg := range args {
key, value, found := utils.Cut(arg, "=")
if found {
ans[key] = value
} else {
ans[key+"="] = ""
}
}
return ans
}

View File

@@ -9,6 +9,7 @@ import (
"fmt"
"io"
"os"
"strconv"
"strings"
"time"
@@ -73,20 +74,37 @@ func simple_serializer(rc *utils.RemoteControlCmd) (ans []byte, err error) {
type serializer_func func(rc *utils.RemoteControlCmd) ([]byte, error)
type wrapped_serializer struct {
state int
serializer serializer_func
state int
serializer serializer_func
all_payloads_done bool
}
func (self *wrapped_serializer) next(rc *utils.RemoteControlCmd) ([]byte, error) {
func (self *wrapped_serializer) next(io_data *rc_io_data) ([]byte, error) {
const prefix = "\x1bP@kitty-cmd"
const suffix = "\x1b\\"
defer func() { self.state++ }()
switch self.state {
case 0:
self.state++
return []byte(prefix), nil
case 1:
return self.serializer(rc)
if io_data.multiple_payload_generator != nil {
is_last, err := io_data.multiple_payload_generator(io_data)
if err != nil {
return nil, err
}
if is_last {
self.all_payloads_done = true
}
} else {
self.all_payloads_done = true
}
return self.serializer(io_data.rc)
case 2:
if self.all_payloads_done {
self.state++
} else {
self.state = 0
}
return []byte(suffix), nil
default:
return make([]byte, 0), nil
@@ -144,12 +162,13 @@ type Response struct {
}
type rc_io_data struct {
cmd *cobra.Command
rc *utils.RemoteControlCmd
serializer wrapped_serializer
send_keypresses bool
string_response_is_err bool
timeout time.Duration
cmd *cobra.Command
rc *utils.RemoteControlCmd
serializer wrapped_serializer
send_keypresses bool
string_response_is_err bool
timeout time.Duration
multiple_payload_generator func(io_data *rc_io_data) (bool, error)
pending_chunks [][]byte
}
@@ -161,7 +180,7 @@ func (self *rc_io_data) next_chunk(limit_size bool) (chunk []byte, err error) {
self.pending_chunks = self.pending_chunks[:len(self.pending_chunks)-1]
return
}
block, err := self.serializer.next(self.rc)
block, err := self.serializer.next(self)
if err != nil && !errors.Is(err, io.EOF) {
return
}

View File

@@ -0,0 +1,40 @@
// License: GPLv3 Copyright: 2022, Kovid Goyal, <kovid at kovidgoyal.net>
package at
import (
"fmt"
"strconv"
"strings"
)
func parse_scroll_amount(amt string) ([2]interface{}, error) {
var ans [2]interface{}
if amt == "start" || amt == "end" {
ans[0] = amt
ans[1] = nil
} else {
pages := strings.Contains(amt, "p")
unscroll := strings.Contains(amt, "u")
var mult float64 = 1
if strings.HasSuffix(amt, "-") && !unscroll {
mult = -1
q, err := strconv.ParseFloat(strings.TrimRight(amt, "+-plu"), 64)
if err != nil {
return ans, err
}
if !pages && q != float64(int(q)) {
return ans, fmt.Errorf("The number must be an integer")
}
ans[0] = q * mult
if pages {
ans[1] = "p"
} else if unscroll {
ans[1] = "u"
} else {
ans[1] = "l"
}
}
}
return ans, nil
}

View File

@@ -0,0 +1,54 @@
// License: GPLv3 Copyright: 2022, Kovid Goyal, <kovid at kovidgoyal.net>
package at
import (
"encoding/base64"
"fmt"
"io"
"net/http"
"os"
"strings"
)
func read_window_logo(path string) (func(io_data *rc_io_data) (bool, error), error) {
if strings.ToLower(path) == "none" {
return func(io_data *rc_io_data) (bool, error) {
io_data.rc.Payload = "-"
return true, nil
}, nil
}
f, err := os.Open(path)
if err != nil {
return nil, err
}
buf := make([]byte, 2048)
n, err := f.Read(buf)
if err != nil && err != io.EOF {
f.Close()
return nil, err
}
buf = buf[:n]
if http.DetectContentType(buf) != "image/png" {
f.Close()
return nil, fmt.Errorf("%s is not a PNG image", path)
}
return func(io_data *rc_io_data) (bool, error) {
var payload set_window_logo_json_type = io_data.rc.Payload.(set_window_logo_json_type)
if len(buf) == 0 {
payload.Data = ""
return true, nil
}
payload.Data = base64.StdEncoding.EncodeToString(buf)
buf = buf[:cap(buf)]
n, err := f.Read(buf)
if err != nil && err != io.EOF {
return false, err
}
buf = buf[:n]
return n == 0, nil
}, nil
}

View File

@@ -7,6 +7,8 @@
package at
import (
"fmt"
"strings"
"time"
"github.com/spf13/cobra"
@@ -16,6 +18,9 @@ import (
"kitty/tools/utils"
)
var _ = fmt.Print
var _ = strings.Join
type options_CMD_NAME_type struct {
OPTIONS_DECLARATION_CODE
}
@@ -88,7 +93,7 @@ func aliasNormalizeFunc_CMD_NAME(f *pflag.FlagSet, name string) pflag.Normalized
func setup_CMD_NAME(root *cobra.Command) *cobra.Command {
ans := cli.CreateCommand(&cobra.Command{
Use: "CLI_NAME [options]",
Use: "CLI_NAME [options]" + "ARGSPEC",
Short: "SHORT_DESC",
Long: "LONG_DESC",
RunE: run_CMD_NAME,

View File

@@ -44,7 +44,7 @@ func do_chunked_io(io_data *rc_io_data) (serialized_response []byte, err error)
}
lp.OnInitialize = func() (string, error) {
chunk, err := io_data.next_chunk(true)
chunk, err := io_data.next_chunk(false)
if err != nil {
return "", err
}
@@ -62,7 +62,7 @@ func do_chunked_io(io_data *rc_io_data) (serialized_response []byte, err error)
}
return nil
}
chunk, err := io_data.next_chunk(true)
chunk, err := io_data.next_chunk(false)
if err != nil {
return err
}