main.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. // License: GPLv3 Copyright: 2023, Kovid Goyal, <kovid at kovidgoyal.net>
  2. package themes
  3. import (
  4. "encoding/json"
  5. "fmt"
  6. "io"
  7. "os"
  8. "path/filepath"
  9. "strings"
  10. "time"
  11. "kitty/tools/cli"
  12. "kitty/tools/themes"
  13. "kitty/tools/tui/loop"
  14. "kitty/tools/utils"
  15. )
  16. var _ = fmt.Print
  17. func complete_themes(completions *cli.Completions, word string, arg_num int) {
  18. themes.CompleteThemes(completions, word, arg_num)
  19. }
  20. func non_interactive(opts *Options, theme_name string) (rc int, err error) {
  21. themes, closer, err := themes.LoadThemes(time.Duration(opts.CacheAge * float64(time.Hour*24)))
  22. if err != nil {
  23. return 1, err
  24. }
  25. defer closer.Close()
  26. theme := themes.ThemeByName(theme_name)
  27. if theme == nil {
  28. theme_name = strings.ReplaceAll(theme_name, `\`, ``)
  29. theme = themes.ThemeByName(theme_name)
  30. if theme == nil {
  31. return 1, fmt.Errorf("No theme named: %s", theme_name)
  32. }
  33. }
  34. if opts.DumpTheme {
  35. code, err := theme.Code()
  36. if err != nil {
  37. return 1, err
  38. }
  39. fmt.Println(code)
  40. } else {
  41. err = theme.SaveInConf(utils.ConfigDir(), opts.ReloadIn, opts.ConfigFileName)
  42. if err != nil {
  43. return 1, err
  44. }
  45. }
  46. return
  47. }
  48. func main(_ *cli.Command, opts *Options, args []string) (rc int, err error) {
  49. if len(args) > 1 {
  50. args = []string{strings.Join(args, ` `)}
  51. }
  52. if len(args) == 1 {
  53. return non_interactive(opts, args[0])
  54. }
  55. lp, err := loop.New()
  56. if err != nil {
  57. return 1, err
  58. }
  59. cv := utils.NewCachedValues("unicode-input", &CachedData{Category: "All"})
  60. h := &handler{lp: lp, opts: opts, cached_data: cv.Load()}
  61. defer cv.Save()
  62. lp.OnInitialize = func() (string, error) {
  63. lp.AllowLineWrapping(false)
  64. lp.SetWindowTitle(`Choose a theme for kitty`)
  65. h.initialize()
  66. return "", nil
  67. }
  68. lp.OnWakeup = h.on_wakeup
  69. lp.OnFinalize = func() string {
  70. h.finalize()
  71. lp.SetCursorVisible(true)
  72. return ``
  73. }
  74. lp.OnResize = func(_, _ loop.ScreenSize) error {
  75. h.draw_screen()
  76. return nil
  77. }
  78. lp.OnKeyEvent = h.on_key_event
  79. lp.OnText = h.on_text
  80. err = lp.Run()
  81. if err != nil {
  82. return 1, err
  83. }
  84. ds := lp.DeathSignalName()
  85. if ds != "" {
  86. fmt.Println("Killed by signal: ", ds)
  87. lp.KillIfSignalled()
  88. return 1, nil
  89. }
  90. return
  91. }
  92. func EntryPoint(parent *cli.Command) {
  93. create_cmd(parent, main)
  94. }
  95. func parse_theme_metadata() error {
  96. raw, err := io.ReadAll(os.Stdin)
  97. if err != nil {
  98. return err
  99. }
  100. paths := utils.Splitlines(utils.UnsafeBytesToString(raw))
  101. ans := make([]*themes.ThemeMetadata, 0, len(paths))
  102. for _, path := range paths {
  103. if path != "" {
  104. metadata, _, err := themes.ParseThemeMetadata(path)
  105. if err != nil {
  106. return err
  107. }
  108. if metadata.Name == "" {
  109. metadata.Name = themes.ThemeNameFromFileName(filepath.Base(path))
  110. }
  111. ans = append(ans, metadata)
  112. }
  113. }
  114. raw, err = json.Marshal(ans)
  115. if err != nil {
  116. return err
  117. }
  118. _, err = os.Stdout.Write(raw)
  119. if err != nil {
  120. return err
  121. }
  122. return nil
  123. }
  124. func ParseEntryPoint(parent *cli.Command) {
  125. parent.AddSubCommand(&cli.Command{
  126. Name: "__parse_theme_metadata__",
  127. Hidden: true,
  128. Run: func(cmd *cli.Command, args []string) (rc int, err error) {
  129. err = parse_theme_metadata()
  130. if err != nil {
  131. rc = 1
  132. }
  133. return
  134. },
  135. })
  136. }