Always use run script

pull/9/head
Trevor Slocum 2019-07-05 09:11:14 -07:00
parent 372c2be50f
commit cc4942dcf7
6 changed files with 78 additions and 92 deletions

View File

@ -5,8 +5,6 @@ package main
import (
"flag"
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
@ -14,12 +12,11 @@ import (
"strings"
"syscall"
"git.sr.ht/~tslocum/gmenu/pkg/config"
"git.sr.ht/~tslocum/gmenu/pkg/dmenu"
"github.com/tslocum/promptui"
)
var terminal = "i3-sensible-terminal"
func init() {
log.SetFlags(0)
@ -73,10 +70,8 @@ func main() {
Active: ">{{ .Name }}",
Inactive: " {{ .Name }}",
Selected: "Launching {{ .Name }}...",
Details: `{{ "Name(s)" | faint }} {{ .Name }}{{ if .GenericName }}, {{ .GenericName }}{{ end }}
{{ "Comment" | faint }} {{ .Comment }}
{{ "Exec" | faint }} {{ .Exec }}`,
Help: "",
Details: `{{ "Exec:" | faint }} {{ printf "%.60s" .Exec }}`,
Help: "",
}
prompt := promptui.Select{
Items: desktopEntries,
@ -89,57 +84,39 @@ func main() {
selected, input, err := prompt.Run()
if err != nil {
log.Fatal(err)
} else if selected < 0 && strings.TrimSpace(input) == "" {
return
}
var (
ex string
ex string
runInTerminal bool
waitUntilFinished bool
)
if selected >= 0 {
runInTerminal = desktopEntries[selected].Terminal
ex = dmenu.ExpandFieldCodes(desktopEntries[selected].Exec)
if desktopEntries[selected].Terminal {
runScript, err := ioutil.TempFile("", "gmenu-*")
if err != nil {
log.Fatal(err)
}
_, err = runScript.WriteString("#!/bin/sh\n")
if err != nil {
runScript.Close()
log.Fatal(err)
}
_, err = runScript.WriteString(fmt.Sprintf("rm %s\n", runScript.Name()))
if err != nil {
runScript.Close()
log.Fatal(err)
}
_, err = runScript.WriteString(fmt.Sprintf("exec %s\n", ex))
if err != nil {
runScript.Close()
log.Fatal(err)
}
runScript.Close()
if err := os.Chmod(runScript.Name(), 0744); err != nil {
log.Fatal(err)
}
ex = fmt.Sprintf(`%s -e '%s'`, terminal, runScript.Name())
} else {
ex = fmt.Sprintf(`/bin/bash -i -c '%s'`, strings.ReplaceAll(ex, `'`, `'\''`))
}
} else {
ex = fmt.Sprintf(`/bin/bash -i -c '%s'`, strings.ReplaceAll(input, `'`, `'\''`))
waitUntilFinished = true
ex = input
}
command, args, err := dmenu.CommandNameAndArgs(ex)
log.Println(ex)
runScript, err := dmenu.WriteRunScript(ex)
if err != nil {
log.Fatal(err)
log.Fatalf("failed to write run script: %s", err)
}
var cmd *exec.Cmd
if runInTerminal {
cmd = exec.Command(config.TerminalCommand, "-e", runScript)
} else {
cmd = exec.Command("/usr/bin/env", "bash", "-c", runScript)
}
cmd := exec.Command(command, args...)
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true, Pgid: 0}
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
@ -148,4 +125,13 @@ func main() {
if err != nil {
log.Fatal(err)
}
if !waitUntilFinished {
return
}
err = cmd.Wait()
if err != nil {
log.Fatal(err)
}
}

1
go.mod
View File

@ -4,6 +4,5 @@ go 1.12
require (
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
github.com/tslocum/promptui v0.3.4-0.20190628082230-cf53eafff9c5
)

2
go.sum
View File

@ -11,8 +11,6 @@ github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf/go.mod h1:RpwtwJQFrIE
github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU=
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a h1:FaWFmfWdAUKbSCtOU2QjDaorUexogfaMgbipgYATUMU=
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=

View File

@ -1,3 +1,6 @@
package config
var Version string
var (
Version string
TerminalCommand = "i3-sensible-terminal"
)

View File

@ -8,8 +8,6 @@ import (
"os"
"path/filepath"
"strings"
"github.com/kballard/go-shellquote"
)
// TODO: Support Type=URL
@ -102,46 +100,6 @@ func ExpandFieldCodes(ex string) string {
return ex
}
func CommandNameAndArgs(ex string) (string, []string, error) {
execLen := len(ex)
if execLen == 0 {
return "", nil, nil
} else if execLen <= 2 || ex[0] != '"' {
split := strings.SplitN(ex, " ", 2)
if len(split) == 1 {
return split[0], nil, nil
}
args, err := shellquote.Split(split[1])
if err != nil {
return "", nil, err
}
return split[0], args, nil
} else {
endQuote := strings.IndexRune(ex[1:], '"')
if endQuote > 0 {
var argsAfterQuote string
if execLen > (endQuote + 2) {
if ex[endQuote+2] == ' ' {
argsAfterQuote = ex[endQuote+3:]
} else {
argsAfterQuote = ex[endQuote+2:]
}
}
args, err := shellquote.Split(argsAfterQuote)
if err != nil {
return "", nil, err
}
return ex[1 : endQuote+1], args, nil
} else {
return ex, nil, nil
}
}
}
func scanDirectory(path string, f os.FileInfo, err error) error {
if f.IsDir() || !strings.HasSuffix(strings.ToLower(path), ".desktop") {
return nil

42
pkg/dmenu/exec.go Normal file
View File

@ -0,0 +1,42 @@
package dmenu
import (
"fmt"
"io/ioutil"
"os"
)
func WriteRunScript(ex string) (string, error) {
runScript, err := ioutil.TempFile("", "gmenu-*")
if err != nil {
return "", err
}
_, err = runScript.WriteString("#!/bin/sh\n")
if err != nil {
runScript.Close()
return "", err
}
_, err = runScript.WriteString(fmt.Sprintf("rm %s\n", runScript.Name()))
if err != nil {
runScript.Close()
return "", err
}
_, err = runScript.WriteString("exec " + ex + "\n")
if err != nil {
runScript.Close()
return "", err
}
err = runScript.Close()
if err != nil {
return "", err
}
err = os.Chmod(runScript.Name(), 0744)
if err != nil {
return "", err
}
return runScript.Name(), nil
}