erm/app/darktile/cmd/root.go

148 lines
3.9 KiB
Go
Raw Normal View History

2021-07-30 22:29:20 +00:00
package cmd
import (
2023-01-16 02:55:18 +00:00
"context"
2021-07-30 22:29:20 +00:00
"errors"
"fmt"
"image"
2021-07-30 22:29:20 +00:00
"os"
"time"
2023-01-16 02:55:18 +00:00
2023-01-16 02:11:07 +00:00
config2 "tuxpa.in/t/erm/app/darktile/config"
gui2 "tuxpa.in/t/erm/app/darktile/gui"
"tuxpa.in/t/erm/app/darktile/hinters"
termutil2 "tuxpa.in/t/erm/app/darktile/termutil"
"tuxpa.in/t/erm/app/darktile/version"
2021-07-30 22:29:20 +00:00
)
2023-01-16 02:55:18 +00:00
type Context struct {
context.Context
}
2021-07-30 22:29:20 +00:00
2023-01-16 02:55:18 +00:00
type Root struct {
2023-01-16 06:03:38 +00:00
Term Term `cmd:"" aliases:"t" default:"1" help:"launch term"`
ListFonts ListFonts `cmd:"" aliases:"lf" name:"list-fonts" help:"list fonts"`
2023-01-16 02:55:18 +00:00
}
2021-07-30 22:29:20 +00:00
2023-01-16 02:55:18 +00:00
type Term struct {
2023-01-16 06:03:38 +00:00
ShowVersion bool `name:"version" help:"Show erm version information and exit"`
RewriteConfig bool `name:"rewrite-config" help:"Write the resultant config after parsing config files and merging with defauls back to the config file"`
LogFile string `name:"log-file" help:"Debug log file"`
Shell string `name:"shell" short:"s" help:"Shell to launch terminal with - defaults to configured user shell"`
Command string `name:"command" short:"c" help:"Command to run when shell starts - use this with caution"`
ScreenshotAfterMs int `name:"screenshot-after-ms" help:"Take a screenshot after this many milliseconds"`
ScreenshotFilename string `name:"screenshot-filename" help:"Filename to store screenshot taken by --screenshot-after-ms"`
ThemePath string `name:"theme-path" help:"Path to a theme file to use instead of the default"`
2023-01-16 02:55:18 +00:00
}
2021-07-30 22:29:20 +00:00
2023-01-16 02:55:18 +00:00
func (r *Term) Run(ctx *Context) error {
if r.ShowVersion {
fmt.Println(version.Version)
os.Exit(0)
}
2021-07-30 22:29:20 +00:00
2023-01-16 02:55:18 +00:00
var startupErrors []error
var fileNotFound *config2.ErrorFileNotFound
2021-07-30 22:29:20 +00:00
2023-01-16 02:55:18 +00:00
conf, err := config2.LoadConfig()
if err != nil {
if !errors.As(err, &fileNotFound) {
startupErrors = append(startupErrors, err)
2021-07-30 22:29:20 +00:00
}
2023-01-16 02:55:18 +00:00
conf = config2.DefaultConfig()
}
2021-07-30 22:29:20 +00:00
2023-01-16 02:55:18 +00:00
if r.RewriteConfig {
if _, err := conf.Save(); err != nil {
return fmt.Errorf("failed to write config file: %w", err)
2021-07-30 22:29:20 +00:00
}
2023-01-16 02:55:18 +00:00
fmt.Println("Config written.")
return nil
}
2021-07-30 22:29:20 +00:00
2023-01-16 02:55:18 +00:00
var theme *termutil2.Theme
2021-07-30 22:29:20 +00:00
2023-01-16 02:55:18 +00:00
if r.ThemePath != "" {
theme, err = config2.LoadThemeFromPath(conf, r.ThemePath)
if err != nil {
return fmt.Errorf("failed to load theme: %s", err)
}
2023-01-16 02:55:18 +00:00
} else {
theme, err = config2.LoadTheme(conf)
if err != nil {
if !errors.As(err, &fileNotFound) {
startupErrors = append(startupErrors, err)
2023-01-16 02:55:18 +00:00
}
theme, err = config2.DefaultTheme(conf)
if err != nil {
return fmt.Errorf("failed to load default theme: %w", err)
}
2021-07-30 22:29:20 +00:00
}
2023-01-16 02:55:18 +00:00
}
2021-07-30 22:29:20 +00:00
2023-01-16 02:55:18 +00:00
termOpts := []termutil2.Option{
termutil2.WithTheme(theme),
}
2021-07-30 22:29:20 +00:00
2023-01-16 02:55:18 +00:00
if r.LogFile != "" {
termOpts = append(termOpts, termutil2.WithLogFile(r.LogFile))
}
if r.Shell != "" {
termOpts = append(termOpts, termutil2.WithShell(r.Shell))
}
if r.Command != "" {
termOpts = append(termOpts, termutil2.WithInitialCommand(r.Command))
}
2021-07-30 22:29:20 +00:00
2023-01-16 02:55:18 +00:00
terminal := termutil2.New(termOpts...)
options := []gui2.Option{
gui2.WithFontDPI(conf.Font.DPI),
gui2.WithFontSize(conf.Font.Size),
gui2.WithFontFamily(conf.Font.Family),
gui2.WithOpacity(conf.Opacity),
gui2.WithLigatures(conf.Font.Ligatures),
}
if conf.Cursor.Image != "" {
img, err := getImageFromFilePath(conf.Cursor.Image)
2021-07-30 22:29:20 +00:00
if err != nil {
2023-01-16 02:55:18 +00:00
startupErrors = append(startupErrors, err)
} else {
options = append(options, gui2.WithCursorImage(img))
2021-07-30 22:29:20 +00:00
}
2023-01-16 02:55:18 +00:00
}
2021-07-30 22:29:20 +00:00
2023-01-16 02:55:18 +00:00
if r.ScreenshotAfterMs > 0 {
options = append(options, gui2.WithStartupFunc(func(g *gui2.GUI) {
<-time.After(time.Duration(r.ScreenshotAfterMs) * time.Millisecond)
g.RequestScreenshot(r.ScreenshotFilename)
}))
}
2021-07-30 22:29:20 +00:00
2023-01-16 02:55:18 +00:00
// load all hinters
for _, hinter := range hinters.All() {
options = append(options, gui2.WithHinter(hinter))
}
2021-07-30 22:29:20 +00:00
2023-01-16 02:55:18 +00:00
g, err := gui2.New(terminal, options...)
if err != nil {
2023-01-16 02:55:18 +00:00
return err
}
for _, err := range startupErrors {
g.ShowError(err.Error())
}
2023-01-16 02:55:18 +00:00
return g.Run()
2021-07-30 22:29:20 +00:00
}
2023-01-16 06:03:38 +00:00
func getImageFromFilePath(filePath string) (image.Image, error) {
f, err := os.Open(filePath)
if err != nil {
return nil, err
}
defer f.Close()
image, _, err := image.Decode(f)
return image, err
}