Use shlex

This commit is contained in:
hedy 2023-12-06 09:07:06 +08:00
parent 0e86f4304b
commit 1bd404db94
Signed by: hedy
GPG Key ID: B51B5A8D1B176372
5 changed files with 25 additions and 63 deletions

View File

@ -10,6 +10,7 @@ import (
"strings"
"git.sr.ht/~adnano/go-xdg"
"github.com/google/shlex"
"github.com/manifoldco/ansiwrap"
ln "github.com/peterh/liner"
"golang.org/x/term"
@ -835,7 +836,8 @@ func (c *Client) GetCommandAndArgs(line string) (
return
}
// Rejoin args, split using QuotedFields
args = QuotedFields(strings.Join(args, " "))
// Rejoin args, split using shlex
// XXX: err is ignored
args, _ = shlex.Split(strings.Join(args, " "))
return
}

28
cmd.go
View File

@ -7,6 +7,8 @@ import (
"os/exec"
"strconv"
"strings"
"github.com/google/shlex"
)
// Command is the metadata of all (non-meta) commands in the client
@ -40,18 +42,19 @@ func printHelp(style *Style) {
minSepSpaceLen := 2 // min space between command and the description
// Here comes the fun part
// We are now *actually* printing the help
fmt.Println("You can directly enter a url or link-index (number) at the prompt.")
fmt.Println()
fmt.Println("Otherwise, there are plenty of useful commands you can use.")
fmt.Println("Arguments are separated by spaces, and quoting with ' and \" is supported\nlike the shell, but escaping quotes is not support yet.")
fmt.Println()
fmt.Println("You can supply a command name to `help` to see the help for a specific command, like `help tour`.")
fmt.Println()
fmt.Println("Commands:")
fmt.Println(`You can directly enter a url or link-index (number) at the prompt.
Otherwise, there are plenty of useful commands you can use. Arguments
are separated by spaces, and quoting with ' and " is supported like the
shell, escaping quotes is also supported.
You can supply a command name to 'help' to see the help for a specific
command, like 'help tour.
Commands:`)
var spacesBetween int
for name, cmd := range commands {
// TODO: wrap description with... aniswrap?
// also maybe add some colors in the help!
if cmd.hidden {
continue
}
@ -602,7 +605,12 @@ func (c *Client) ClipboardCopy(content string) (ok bool) {
c.style.ErrorMsg("please set a clipboard command in config file option 'clipboardCopyCmd'\nThe content to copy will be piped into that command as stdin")
return
}
parts := strings.Split(c.conf.ClipboardCopyCmd, " ")
parts, err := shlex.Split(c.conf.ClipboardCopyCmd)
if err != nil {
ok = false
c.style.ErrorMsg("Could not parse ClipboardCopyCmd into command and arguments: " + c.conf.ClipboardCopyCmd)
return
}
cmd := exec.Command(parts[0], parts[1:]...)
stdin, err := cmd.StdinPipe()
if err != nil {

View File

@ -30,39 +30,6 @@ var (
quoteFieldRe = regexp.MustCompile("'(.*)'|\"(.*)\"|(\\S*)")
)
// QuotedFields is an alternative to strings.Fields (see:
// https://golang.org/pkg/strings#Fields) that respects spaces between matching
// pairs of quotation delimiters.
//
// For instance, the quoted fields of the string "foo bar 'baz etc'" would be:
//
// []string{"foo", "bar", "baz etc"}
//
// Whereas the same argument given to strings.Fields, would return:
//
// []string{"foo", "bar", "'baz", "etc'"}
func QuotedFields(s string) []string {
submatches := quoteFieldRe.FindAllStringSubmatch(s, -1)
out := make([]string, 0, len(submatches))
for _, matches := range submatches {
// if a leading or trailing space is found, ignore that
if matches[0] == "" {
continue
}
// otherwise, find the first non-empty match (inside balanced
// quotes, or a space-delimited string)
var str string
for _, m := range matches[1:] {
if len(m) > 0 {
str = m
break
}
}
out = append(out, str)
}
return out
}
// Pager uses `less` to display body
// falls back to fmt.Print if errors encountered
func Pager(body string, conf *Config) {

1
go.mod
View File

@ -6,6 +6,7 @@ require (
git.sr.ht/~adnano/go-xdg v0.1.0
github.com/BurntSushi/toml v1.3.2
github.com/fatih/color v1.15.0
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/manifoldco/ansiwrap v1.1.0
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect

20
go.sum
View File

@ -1,31 +1,22 @@
git.sr.ht/~adnano/go-xdg v0.1.0 h1:UvmVKPmbWHoMGzdfKLvHBGf/Yfp74pqfyJiyu558TB8=
git.sr.ht/~adnano/go-xdg v0.1.0/go.mod h1:n3ytgoiOi6MHzs0leTpVOwDI3L8n+M/E8hS0sEPrzFs=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg=
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/manifoldco/ansiwrap v1.1.0 h1:NS3ZV8cCh+dG/sM4e4wM0WSMFWHhSuVFNnwtx6qrqyU=
github.com/manifoldco/ansiwrap v1.1.0/go.mod h1:2yA5wi1rF9kAuD6RbwON60QdT46zrKhIS+KHbNwwy8U=
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.3 h1:a+kO+98RDGEfo6asOGMmpodZq4FNtnGP54yps8BzLR4=
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/peterh/liner v1.2.1 h1:O4BlKaq/LWu6VRWmol4ByWfzx6MfXc5Op5HETyIy5yg=
github.com/peterh/liner v1.2.1/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0=
github.com/peterh/liner v1.2.2 h1:aJ4AOodmL+JxOZZEL2u9iJf8omNRpqHc/EbrK+3mAXw=
github.com/peterh/liner v1.2.2/go.mod h1:xFwJyiKIXJZUKItq5dGHZSTBRAuG/CpeNpWLyiNRNwI=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
@ -33,17 +24,10 @@ github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20210429154555-c04ba851c2a4 h1:UPou2i3GzKgi6igR+/0C5XyHKBngHxBp/CL5CQ0p3Zk=
golang.org/x/term v0.0.0-20210429154555-c04ba851c2a4/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=