list.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. // License: GPLv3 Copyright: 2023, Kovid Goyal, <kovid at kovidgoyal.net>
  2. package themes
  3. import (
  4. "fmt"
  5. "kitty/tools/themes"
  6. "kitty/tools/utils"
  7. "kitty/tools/wcswidth"
  8. )
  9. var _ = fmt.Print
  10. type ThemesList struct {
  11. themes, all_themes *themes.Themes
  12. current_search string
  13. display_strings []string
  14. widths []int
  15. max_width, current_idx int
  16. }
  17. func (self *ThemesList) Len() int {
  18. if self.themes == nil {
  19. return 0
  20. }
  21. return self.themes.Len()
  22. }
  23. func (self *ThemesList) Next(delta int, allow_wrapping bool) bool {
  24. if len(self.display_strings) == 0 {
  25. return false
  26. }
  27. idx := self.current_idx + delta
  28. if !allow_wrapping && (idx < 0 || idx > self.Len()) {
  29. return false
  30. }
  31. for idx < 0 {
  32. idx += self.Len()
  33. }
  34. self.current_idx = idx % self.Len()
  35. return true
  36. }
  37. func limit_lengths(text string) string {
  38. t, _ := wcswidth.TruncateToVisualLengthWithWidth(text, 31)
  39. if len(t) >= len(text) {
  40. return text
  41. }
  42. return t + "…"
  43. }
  44. func (self *ThemesList) UpdateThemes(themes *themes.Themes) {
  45. self.themes, self.all_themes = themes, themes
  46. if self.current_search != "" {
  47. self.themes = self.all_themes.Copy()
  48. self.display_strings = utils.Map(limit_lengths, self.themes.ApplySearch(self.current_search))
  49. } else {
  50. self.display_strings = utils.Map(limit_lengths, self.themes.Names())
  51. }
  52. self.widths = utils.Map(wcswidth.Stringwidth, self.display_strings)
  53. self.max_width = utils.Max(0, self.widths...)
  54. self.current_idx = 0
  55. }
  56. func (self *ThemesList) UpdateSearch(query string) bool {
  57. if query == self.current_search || self.all_themes == nil {
  58. return false
  59. }
  60. self.current_search = query
  61. self.UpdateThemes(self.all_themes)
  62. return true
  63. }
  64. type Line struct {
  65. text string
  66. width int
  67. is_current bool
  68. }
  69. func (self *ThemesList) Lines(num_rows int) []Line {
  70. if num_rows < 1 {
  71. return nil
  72. }
  73. ans := make([]Line, 0, len(self.display_strings))
  74. before_num := utils.Min(self.current_idx, num_rows-1)
  75. start := self.current_idx - before_num
  76. for i := start; i < utils.Min(start+num_rows, len(self.display_strings)); i++ {
  77. ans = append(ans, Line{self.display_strings[i], self.widths[i], i == self.current_idx})
  78. }
  79. return ans
  80. }
  81. func (self *ThemesList) CurrentTheme() *themes.Theme {
  82. if self.themes == nil {
  83. return nil
  84. }
  85. return self.themes.At(self.current_idx)
  86. }