Skip to content

Commit

Permalink
fixed terminal=true bug #680
Browse files Browse the repository at this point in the history
  • Loading branch information
matryer committed Aug 28, 2021
1 parent 5edfaaa commit 5bf6171
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 42 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -361,14 +361,14 @@ You can control xbar behaviour by modifying the `/Library/Application Support/xb
{
"autoupdate": true,
"terminal": {
"appleScriptWithVarsTemplate": ""
"appleScriptTemplate2": ""
}
}
```

* Changes take effect next time xbar starts
* `autoupdate` - (boolean) whether to keep xbar automatically updated or not
* `terminal.appleScriptWithVarsTemplate` - (string) the AppleScript to use when **Run in terminal** option is used (use `"false"` to turn this feature off)
* `terminal.appleScriptTemplate2` - (string) the AppleScript to use when **Run in terminal** option is used (use `"false"` to turn this feature off)

You can delete this file and restart xbar to reset to defaults.

Expand Down
2 changes: 1 addition & 1 deletion app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ func (app *app) newXbarMenu(plugin *plugins.Plugin, asSubmenu bool) *menu.Menu {
})
if plugin != nil {
items = append(items, menu.Text("Run in terminal…", keys.CmdOrCtrl("t"), func(_ *menu.CallbackData) {
err := plugin.RunInTerminal(app.settings.Terminal.AppleScriptWithVarsTemplate)
err := plugin.RunInTerminal(app.settings.Terminal.AppleScriptTemplate2)
if err != nil {
_, err2 := app.runtime.Dialog.Message(&dialog.MessageDialog{
Type: dialog.ErrorDialog,
Expand Down
2 changes: 1 addition & 1 deletion app/menu_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ package main
import (
"context"
"fmt"
"github.com/leaanthony/go-ansi-parser"
"strconv"

"github.com/leaanthony/go-ansi-parser"
"github.com/matryer/xbar/pkg/plugins"
"github.com/wailsapp/wails/v2/pkg/menu"
"github.com/wailsapp/wails/v2/pkg/menu/keys"
Expand Down
29 changes: 20 additions & 9 deletions app/menu_parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,60 +18,71 @@ func TestMenuParser(t *testing.T) {
ctx, cancel := context.WithTimeout(ctx, 1*time.Second)
defer cancel()

plugin := &plugins.Plugin{}

items := []*plugins.Item{
{
Text: "one",
Plugin: plugin,
Text: "one",
Items: []*plugins.Item{
{Text: "sub1"},
{Text: "sub2"},
{Text: "sub3"},
},
},
{
Text: "two",
Plugin: plugin,
Text: "two",
Params: plugins.ItemParams{
Font: "Courier New",
Size: 26,
Key: "CmdOrCtrl+Shift+K",
},
},
{
Text: "three",
Plugin: plugin,
Text: "three",
},
{
Text: "four",
Plugin: plugin,
Text: "four",
Params: plugins.ItemParams{
Href: "https://xbarapp.com",
},
},
{
Text: "five",
Plugin: plugin,
Text: "five",
Params: plugins.ItemParams{
Shell: "echo",
ShellParams: []string{"hi"},
},
},
{
Text: "six",
Plugin: plugin,
Text: "six",
Params: plugins.ItemParams{
Refresh: true,
},
},
{
Text: "seven but this will be truncated",
Plugin: plugin,
Text: "seven but this will be truncated",
Params: plugins.ItemParams{
Refresh: true,
Length: 5,
},
},
{
Text: "Template Image",
Plugin: plugin,
Text: "Template Image",
Params: plugins.ItemParams{
TemplateImage: "base64stuff",
},
},
{
Text: "Non Alternate",
Plugin: plugin,
Text: "Non Alternate",
Alternate: &plugins.Item{
Text: "Alternate",
Params: plugins.ItemParams{
Expand Down
25 changes: 15 additions & 10 deletions app/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,25 @@ type settings struct {
AutoUpdate bool `json:"autoupdate"`

Terminal struct {
AppleScriptWithVarsTemplate string `json:"appleScriptWithVarsTemplate"`
AppleScriptTemplate2 string `json:"appleScriptTemplate2"`
} `json:"terminal"`
}

func (s *settings) setDefaults() {
if s.Terminal.AppleScriptWithVarsTemplate == "" {
s.Terminal.AppleScriptWithVarsTemplate = `activate application "Terminal"
tell application "Terminal"
if not (exists window 1) then reopen
set quotedScriptName to quoted form of "{{ .Command }}"
set commandLine to {{ .Vars }} & " " & quotedScriptName
do script commandLine
end tell
`
if s.Terminal.AppleScriptTemplate2 == "" {
s.Terminal.AppleScriptTemplate2 = `
activate application "Terminal"
tell application "Terminal"
if not (exists window 1) then reopen
set quotedScriptName to quoted form of "{{ .Command }}"
{{ if .Params }}
set commandLine to {{ .Vars }} & " " & quotedScriptName & " " & {{ .Params }}
{{ else }}
set commandLine to {{ .Vars }} & " " & quotedScriptName
{{ end }}
do script commandLine
end tell
`
}
}

Expand Down
62 changes: 49 additions & 13 deletions pkg/plugins/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"os/exec"
"path/filepath"
"runtime"
"strconv"
"strings"
"syscall"
"time"
Expand Down Expand Up @@ -40,7 +41,7 @@ func (i *Item) Action() ActionFunc {
actions = append(actions, actionHref(debugf, i.Params.Href))
}
if i.Params.Shell != "" {
actions = append(actions, actionShell(debugf, i, i.Params.Shell, i.Params.ShellParams))
actions = append(actions, actionShell(debugf, i, i.Params.Shell, i.Params.ShellParams, i.Plugin.Variables))
}
if i.Params.Refresh {
shouldDelayBeforeRefresh := false
Expand Down Expand Up @@ -114,21 +115,24 @@ func actionHref(debugf DebugFunc, href string) ActionFunc {
}

// actionShell gets an ActionFunc that runs a shell command.
func actionShell(debugf DebugFunc, item *Item, command string, params []string) ActionFunc {
func actionShell(debugf DebugFunc, item *Item, command string, params, envVars []string) ActionFunc {
if item.Params.Terminal {
return actionShellTerminal(debugf, item, command, params, envVars)
}
return func(ctx context.Context) {
var commandExec string
var commandArgs []string
if item.Params.Terminal {
shell := os.Getenv("SHELL")
if shell == "" {
shell = "/bin/bash"
}
commandExec = shell
commandArgs = append([]string{command}, params...)
} else {
commandExec = command
commandArgs = params
}
// if item.Params.Terminal {
// shell := os.Getenv("SHELL")
// if shell == "" {
// shell = "/bin/bash"
// }
// commandExec = shell
// commandArgs = append([]string{command}, params...)
// } else {
commandExec = command
commandArgs = params
//}
debugf("exec: %s %s", commandExec, strings.Join(commandArgs, " "))
cmd := exec.CommandContext(context.Background(), commandExec, commandArgs...)
cmd.SysProcAttr = &syscall.SysProcAttr{
Expand All @@ -151,6 +155,38 @@ func actionShell(debugf DebugFunc, item *Item, command string, params []string)
}
}

// actionShellTerminal runs shell commands where terminal=true.
func actionShellTerminal(debugf DebugFunc, item *Item, command string, params, envVars []string) ActionFunc {
return func(ctx context.Context) {
debugf("exec: RunInTerminal...")
script := `
activate application "Terminal"
tell application "Terminal"
if not (exists window 1) then reopen
set quotedScriptName to quoted form of "{{ .Command }}"
{{ if .Params }}
set commandLine to {{ .Vars }} & " " & quotedScriptName & " " & {{ .Params }}
{{ else }}
set commandLine to {{ .Vars }} & " " & quotedScriptName
{{ end }}
do script commandLine
end tell
`
command := strconv.Quote(command)
command = command[1 : len(command)-1] // trim quotes off
for i := range params {
params[i] = strconv.Quote(params[i])
params[i] = params[i][1 : len(params[i])-1] // trim quotes off
}
paramsStr := strconv.Quote(strings.Join(params, " "))
err := item.Plugin.runInTerminal(script, command, paramsStr, envVars)
if err != nil {
debugf("exec: RunInTerminal: err=%s", err)
return
}
}
}

// actionRefresh gets an ActionFunc that manually refreshes the
// Plugin.
func actionRefresh(debugf DebugFunc, refreshFunc func(ctx context.Context)) ActionFunc {
Expand Down
18 changes: 12 additions & 6 deletions pkg/plugins/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,21 +279,21 @@ func (p *Plugin) CurrentCycleItem() *Item {
return p.Items.CycleItems[p.CycleIndex]
}

// RunInTerminal runs this plugin in a terminal using the template
// apple script.
func (p *Plugin) RunInTerminal(appleScriptWithVarsTemplate string) error {
tpl, err := template.New("appleScriptWithVarsTemplate").Parse(appleScriptWithVarsTemplate)
func (p *Plugin) runInTerminal(appleScriptTemplate2, command, paramsStr string, vars []string) error {
tpl, err := template.New("appleScriptTemplate2").Parse(appleScriptTemplate2)
if err != nil {
return err
}
commandLine := p.Command
commandLine := command
var renderedScript bytes.Buffer
err = tpl.Execute(&renderedScript, struct {
Command string
Vars string
Params string
}{
Command: commandLine,
Vars: fmt.Sprintf("%q", variablesEnvString(p.Variables)),
Vars: fmt.Sprintf("%q", variablesEnvString(vars)),
Params: paramsStr,
})
if err != nil {
return err
Expand All @@ -313,6 +313,12 @@ func (p *Plugin) RunInTerminal(appleScriptWithVarsTemplate string) error {
return nil
}

// RunInTerminal runs this plugin in a terminal using the template
// apple script.
func (p *Plugin) RunInTerminal(appleScriptTemplate2 string) error {
return p.runInTerminal(appleScriptTemplate2, p.Command, "", p.Variables)
}

// refresh runs the plugin and parses the output, updating the
// state of Plugin.
func (p *Plugin) refresh(ctx context.Context) error {
Expand Down

0 comments on commit 5bf6171

Please sign in to comment.