Streamline JXA.

This commit is contained in:
Nuno Cruces 2021-02-19 17:46:47 +00:00
parent 6c0e609037
commit 3296597158
10 changed files with 160 additions and 236 deletions

View file

@ -10,17 +10,17 @@ import (
func selectFile(options []Option) (string, error) {
opts := applyOptions(options)
data := zenutil.File{
Prompt: opts.title,
Invisibles: opts.showHidden,
}
var data zenutil.File
data.Options.Prompt = opts.title
data.Options.Invisibles = opts.showHidden
data.Options.Location, _ = splitDirAndName(opts.filename)
if opts.directory {
data.Operation = "chooseFolder"
} else {
data.Operation = "chooseFile"
data.Type = initFilters(opts.fileFilters)
data.Options.Type = initFilters(opts.fileFilters)
}
data.Location, _ = splitDirAndName(opts.filename)
out, err := zenutil.Run(opts.ctx, "file", data)
if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 {
@ -38,19 +38,19 @@ func selectFile(options []Option) (string, error) {
func selectFileMutiple(options []Option) ([]string, error) {
opts := applyOptions(options)
data := zenutil.File{
Prompt: opts.title,
Invisibles: opts.showHidden,
Separator: zenutil.Separator,
Multiple: true,
}
var data zenutil.File
data.Options.Prompt = opts.title
data.Options.Invisibles = opts.showHidden
data.Options.Location, _ = splitDirAndName(opts.filename)
data.Options.Multiple = true
data.Separator = zenutil.Separator
if opts.directory {
data.Operation = "chooseFolder"
} else {
data.Operation = "chooseFile"
data.Type = initFilters(opts.fileFilters)
data.Options.Type = initFilters(opts.fileFilters)
}
data.Location, _ = splitDirAndName(opts.filename)
out, err := zenutil.Run(opts.ctx, "file", data)
if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 {
@ -71,16 +71,16 @@ func selectFileMutiple(options []Option) ([]string, error) {
func selectFileSave(options []Option) (string, error) {
opts := applyOptions(options)
data := zenutil.File{
Prompt: opts.title,
Invisibles: opts.showHidden,
}
var data zenutil.File
data.Options.Prompt = opts.title
data.Options.Invisibles = opts.showHidden
data.Options.Location, data.Options.Name = splitDirAndName(opts.filename)
if opts.directory {
data.Operation = "chooseFolder"
} else {
data.Operation = "chooseFileName"
}
data.Location, data.Name = splitDirAndName(opts.filename)
out, err := zenutil.Run(opts.ctx, "file", data)
if err, ok := err.(*exec.ExitError); ok && err.ExitCode() == 1 {

View file

@ -11,93 +11,30 @@ var scripts = template.Must(template.New("").Funcs(template.FuncMap{"json": func
return string(b), err
}}).Parse(`
{{define "color" -}}
var app = Application.currentApplication()
app.includeStandardAdditions = true
var app=Application.currentApplication()
app.includeStandardAdditions=true
app.activate()
var opts = {}
opts.defaultColor = {{json .}}
var res = app.chooseColor(opts)
'rgb(' + res.map(x => Math.round(x * 255)) + ')'
var res=app.chooseColor({defaultColor:{{json .}}})
{"rgb("+res.map(x=>Math.round(x*255))+")"}
{{- end}}
{{define "file" -}}
var app = Application.currentApplication()
app.includeStandardAdditions = true
var app=Application.currentApplication()
app.includeStandardAdditions=true
app.activate()
var opts = {}
{{if .Prompt -}}
opts.withPrompt = {{json .Prompt}}
{{end -}}
{{if .Type -}}
opts.ofType = {{json .Type}}
{{end -}}
{{if .Name -}}
opts.defaultName = {{json .Name}}
{{end -}}
{{if .Location -}}
opts.defaultLocation = {{json .Location}}
{{end -}}
{{if .Invisibles -}}
opts.invisibles = {{json .Invisibles}}
{{end -}}
{{if .Multiple -}}
opts.multipleSelectionsAllowed = {{json .Multiple}}
{{end -}}
var res = app[{{json .Operation}}](opts)
if (Array.isArray(res)) {
res.join({{json .Separator}})
} else {
res.toString()
}
var res=app[{{json .Operation}}]({{json .Options}})
if(Array.isArray(res)){res.join({{json .Separator}})}else{res.toString()}
{{- end}}
{{define "msg" -}}
var app = Application.currentApplication()
app.includeStandardAdditions = true
var app=Application.currentApplication()
app.includeStandardAdditions=true
app.activate()
var opts = {}
{{if .Message -}}
opts.message = {{json .Message}}
{{end -}}
{{if .As -}}
opts.as = {{json .As}}
{{end -}}
{{if .Title -}}
opts.withTitle = {{json .Title}}
{{end -}}
{{if .Icon -}}
opts.withIcon = {{json .Icon}}
{{end -}}
{{if .Buttons -}}
opts.buttons = {{json .Buttons}}
{{end -}}
{{if .Cancel -}}
opts.cancelButton = {{json .Cancel}}
{{end -}}
{{if .Default -}}
opts.defaultButton = {{json .Default}}
{{end -}}
{{if .Timeout -}}
opts.givingUpAfter = {{json .Timeout}}
{{end -}}
var res = app[{{json .Operation}}]({{json .Text}}, opts)
if (res.gaveUp) {
ObjC.import("stdlib")
$.exit(5)
}
if (res.buttonReturned === {{json .Extra}}) {
res
} else {
void 0
}
var res=app[{{json .Operation}}]({{json .Text}},{{json .Options}})
if(res.gaveUp){ObjC.import("stdlib")
$.exit(5)}
if(res.buttonReturned==={{json .Extra}}){res}else{void 0}
{{- end}}
{{define "notify" -}}
var app = Application.currentApplication()
app.includeStandardAdditions = true
var opts = {}
{{if .Title -}}
opts.withTitle = {{json .Title}}
{{end -}}
{{if .Subtitle -}}
opts.subtitle = {{json .Subtitle}}
{{end -}}
void app.displayNotification({{json .Text}}, opts)
var app=Application.currentApplication()
app.includeStandardAdditions=true
void app.displayNotification({{json .Text}},{{json .Options}})
{{- end}}`))

View file

@ -3,13 +3,15 @@
package main
import (
"bufio"
"bytes"
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"
"text/template"
"github.com/dchest/jsmin"
)
func main() {
@ -29,27 +31,17 @@ func main() {
str.WriteString(strings.TrimSuffix(name, filepath.Ext(name)))
str.WriteString(`" -}}` + "\n")
func() {
in, err := os.Open(filepath.Join(dir, name))
if err != nil {
log.Fatal(err)
}
defer in.Close()
data, err := ioutil.ReadFile(filepath.Join(dir, name))
if err != nil {
log.Fatal(err)
}
data, err = minify(data)
if err != nil {
log.Fatal(err)
}
scanner := bufio.NewScanner(in)
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
if line != "" {
str.WriteString(line)
str.WriteRune('\n')
}
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
}()
str.WriteString("{{- end}}")
str.Write(data)
str.WriteString("\n{{- end}}")
}
out, err := os.Create("osa_generated.go")
@ -68,6 +60,41 @@ func main() {
}
}
func minify(data []byte) ([]byte, error) {
var templates [][]byte
var buf []byte
for {
i := bytes.Index(data, []byte("{{"))
if i < 0 {
break
}
j := bytes.Index(data[i+len("{{"):], []byte("}}"))
if j < 0 {
break
}
templates = append(templates, data[i:i+j+len("{{}}")])
buf = append(buf, data[:i]...)
buf = append(buf, []byte("TEMPLATE")...)
data = data[i+j+len("{{}}"):]
}
buf = append(buf, data...)
buf, err := jsmin.Minify(buf)
if err != nil {
return nil, err
}
var res []byte
for _, t := range templates {
i := bytes.Index(buf, []byte("TEMPLATE"))
res = append(res, buf[:i]...)
res = append(res, t...)
buf = buf[i+len("TEMPLATE"):]
}
return append(res, buf...), nil
}
var generator = template.Must(template.New("").Parse(`// Code generated by zenity; DO NOT EDIT.
// +build darwin

View file

@ -2,8 +2,5 @@ var app = Application.currentApplication()
app.includeStandardAdditions = true
app.activate()
var opts = {}
opts.defaultColor = {{json .}}
var res = app.chooseColor(opts)
'rgb(' + res.map(x => Math.round(x * 255)) + ')'
var res = app.chooseColor({defaultColor: {{json .}}})
{"rgb(" + res.map(x => Math.round(x * 255)) + ")"}

View file

@ -2,28 +2,7 @@ var app = Application.currentApplication()
app.includeStandardAdditions = true
app.activate()
var opts = {}
{{if .Prompt -}}
opts.withPrompt = {{json .Prompt}}
{{end -}}
{{if .Type -}}
opts.ofType = {{json .Type}}
{{end -}}
{{if .Name -}}
opts.defaultName = {{json .Name}}
{{end -}}
{{if .Location -}}
opts.defaultLocation = {{json .Location}}
{{end -}}
{{if .Invisibles -}}
opts.invisibles = {{json .Invisibles}}
{{end -}}
{{if .Multiple -}}
opts.multipleSelectionsAllowed = {{json .Multiple}}
{{end -}}
var res = app[{{json .Operation}}](opts)
var res = app[{{json .Operation}}]({{json .Options}})
if (Array.isArray(res)) {
res.join({{json .Separator}})
} else {

View file

@ -2,34 +2,7 @@ var app = Application.currentApplication()
app.includeStandardAdditions = true
app.activate()
var opts = {}
{{if .Message -}}
opts.message = {{json .Message}}
{{end -}}
{{if .As -}}
opts.as = {{json .As}}
{{end -}}
{{if .Title -}}
opts.withTitle = {{json .Title}}
{{end -}}
{{if .Icon -}}
opts.withIcon = {{json .Icon}}
{{end -}}
{{if .Buttons -}}
opts.buttons = {{json .Buttons}}
{{end -}}
{{if .Cancel -}}
opts.cancelButton = {{json .Cancel}}
{{end -}}
{{if .Default -}}
opts.defaultButton = {{json .Default}}
{{end -}}
{{if .Timeout -}}
opts.givingUpAfter = {{json .Timeout}}
{{end -}}
var res = app[{{json .Operation}}]({{json .Text}}, opts)
var res = app[{{json .Operation}}]({{json .Text}}, {{json .Options}})
if (res.gaveUp) {
ObjC.import("stdlib")
$.exit(5)

View file

@ -1,13 +1,4 @@
var app = Application.currentApplication()
app.includeStandardAdditions = true
var opts = {}
{{if .Title -}}
opts.withTitle = {{json .Title}}
{{end -}}
{{if .Subtitle -}}
opts.subtitle = {{json .Subtitle}}
{{end -}}
void app.displayNotification({{json .Text}}, opts)
void app.displayNotification({{json .Text}}, {{json .Options}})

View file

@ -40,33 +40,51 @@ func Run(ctx context.Context, script string, data interface{}) ([]byte, error) {
return cmd.Output()
}
// File is internal.
type File struct {
Operation string
Prompt string
Name string
Location string
Separator string
Type []string
Invisibles bool
Multiple bool
Operation string
Separator string
Options FileOptions
}
// FileOptions is internal.
type FileOptions struct {
Prompt string `json:"withPrompt,omitempty"`
Type []string `json:"ofType,omitempty"`
Name string `json:"defaultName,omitempty"`
Location string `json:"defaultLocation,omitempty"`
Multiple bool `json:"multipleSelectionsAllowed,omitempty"`
Invisibles bool `json:"invisibles,omitempty"`
}
// Msg is internal.
type Msg struct {
Operation string
Text string
Message string
As string
Title string
Icon string
Extra string
Buttons []string
Cancel int
Default int
Timeout int
Options MsgOptions
}
type Notify struct {
Text string
Title string
Subtitle string
// MsgOptions is internal.
type MsgOptions struct {
Message string `json:"message,omitempty"`
As string `json:"as,omitempty"`
Title string `json:"withTitle,omitempty"`
Icon string `json:"withIcon,omitempty"`
Buttons []string `json:"buttons,omitempty"`
Cancel int `json:"cancelButton,omitempty"`
Default int `json:"defaultButton,omitempty"`
Timeout int `json:"givingUpAfter,omitempty"`
}
// Notify is internal.
type Notify struct {
Text string
Options NotifyOptions
}
// NotifyOptions is internal.
type NotifyOptions struct {
Title string `json:"withTitle,omitempty"`
Subtitle string `json:"subtitle,omitempty"`
}

View file

@ -8,38 +8,39 @@ import (
func message(kind messageKind, text string, options []Option) (bool, error) {
opts := applyOptions(options)
data := zenutil.Msg{
Text: text,
Timeout: zenutil.Timeout,
}
var data zenutil.Msg
data.Text = text
data.Options.Timeout = zenutil.Timeout
dialog := kind == questionKind || opts.icon != 0
if dialog {
data.Operation = "displayDialog"
data.Title = opts.title
data.Options.Title = opts.title
switch opts.icon {
case ErrorIcon:
data.Icon = "stop"
data.Options.Icon = "stop"
case WarningIcon:
data.Icon = "caution"
data.Options.Icon = "caution"
case InfoIcon, QuestionIcon:
data.Icon = "note"
data.Options.Icon = "note"
}
} else {
data.Operation = "displayAlert"
if opts.title != "" {
data.Message = text
data.Options.Message = text
data.Text = opts.title
}
switch kind {
case infoKind:
data.As = "informational"
data.Options.As = "informational"
case warningKind:
data.As = "warning"
data.Options.As = "warning"
case errorKind:
data.As = "critical"
data.Options.As = "critical"
}
}
@ -58,31 +59,31 @@ func message(kind messageKind, text string, options []Option) (bool, error) {
}
if kind == questionKind {
if opts.extraButton == "" {
data.Buttons = []string{opts.cancelLabel, opts.okLabel}
data.Default = 2
data.Cancel = 1
data.Options.Buttons = []string{opts.cancelLabel, opts.okLabel}
data.Options.Default = 2
data.Options.Cancel = 1
} else {
data.Buttons = []string{opts.extraButton, opts.cancelLabel, opts.okLabel}
data.Default = 3
data.Cancel = 2
data.Options.Buttons = []string{opts.extraButton, opts.cancelLabel, opts.okLabel}
data.Options.Default = 3
data.Options.Cancel = 2
}
} else {
if opts.extraButton == "" {
data.Buttons = []string{opts.okLabel}
data.Default = 1
data.Options.Buttons = []string{opts.okLabel}
data.Options.Default = 1
} else {
data.Buttons = []string{opts.extraButton, opts.okLabel}
data.Default = 2
data.Options.Buttons = []string{opts.extraButton, opts.okLabel}
data.Options.Default = 2
}
}
data.Extra = opts.extraButton
}
if opts.defaultCancel {
if data.Cancel != 0 {
data.Default = data.Cancel
if data.Options.Cancel != 0 {
data.Options.Default = data.Options.Cancel
}
if dialog && data.Buttons == nil {
data.Default = 1
if dialog && data.Options.Buttons == nil {
data.Options.Default = 1
}
}

View file

@ -8,12 +8,13 @@ import (
func notify(text string, options []Option) error {
opts := applyOptions(options)
data := zenutil.Notify{
Text: text,
Title: opts.title,
}
var data zenutil.Notify
data.Text = text
data.Options.Title = opts.title
if i := strings.IndexByte(text, '\n'); i >= 0 && i < len(text) {
data.Subtitle = text[:i]
data.Options.Subtitle = text[:i]
data.Text = text[i+1:]
}
_, err := zenutil.Run(opts.ctx, "notify", data)