Compare commits

...

8 Commits

Author SHA1 Message Date
Lea Anthony
4e152bb849 v2.0.0-alpha.29 2021-02-21 05:56:11 +11:00
Lea Anthony
51133d098c Slight refactor of backend module generation 2021-02-21 05:52:42 +11:00
Lea Anthony
d4191e7d1b Support parsing keyboard shortcuts 2021-02-20 21:32:32 +11:00
Lea Anthony
9c273bc745 v2.0.0-alpha.28 2021-02-20 16:04:42 +11:00
Lea Anthony
c6f6ad6beb Improved dev reload. Early abort for bad app. Don't reload if bad build. 2021-02-20 16:04:03 +11:00
Lea Anthony
4362a14459 Dev colours 2021-02-20 15:25:40 +11:00
Lea Anthony
0080e9e311 Gimme some colour 2021-02-20 15:14:20 +11:00
Lea Anthony
83d9297cac v2.0.0-alpha.27 2021-02-20 14:51:38 +11:00
13 changed files with 376 additions and 97 deletions

View File

@@ -5,12 +5,13 @@ import (
"io" "io"
"os" "os"
"os/signal" "os/signal"
"path/filepath"
"runtime" "runtime"
"strings" "strings"
"syscall" "syscall"
"time" "time"
"github.com/pkg/errors" "github.com/wailsapp/wails/v2/internal/colour"
"github.com/fsnotify/fsnotify" "github.com/fsnotify/fsnotify"
"github.com/leaanthony/clir" "github.com/leaanthony/clir"
@@ -20,6 +21,21 @@ import (
"github.com/wailsapp/wails/v2/pkg/commands/build" "github.com/wailsapp/wails/v2/pkg/commands/build"
) )
func LogGreen(message string, args ...interface{}) {
text := fmt.Sprintf(message, args...)
println(colour.Green(text))
}
func LogRed(message string, args ...interface{}) {
text := fmt.Sprintf(message, args...)
println(colour.Red(text))
}
func LogDarkYellow(message string, args ...interface{}) {
text := fmt.Sprintf(message, args...)
println(colour.DarkYellow(text))
}
// AddSubcommand adds the `dev` command for the Wails application // AddSubcommand adds the `dev` command for the Wails application
func AddSubcommand(app *clir.Cli, w io.Writer) error { func AddSubcommand(app *clir.Cli, w io.Writer) error {
@@ -52,7 +68,6 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
defer watcher.Close() defer watcher.Close()
var debugBinaryProcess *process.Process = nil var debugBinaryProcess *process.Process = nil
var buildFrontend bool = false
var extensionsThatTriggerARebuild = strings.Split(extensions, ",") var extensionsThatTriggerARebuild = strings.Split(extensions, ",")
// Setup signal handler // Setup signal handler
@@ -63,7 +78,10 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
// Do initial build // Do initial build
logger.Println("Building application for development...") logger.Println("Building application for development...")
debugBinaryProcess, err = restartApp(logger, "dev", ldflags, compilerCommand, debugBinaryProcess) newProcess, err := restartApp(logger, "dev", ldflags, compilerCommand, debugBinaryProcess)
if newProcess != nil {
debugBinaryProcess = newProcess
}
if err != nil { if err != nil {
return err return err
} }
@@ -79,7 +97,7 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
if err != nil { if err != nil {
logger.Fatal("%s", err.Error()) logger.Fatal("%s", err.Error())
} }
logger.Println("Watching directory: %s", event.Name) LogGreen("[New Directory] Watching new directory: %s", event.Name)
} }
} }
return return
@@ -88,28 +106,22 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
// Check for file writes // Check for file writes
if event.Op&fsnotify.Write == fsnotify.Write { if event.Op&fsnotify.Write == fsnotify.Write {
logger.Println("modified file: %s", event.Name)
var rebuild bool = false var rebuild bool = false
// Iterate all file patterns // Iterate all file patterns
for _, pattern := range extensionsThatTriggerARebuild { for _, pattern := range extensionsThatTriggerARebuild {
rebuild = strings.HasSuffix(event.Name, pattern) if strings.HasSuffix(event.Name, pattern) {
if err != nil { rebuild = true
logger.Fatal(err.Error())
}
if rebuild {
// Only build frontend when the file isn't a Go file
buildFrontend = !strings.HasSuffix(event.Name, "go")
break break
} }
} }
if !rebuild { if !rebuild {
logger.Println("Filename change: %s did not match extension list (%s)", event.Name, extensions) LogDarkYellow("[File change] %s did not match extension list (%s)", event.Name, extensions)
return return
} }
logger.Println("Partial build triggered: %s updated", event.Name) LogGreen("[Attempting rebuild] %s updated", event.Name)
// Do a rebuild // Do a rebuild
@@ -128,23 +140,28 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
}) })
// Get project dir // Get project dir
dir, err := os.Getwd() projectDir, err := os.Getwd()
if err != nil { if err != nil {
return err return err
} }
// Get all subdirectories // Get all subdirectories
dirs, err := fs.GetSubdirectories(dir) dirs, err := fs.GetSubdirectories(projectDir)
if err != nil { if err != nil {
return err return err
} }
LogGreen("Watching (sub)/directory: %s", projectDir)
// Setup a watcher for non-node_modules directories // Setup a watcher for non-node_modules directories
dirs.Each(func(dir string) { dirs.Each(func(dir string) {
if strings.Contains(dir, "node_modules") { if strings.Contains(dir, "node_modules") {
return return
} }
logger.Println("Watching directory: %s", dir) // Ignore build directory
if strings.HasPrefix(dir, filepath.Join(projectDir, "build")) {
return
}
err = watcher.Add(dir) err = watcher.Add(dir)
if err != nil { if err != nil {
logger.Fatal(err.Error()) logger.Fatal(err.Error())
@@ -156,7 +173,7 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
for quit == false { for quit == false {
select { select {
case <-quitChannel: case <-quitChannel:
println("Caught quit") LogGreen("\nCaught quit")
// Notify debouncer to quit // Notify debouncer to quit
debounceQuit <- true debounceQuit <- true
quit = true quit = true
@@ -171,7 +188,7 @@ func AddSubcommand(app *clir.Cli, w io.Writer) error {
} }
} }
logger.Println("Development mode exited") LogGreen("Development mode exited")
return nil return nil
}) })
@@ -203,10 +220,10 @@ func restartApp(logger *clilogger.CLILogger, outputType string, ldflags string,
appBinary, err := buildApp(logger, outputType, ldflags, compilerCommand) appBinary, err := buildApp(logger, outputType, ldflags, compilerCommand)
println() println()
if err != nil { if err != nil {
logger.Fatal(err.Error()) LogRed("Build error - continuing to run current version")
return nil, errors.Wrap(err, "Build Failed:") LogDarkYellow(err.Error())
return nil, nil
} }
logger.Println("Build new binary: %s", appBinary)
// Kill existing binary if need be // Kill existing binary if need be
if debugBinaryProcess != nil { if debugBinaryProcess != nil {
@@ -239,7 +256,7 @@ func restartApp(logger *clilogger.CLILogger, outputType string, ldflags string,
func buildApp(logger *clilogger.CLILogger, outputType string, ldflags string, compilerCommand string) (string, error) { func buildApp(logger *clilogger.CLILogger, outputType string, ldflags string, compilerCommand string) (string, error) {
// Create random output file // Create random output file
outputFile := fmt.Sprintf("debug-%d", time.Now().Unix()) outputFile := fmt.Sprintf("dev-%d", time.Now().Unix())
// Create BuildOptions // Create BuildOptions
buildOptions := &build.Options{ buildOptions := &build.Options{

View File

@@ -1,8 +1,11 @@
package main package main
import ( import (
"fmt"
"os" "os"
"github.com/wailsapp/wails/v2/internal/colour"
"github.com/wailsapp/wails/v2/cmd/wails/internal/commands/update" "github.com/wailsapp/wails/v2/cmd/wails/internal/commands/update"
"github.com/leaanthony/clir" "github.com/leaanthony/clir"
@@ -19,12 +22,18 @@ func fatal(message string) {
os.Exit(1) os.Exit(1)
} }
func banner(_ *clir.Cli) string {
return fmt.Sprintf("%s %s - Go/HTML Application Framework", colour.Yellow("Wails"), colour.DarkRed(version))
}
func main() { func main() {
var err error var err error
app := clir.NewCli("Wails", "Go/HTML Application Framework", version) app := clir.NewCli("Wails", "Go/HTML Application Framework", version)
app.SetBannerFunction(banner)
build.AddBuildSubcommand(app, os.Stdout) build.AddBuildSubcommand(app, os.Stdout)
err = initialise.AddSubcommand(app, os.Stdout) err = initialise.AddSubcommand(app, os.Stdout)
if err != nil { if err != nil {

View File

@@ -1,3 +1,3 @@
package main package main
var version = "v2.0.0-alpha.26" var version = "v2.0.0-alpha.29"

View File

@@ -20,9 +20,9 @@ require (
github.com/tdewolff/minify v2.3.6+incompatible github.com/tdewolff/minify v2.3.6+incompatible
github.com/tdewolff/parse v2.3.4+incompatible // indirect github.com/tdewolff/parse v2.3.4+incompatible // indirect
github.com/tdewolff/test v1.0.6 // indirect github.com/tdewolff/test v1.0.6 // indirect
github.com/wzshiming/ctc v1.2.3
github.com/xyproto/xpm v1.2.1 github.com/xyproto/xpm v1.2.1
golang.org/x/net v0.0.0-20200822124328-c89045814202 golang.org/x/net v0.0.0-20200822124328-c89045814202
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a
golang.org/x/sys v0.0.0-20200724161237-0e2f3a69832c golang.org/x/sys v0.0.0-20200724161237-0e2f3a69832c
golang.org/x/tools v0.0.0-20200902012652-d1954cc86c82 golang.org/x/tools v0.0.0-20200902012652-d1954cc86c82
nhooyr.io/websocket v1.8.6 nhooyr.io/websocket v1.8.6

View File

@@ -78,6 +78,10 @@ github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/wzshiming/ctc v1.2.3 h1:q+hW3IQNsjIlOFBTGZZZeIXTElFM4grF4spW/errh/c=
github.com/wzshiming/ctc v1.2.3/go.mod h1:2tVAtIY7SUyraSk0JxvwmONNPFL4ARavPuEsg5+KA28=
github.com/wzshiming/winseq v0.0.0-20200112104235-db357dc107ae h1:tpXvBXC3hpQBDCc9OojJZCQMVRAbT3TTdUMP8WguXkY=
github.com/wzshiming/winseq v0.0.0-20200112104235-db357dc107ae/go.mod h1:VTAq37rkGeV+WOybvZwjXiJOicICdpLCN8ifpISjK20=
github.com/xyproto/xpm v1.2.1 h1:trdvGjjWBsOOKzBBUPT6JvaIQM3acJEEYfbxN7M96wg= github.com/xyproto/xpm v1.2.1 h1:trdvGjjWBsOOKzBBUPT6JvaIQM3acJEEYfbxN7M96wg=
github.com/xyproto/xpm v1.2.1/go.mod h1:cMnesLsD0PBXLgjDfTDEaKr8XyTFsnP1QycSqRw7BiY= github.com/xyproto/xpm v1.2.1/go.mod h1:cMnesLsD0PBXLgjDfTDEaKr8XyTFsnP1QycSqRw7BiY=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@@ -92,11 +96,10 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200724161237-0e2f3a69832c h1:UIcGWL6/wpCfyGuJnRFJRurA+yj8RrW7Q6x2YMCXt6c= golang.org/x/sys v0.0.0-20200724161237-0e2f3a69832c h1:UIcGWL6/wpCfyGuJnRFJRurA+yj8RrW7Q6x2YMCXt6c=

View File

@@ -58,7 +58,7 @@ const backend = {`)
sortedPackageNames.Add(packageName) sortedPackageNames.Add(packageName)
} }
sortedPackageNames.Sort() sortedPackageNames.Sort()
for _, packageName := range sortedPackageNames.AsSlice() { sortedPackageNames.Each(func(packageName string) {
packages := store[packageName] packages := store[packageName]
output.WriteString(fmt.Sprintf(" \"%s\": {", packageName)) output.WriteString(fmt.Sprintf(" \"%s\": {", packageName))
output.WriteString("\n") output.WriteString("\n")
@@ -67,7 +67,8 @@ const backend = {`)
sortedStructNames.Add(structName) sortedStructNames.Add(structName)
} }
sortedStructNames.Sort() sortedStructNames.Sort()
for _, structName := range sortedStructNames.AsSlice() {
sortedStructNames.Each(func(structName string) {
structs := packages[structName] structs := packages[structName]
output.WriteString(fmt.Sprintf(" \"%s\": {", structName)) output.WriteString(fmt.Sprintf(" \"%s\": {", structName))
output.WriteString("\n") output.WriteString("\n")
@@ -78,7 +79,7 @@ const backend = {`)
} }
sortedMethodNames.Sort() sortedMethodNames.Sort()
for _, methodName := range sortedMethodNames.AsSlice() { sortedMethodNames.Each(func(methodName string) {
methodDetails := structs[methodName] methodDetails := structs[methodName]
output.WriteString(" /**\n") output.WriteString(" /**\n")
output.WriteString(" * " + methodName + "\n") output.WriteString(" * " + methodName + "\n")
@@ -109,13 +110,16 @@ const backend = {`)
output.WriteString("\n") output.WriteString("\n")
output.WriteString(fmt.Sprintf(" },")) output.WriteString(fmt.Sprintf(" },"))
output.WriteString("\n") output.WriteString("\n")
}
})
output.WriteString(fmt.Sprintf(" }")) output.WriteString(fmt.Sprintf(" }"))
output.WriteString("\n") output.WriteString("\n")
} })
output.WriteString(fmt.Sprintf(" }\n")) output.WriteString(fmt.Sprintf(" }\n"))
output.WriteString("\n") output.WriteString("\n")
} })
output.WriteString(`}; output.WriteString(`};
export default backend;`) export default backend;`)

View File

@@ -0,0 +1,89 @@
package colour
import (
"fmt"
"strings"
"github.com/wzshiming/ctc"
)
func Col(col ctc.Color, text string) string {
return fmt.Sprintf("%s%s%s", col, text, ctc.Reset)
}
func Yellow(text string) string {
return Col(ctc.ForegroundBrightYellow, text)
}
func Red(text string) string {
return Col(ctc.ForegroundBrightRed, text)
}
func Blue(text string) string {
return Col(ctc.ForegroundBrightBlue, text)
}
func Green(text string) string {
return Col(ctc.ForegroundBrightGreen, text)
}
func Cyan(text string) string {
return Col(ctc.ForegroundBrightCyan, text)
}
func Magenta(text string) string {
return Col(ctc.ForegroundBrightMagenta, text)
}
func White(text string) string {
return Col(ctc.ForegroundBrightWhite, text)
}
func Black(text string) string {
return Col(ctc.ForegroundBrightBlack, text)
}
func DarkYellow(text string) string {
return Col(ctc.ForegroundYellow, text)
}
func DarkRed(text string) string {
return Col(ctc.ForegroundRed, text)
}
func DarkBlue(text string) string {
return Col(ctc.ForegroundBlue, text)
}
func DarkGreen(text string) string {
return Col(ctc.ForegroundGreen, text)
}
func DarkCyan(text string) string {
return Col(ctc.ForegroundCyan, text)
}
func DarkMagenta(text string) string {
return Col(ctc.ForegroundMagenta, text)
}
func DarkWhite(text string) string {
return Col(ctc.ForegroundWhite, text)
}
func DarkBlack(text string) string {
return Col(ctc.ForegroundBlack, text)
}
var rainbowCols = []func(string) string{Red, Yellow, Green, Cyan, Blue, Magenta}
func Rainbow(text string) string {
var builder strings.Builder
for i := 0; i < len(text); i++ {
fn := rainbowCols[i%len(rainbowCols)]
builder.WriteString(fn(text[i : i+1]))
}
return builder.String()
}

View File

@@ -180,151 +180,151 @@ id processAcceleratorKey(const char *key) {
return str(""); return str("");
} }
if( STREQ(key, "Backspace") ) { if( STREQ(key, "backspace") ) {
return strunicode(0x0008); return strunicode(0x0008);
} }
if( STREQ(key, "Tab") ) { if( STREQ(key, "tab") ) {
return strunicode(0x0009); return strunicode(0x0009);
} }
if( STREQ(key, "Return") ) { if( STREQ(key, "return") ) {
return strunicode(0x000d); return strunicode(0x000d);
} }
if( STREQ(key, "Escape") ) { if( STREQ(key, "escape") ) {
return strunicode(0x001b); return strunicode(0x001b);
} }
if( STREQ(key, "Left") ) { if( STREQ(key, "left") ) {
return strunicode(0x001c); return strunicode(0x001c);
} }
if( STREQ(key, "Right") ) { if( STREQ(key, "right") ) {
return strunicode(0x001d); return strunicode(0x001d);
} }
if( STREQ(key, "Up") ) { if( STREQ(key, "up") ) {
return strunicode(0x001e); return strunicode(0x001e);
} }
if( STREQ(key, "Down") ) { if( STREQ(key, "down") ) {
return strunicode(0x001f); return strunicode(0x001f);
} }
if( STREQ(key, "Space") ) { if( STREQ(key, "space") ) {
return strunicode(0x0020); return strunicode(0x0020);
} }
if( STREQ(key, "Delete") ) { if( STREQ(key, "delete") ) {
return strunicode(0x007f); return strunicode(0x007f);
} }
if( STREQ(key, "Home") ) { if( STREQ(key, "home") ) {
return strunicode(0x2196); return strunicode(0x2196);
} }
if( STREQ(key, "End") ) { if( STREQ(key, "end") ) {
return strunicode(0x2198); return strunicode(0x2198);
} }
if( STREQ(key, "Page Up") ) { if( STREQ(key, "page up") ) {
return strunicode(0x21de); return strunicode(0x21de);
} }
if( STREQ(key, "Page Down") ) { if( STREQ(key, "page down") ) {
return strunicode(0x21df); return strunicode(0x21df);
} }
if( STREQ(key, "F1") ) { if( STREQ(key, "f1") ) {
return strunicode(0xf704); return strunicode(0xf704);
} }
if( STREQ(key, "F2") ) { if( STREQ(key, "f2") ) {
return strunicode(0xf705); return strunicode(0xf705);
} }
if( STREQ(key, "F3") ) { if( STREQ(key, "f3") ) {
return strunicode(0xf706); return strunicode(0xf706);
} }
if( STREQ(key, "F4") ) { if( STREQ(key, "f4") ) {
return strunicode(0xf707); return strunicode(0xf707);
} }
if( STREQ(key, "F5") ) { if( STREQ(key, "f5") ) {
return strunicode(0xf708); return strunicode(0xf708);
} }
if( STREQ(key, "F6") ) { if( STREQ(key, "f6") ) {
return strunicode(0xf709); return strunicode(0xf709);
} }
if( STREQ(key, "F7") ) { if( STREQ(key, "f7") ) {
return strunicode(0xf70a); return strunicode(0xf70a);
} }
if( STREQ(key, "F8") ) { if( STREQ(key, "f8") ) {
return strunicode(0xf70b); return strunicode(0xf70b);
} }
if( STREQ(key, "F9") ) { if( STREQ(key, "f9") ) {
return strunicode(0xf70c); return strunicode(0xf70c);
} }
if( STREQ(key, "F10") ) { if( STREQ(key, "f10") ) {
return strunicode(0xf70d); return strunicode(0xf70d);
} }
if( STREQ(key, "F11") ) { if( STREQ(key, "f11") ) {
return strunicode(0xf70e); return strunicode(0xf70e);
} }
if( STREQ(key, "F12") ) { if( STREQ(key, "f12") ) {
return strunicode(0xf70f); return strunicode(0xf70f);
} }
if( STREQ(key, "F13") ) { if( STREQ(key, "f13") ) {
return strunicode(0xf710); return strunicode(0xf710);
} }
if( STREQ(key, "F14") ) { if( STREQ(key, "f14") ) {
return strunicode(0xf711); return strunicode(0xf711);
} }
if( STREQ(key, "F15") ) { if( STREQ(key, "f15") ) {
return strunicode(0xf712); return strunicode(0xf712);
} }
if( STREQ(key, "F16") ) { if( STREQ(key, "f16") ) {
return strunicode(0xf713); return strunicode(0xf713);
} }
if( STREQ(key, "F17") ) { if( STREQ(key, "f17") ) {
return strunicode(0xf714); return strunicode(0xf714);
} }
if( STREQ(key, "F18") ) { if( STREQ(key, "f18") ) {
return strunicode(0xf715); return strunicode(0xf715);
} }
if( STREQ(key, "F19") ) { if( STREQ(key, "f19") ) {
return strunicode(0xf716); return strunicode(0xf716);
} }
if( STREQ(key, "F20") ) { if( STREQ(key, "f20") ) {
return strunicode(0xf717); return strunicode(0xf717);
} }
if( STREQ(key, "F21") ) { if( STREQ(key, "f21") ) {
return strunicode(0xf718); return strunicode(0xf718);
} }
if( STREQ(key, "F22") ) { if( STREQ(key, "f22") ) {
return strunicode(0xf719); return strunicode(0xf719);
} }
if( STREQ(key, "F23") ) { if( STREQ(key, "f23") ) {
return strunicode(0xf71a); return strunicode(0xf71a);
} }
if( STREQ(key, "F24") ) { if( STREQ(key, "f24") ) {
return strunicode(0xf71b); return strunicode(0xf71b);
} }
if( STREQ(key, "F25") ) { if( STREQ(key, "f25") ) {
return strunicode(0xf71c); return strunicode(0xf71c);
} }
if( STREQ(key, "F26") ) { if( STREQ(key, "f26") ) {
return strunicode(0xf71d); return strunicode(0xf71d);
} }
if( STREQ(key, "F27") ) { if( STREQ(key, "f27") ) {
return strunicode(0xf71e); return strunicode(0xf71e);
} }
if( STREQ(key, "F28") ) { if( STREQ(key, "f28") ) {
return strunicode(0xf71f); return strunicode(0xf71f);
} }
if( STREQ(key, "F29") ) { if( STREQ(key, "f29") ) {
return strunicode(0xf720); return strunicode(0xf720);
} }
if( STREQ(key, "F30") ) { if( STREQ(key, "f30") ) {
return strunicode(0xf721); return strunicode(0xf721);
} }
if( STREQ(key, "F31") ) { if( STREQ(key, "f31") ) {
return strunicode(0xf722); return strunicode(0xf722);
} }
if( STREQ(key, "F32") ) { if( STREQ(key, "f32") ) {
return strunicode(0xf723); return strunicode(0xf723);
} }
if( STREQ(key, "F33") ) { if( STREQ(key, "f33") ) {
return strunicode(0xf724); return strunicode(0xf724);
} }
if( STREQ(key, "F34") ) { if( STREQ(key, "f34") ) {
return strunicode(0xf725); return strunicode(0xf725);
} }
if( STREQ(key, "F35") ) { if( STREQ(key, "f35") ) {
return strunicode(0xf726); return strunicode(0xf726);
} }
// if( STREQ(key, "Insert") ) { // if( STREQ(key, "Insert") ) {
@@ -336,7 +336,7 @@ id processAcceleratorKey(const char *key) {
// if( STREQ(key, "ScrollLock") ) { // if( STREQ(key, "ScrollLock") ) {
// return strunicode(0xf72f); // return strunicode(0xf72f);
// } // }
if( STREQ(key, "NumLock") ) { if( STREQ(key, "numLock") ) {
return strunicode(0xf739); return strunicode(0xf739);
} }
@@ -509,19 +509,19 @@ unsigned long parseModifiers(const char **modifiers) {
int count = 0; int count = 0;
while( thisModifier != NULL ) { while( thisModifier != NULL ) {
// Determine flags // Determine flags
if( STREQ(thisModifier, "CmdOrCtrl") ) { if( STREQ(thisModifier, "cmdorctrl") ) {
result |= NSEventModifierFlagCommand; result |= NSEventModifierFlagCommand;
} }
if( STREQ(thisModifier, "OptionOrAlt") ) { if( STREQ(thisModifier, "optionoralt") ) {
result |= NSEventModifierFlagOption; result |= NSEventModifierFlagOption;
} }
if( STREQ(thisModifier, "Shift") ) { if( STREQ(thisModifier, "shift") ) {
result |= NSEventModifierFlagShift; result |= NSEventModifierFlagShift;
} }
if( STREQ(thisModifier, "Super") ) { if( STREQ(thisModifier, "super") ) {
result |= NSEventModifierFlagCommand; result |= NSEventModifierFlagCommand;
} }
if( STREQ(thisModifier, "Control") ) { if( STREQ(thisModifier, "control") ) {
result |= NSEventModifierFlagControl; result |= NSEventModifierFlagControl;
} }
count++; count++;

View File

@@ -39,7 +39,12 @@ func (p *Process) Start() error {
go func(cmd *exec.Cmd, running *bool, logger *clilogger.CLILogger, exitChannel chan bool) { go func(cmd *exec.Cmd, running *bool, logger *clilogger.CLILogger, exitChannel chan bool) {
logger.Println("Starting process (PID: %d)", cmd.Process.Pid) logger.Println("Starting process (PID: %d)", cmd.Process.Pid)
cmd.Wait() err := cmd.Wait()
if err != nil {
if err.Error() != "signal: killed" {
logger.Fatal("Fatal error from app: " + err.Error())
}
}
logger.Println("Exiting process (PID: %d)", cmd.Process.Pid) logger.Println("Exiting process (PID: %d)", cmd.Process.Pid)
*running = false *running = false
exitChannel <- true exitChannel <- true

View File

@@ -4,6 +4,8 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
"github.com/wailsapp/wails/v2/internal/colour"
) )
// CLILogger is used by the cli // CLILogger is used by the cli
@@ -51,9 +53,9 @@ func (c *CLILogger) Println(message string, args ...interface{}) {
// Fatal prints the given message then aborts // Fatal prints the given message then aborts
func (c *CLILogger) Fatal(message string, args ...interface{}) { func (c *CLILogger) Fatal(message string, args ...interface{}) {
temp := fmt.Sprintf(message, args...) temp := fmt.Sprintf(message, args...)
_, err := fmt.Fprintln(c.Writer, "FATAL: "+temp) _, err := fmt.Fprintln(c.Writer, colour.Red("FATAL: "+temp))
if err != nil { if err != nil {
println("FATAL: ", err) println(colour.Red("FATAL: " + err.Error()))
} }
os.Exit(1) os.Exit(1)
} }

View File

@@ -1,5 +1,10 @@
package keys package keys
import (
"fmt"
"strings"
)
// Modifier is actually a string // Modifier is actually a string
type Modifier string type Modifier string
@@ -16,6 +21,23 @@ const (
ControlKey Modifier = "Control" ControlKey Modifier = "Control"
) )
var modifierMap = map[string]Modifier{
"cmdorctrl": CmdOrCtrlKey,
"optionoralt": OptionOrAltKey,
"shift": ShiftKey,
"super": SuperKey,
"ctrl": ControlKey,
}
func parseModifier(text string) (*Modifier, error) {
result, valid := modifierMap[text]
if !valid {
return nil, fmt.Errorf("'%s' is not a valid modifier", text)
}
return &result, nil
}
// Accelerator holds the keyboard shortcut for a menu item // Accelerator holds the keyboard shortcut for a menu item
type Accelerator struct { type Accelerator struct {
Key string Key string
@@ -25,14 +47,14 @@ type Accelerator struct {
// Key creates a standard key Accelerator // Key creates a standard key Accelerator
func Key(key string) *Accelerator { func Key(key string) *Accelerator {
return &Accelerator{ return &Accelerator{
Key: key, Key: strings.ToLower(key),
} }
} }
// CmdOrCtrl creates a 'CmdOrCtrl' Accelerator // CmdOrCtrl creates a 'CmdOrCtrl' Accelerator
func CmdOrCtrl(key string) *Accelerator { func CmdOrCtrl(key string) *Accelerator {
return &Accelerator{ return &Accelerator{
Key: key, Key: strings.ToLower(key),
Modifiers: []Modifier{CmdOrCtrlKey}, Modifiers: []Modifier{CmdOrCtrlKey},
} }
} }
@@ -40,7 +62,7 @@ func CmdOrCtrl(key string) *Accelerator {
// OptionOrAlt creates a 'OptionOrAlt' Accelerator // OptionOrAlt creates a 'OptionOrAlt' Accelerator
func OptionOrAlt(key string) *Accelerator { func OptionOrAlt(key string) *Accelerator {
return &Accelerator{ return &Accelerator{
Key: key, Key: strings.ToLower(key),
Modifiers: []Modifier{OptionOrAltKey}, Modifiers: []Modifier{OptionOrAltKey},
} }
} }
@@ -48,7 +70,7 @@ func OptionOrAlt(key string) *Accelerator {
// Shift creates a 'Shift' Accelerator // Shift creates a 'Shift' Accelerator
func Shift(key string) *Accelerator { func Shift(key string) *Accelerator {
return &Accelerator{ return &Accelerator{
Key: key, Key: strings.ToLower(key),
Modifiers: []Modifier{ShiftKey}, Modifiers: []Modifier{ShiftKey},
} }
} }
@@ -56,7 +78,7 @@ func Shift(key string) *Accelerator {
// Control creates a 'Control' Accelerator // Control creates a 'Control' Accelerator
func Control(key string) *Accelerator { func Control(key string) *Accelerator {
return &Accelerator{ return &Accelerator{
Key: key, Key: strings.ToLower(key),
Modifiers: []Modifier{ControlKey}, Modifiers: []Modifier{ControlKey},
} }
} }
@@ -64,7 +86,7 @@ func Control(key string) *Accelerator {
// Super creates a 'Super' Accelerator // Super creates a 'Super' Accelerator
func Super(key string) *Accelerator { func Super(key string) *Accelerator {
return &Accelerator{ return &Accelerator{
Key: key, Key: strings.ToLower(key),
Modifiers: []Modifier{SuperKey}, Modifiers: []Modifier{SuperKey},
} }
} }

View File

@@ -0,0 +1,90 @@
package keys
import (
"fmt"
"strconv"
"strings"
"github.com/leaanthony/slicer"
)
var namedKeys = slicer.String([]string{"backspace", "tab", "return", "escape", "left", "right", "up", "down", "space", "delete", "home", "end", "page up", "page down", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", "f32", "f33", "f34", "f35", "numlock"})
func parseKey(key string) (string, bool) {
// Lowercase!
key = strings.ToLower(key)
// Check special case
if key == "plus" {
return "+", true
}
// Handle named keys
if namedKeys.Contains(key) {
return key, true
}
// Check we only have a single character
if len(key) != 1 {
return "", false
}
runeKey := rune(key[0])
// This may be too inclusive
if strconv.IsPrint(runeKey) {
return key, true
}
return "", false
}
func Parse(shortcut string) (*Accelerator, error) {
var result Accelerator
// Split the shortcut by +
components := strings.Split(shortcut, "+")
// If we only have one it should be a key
// We require components
if len(components) == 0 {
return nil, fmt.Errorf("no components given to validateComponents")
}
// Keep track of modifiers we have processed
var modifiersProcessed slicer.StringSlicer
// Check components
for index, component := range components {
// If last component
if index == len(components)-1 {
processedkey, validKey := parseKey(component)
if !validKey {
return nil, fmt.Errorf("'%s' is not a valid key", component)
}
result.Key = processedkey
continue
}
// Not last component - needs to be modifier
lowercaseComponent := strings.ToLower(component)
thisModifier, valid := modifierMap[lowercaseComponent]
if !valid {
return nil, fmt.Errorf("'%s' is not a valid modifier", component)
}
// Needs to be unique
if modifiersProcessed.Contains(lowercaseComponent) {
return nil, fmt.Errorf("Modifier '%s' is defined twice for shortcut: %s", component, shortcut)
}
// Save this data
result.Modifiers = append(result.Modifiers, thisModifier)
modifiersProcessed.Add(lowercaseComponent)
}
return &result, nil
}

View File

@@ -0,0 +1,38 @@
package keys
import (
"testing"
"github.com/matryer/is"
)
func TestParse(t *testing.T) {
i := is.New(t)
type args struct {
Input string
Expected *Accelerator
}
gooddata := []args{
{"CmdOrCtrl+A", CmdOrCtrl("A")},
{"SHIFT+.", Shift(".")},
{"CTRL+plus", Control("+")},
{"CTRL+SHIFT+escApe", Combo("escape", ControlKey, ShiftKey)},
{";", Key(";")},
{"Super+Tab", Super("tab")},
{"OptionOrAlt+Page Down", OptionOrAlt("Page Down")},
}
for _, tt := range gooddata {
result, err := Parse(tt.Input)
i.NoErr(err)
i.Equal(result, tt.Expected)
}
baddata := []string{"CmdOrCrl+A", "SHIT+.", "CTL+plus", "CTRL+SHIF+esApe", "escap", "Sper+Tab", "OptionOrAlt"}
for _, d := range baddata {
result, err := Parse(d)
i.True(err != nil)
i.Equal(result, "")
}
}