Finish port of themes kitten to Go
This commit is contained in:
parent
0c20a4d980
commit
0805330b77
@ -6,11 +6,13 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"kitty/tools/themes"
|
"kitty/tools/themes"
|
||||||
|
"kitty/tools/tty"
|
||||||
"kitty/tools/utils"
|
"kitty/tools/utils"
|
||||||
"kitty/tools/wcswidth"
|
"kitty/tools/wcswidth"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = fmt.Print
|
var _ = fmt.Print
|
||||||
|
var DebugPrintln = tty.DebugPrintln
|
||||||
|
|
||||||
type ThemesList struct {
|
type ThemesList struct {
|
||||||
themes, all_themes *themes.Themes
|
themes, all_themes *themes.Themes
|
||||||
|
|||||||
@ -79,6 +79,7 @@ func main(_ *cli.Command, opts *Options, args []string) (rc int, err error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
lp.OnKeyEvent = h.on_key_event
|
lp.OnKeyEvent = h.on_key_event
|
||||||
|
lp.OnText = h.on_text
|
||||||
err = lp.Run()
|
err = lp.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 1, err
|
return 1, err
|
||||||
|
|||||||
@ -84,8 +84,8 @@ func (self *handler) fetch_themes() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *handler) on_fetching_key_event(ev *loop.KeyEvent) error {
|
func (self *handler) on_fetching_key_event(ev *loop.KeyEvent) error {
|
||||||
if ev.MatchesRelease("esc") {
|
if ev.MatchesPressOrRepeat("esc") {
|
||||||
self.lp.Quit(0)
|
self.quit_on_next_key_release = 0
|
||||||
ev.Handled = true
|
ev.Handled = true
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -120,7 +120,7 @@ func (self *handler) finalize() {
|
|||||||
func (self *handler) initialize() {
|
func (self *handler) initialize() {
|
||||||
self.quit_on_next_key_release = -1
|
self.quit_on_next_key_release = -1
|
||||||
self.tabs = strings.Split("all dark light recent user", " ")
|
self.tabs = strings.Split("all dark light recent user", " ")
|
||||||
self.rl = readline.New(self.lp, readline.RlInit{DontMarkPrompts: true, Prompt: "/ "})
|
self.rl = readline.New(self.lp, readline.RlInit{DontMarkPrompts: true, Prompt: "/"})
|
||||||
self.themes_list = &ThemesList{}
|
self.themes_list = &ThemesList{}
|
||||||
self.fetch_result = make(chan fetch_data)
|
self.fetch_result = make(chan fetch_data)
|
||||||
self.category_filters = make(map[string]func(*themes.Theme) bool, len(category_filters)+1)
|
self.category_filters = make(map[string]func(*themes.Theme) bool, len(category_filters)+1)
|
||||||
@ -238,13 +238,13 @@ func (self *handler) next(delta int, allow_wrapping bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *handler) on_browsing_key_event(ev *loop.KeyEvent) error {
|
func (self *handler) on_browsing_key_event(ev *loop.KeyEvent) error {
|
||||||
if ev.MatchesRelease("esc") || ev.MatchesRelease("q") {
|
if ev.MatchesPressOrRepeat("esc") || ev.MatchesPressOrRepeat("q") {
|
||||||
self.lp.Quit(0)
|
self.quit_on_next_key_release = 0
|
||||||
ev.Handled = true
|
ev.Handled = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
for _, cat := range self.tabs {
|
for _, cat := range self.tabs {
|
||||||
if ev.MatchesRelease(cat[0:1]) || ev.MatchesRelease("alt+"+cat[0:1]) {
|
if ev.MatchesPressOrRepeat(cat[0:1]) || ev.MatchesPressOrRepeat("alt+"+cat[0:1]) {
|
||||||
ev.Handled = true
|
ev.Handled = true
|
||||||
if cat != self.current_category() {
|
if cat != self.current_category() {
|
||||||
self.set_current_category(cat)
|
self.set_current_category(cat)
|
||||||
@ -253,27 +253,27 @@ func (self *handler) on_browsing_key_event(ev *loop.KeyEvent) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ev.MatchesRelease("left") || ev.MatchesRelease("shift+tab") {
|
if ev.MatchesPressOrRepeat("left") || ev.MatchesPressOrRepeat("shift+tab") {
|
||||||
self.next_category(-1)
|
self.next_category(-1)
|
||||||
ev.Handled = true
|
ev.Handled = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if ev.MatchesRelease("right") || ev.MatchesRelease("tab") {
|
if ev.MatchesPressOrRepeat("right") || ev.MatchesPressOrRepeat("tab") {
|
||||||
self.next_category(1)
|
self.next_category(1)
|
||||||
ev.Handled = true
|
ev.Handled = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if ev.MatchesRelease("j") || ev.MatchesRelease("down") {
|
if ev.MatchesPressOrRepeat("j") || ev.MatchesPressOrRepeat("down") {
|
||||||
self.next(1, true)
|
self.next(1, true)
|
||||||
ev.Handled = true
|
ev.Handled = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if ev.MatchesRelease("k") || ev.MatchesRelease("up") {
|
if ev.MatchesPressOrRepeat("k") || ev.MatchesPressOrRepeat("up") {
|
||||||
self.next(-1, true)
|
self.next(-1, true)
|
||||||
ev.Handled = true
|
ev.Handled = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if ev.MatchesRelease("page_down") {
|
if ev.MatchesPressOrRepeat("page_down") {
|
||||||
ev.Handled = true
|
ev.Handled = true
|
||||||
sz, err := self.lp.ScreenSize()
|
sz, err := self.lp.ScreenSize()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -281,7 +281,7 @@ func (self *handler) on_browsing_key_event(ev *loop.KeyEvent) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if ev.MatchesRelease("page_up") {
|
if ev.MatchesPressOrRepeat("page_up") {
|
||||||
ev.Handled = true
|
ev.Handled = true
|
||||||
sz, err := self.lp.ScreenSize()
|
sz, err := self.lp.ScreenSize()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -289,11 +289,20 @@ func (self *handler) on_browsing_key_event(ev *loop.KeyEvent) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if ev.MatchesRelease("s") || ev.MatchesRelease("/") {
|
if ev.MatchesPressOrRepeat("s") || ev.MatchesPressOrRepeat("/") {
|
||||||
ev.Handled = true
|
ev.Handled = true
|
||||||
self.start_search()
|
self.start_search()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
if ev.MatchesPressOrRepeat("c") || ev.MatchesPressOrRepeat("enter") {
|
||||||
|
ev.Handled = true
|
||||||
|
if self.themes_list == nil || self.themes_list.Len() == 0 {
|
||||||
|
self.lp.Beep()
|
||||||
|
} else {
|
||||||
|
self.state = ACCEPTING
|
||||||
|
self.draw_screen()
|
||||||
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,21 +320,19 @@ func (self *handler) draw_browsing_screen() {
|
|||||||
}
|
}
|
||||||
num_rows := int(sz.HeightCells) - 2
|
num_rows := int(sz.HeightCells) - 2
|
||||||
mw := self.themes_list.max_width + 1
|
mw := self.themes_list.max_width + 1
|
||||||
|
green_fg, _, _ := strings.Cut(self.lp.SprintStyled("fg=green", "|"), "|")
|
||||||
for _, l := range self.themes_list.Lines(num_rows) {
|
for _, l := range self.themes_list.Lines(num_rows) {
|
||||||
num_rows--
|
|
||||||
line := l.text
|
line := l.text
|
||||||
if l.is_current {
|
if l.is_current {
|
||||||
line = strings.ReplaceAll(line, themes.MARK_BEFORE, self.lp.SprintStyled("fg=green"))
|
line = strings.ReplaceAll(line, themes.MARK_AFTER, green_fg)
|
||||||
if l.is_current {
|
self.lp.PrintStyled("fg=green", ">")
|
||||||
self.lp.PrintStyled("fg=green", ">")
|
self.lp.PrintStyled("fg=green bold", line)
|
||||||
self.lp.PrintStyled("fg=green bold", line)
|
} else {
|
||||||
} else {
|
self.lp.PrintStyled("fg=green", " ")
|
||||||
self.lp.PrintStyled("fg=green", " ")
|
self.lp.QueueWriteString(line)
|
||||||
self.lp.QueueWriteString(line)
|
|
||||||
}
|
|
||||||
self.lp.MoveCursorHorizontally(mw - l.width)
|
|
||||||
self.lp.Println(SEPARATOR)
|
|
||||||
}
|
}
|
||||||
|
self.lp.MoveCursorHorizontally(mw - l.width)
|
||||||
|
self.lp.Println(SEPARATOR)
|
||||||
}
|
}
|
||||||
if self.themes_list != nil && self.themes_list.Len() > 0 {
|
if self.themes_list != nil && self.themes_list.Len() > 0 {
|
||||||
self.draw_theme_demo()
|
self.draw_theme_demo()
|
||||||
@ -446,7 +453,10 @@ func (self *handler) draw_theme_demo() {
|
|||||||
if intense {
|
if intense {
|
||||||
s = "bright-" + s
|
s = "bright-" + s
|
||||||
}
|
}
|
||||||
buf.WriteString(self.lp.SprintStyled("fg="+c, c[:trunc]))
|
if len(c) > trunc {
|
||||||
|
c = c[:trunc]
|
||||||
|
}
|
||||||
|
buf.WriteString(self.lp.SprintStyled("fg="+c, c))
|
||||||
buf.WriteString(" ")
|
buf.WriteString(" ")
|
||||||
}
|
}
|
||||||
text := strings.TrimSpace(buf.String())
|
text := strings.TrimSpace(buf.String())
|
||||||
@ -487,25 +497,25 @@ func (self *handler) draw_theme_demo() {
|
|||||||
// accepting {{{
|
// accepting {{{
|
||||||
|
|
||||||
func (self *handler) on_accepting_key_event(ev *loop.KeyEvent) error {
|
func (self *handler) on_accepting_key_event(ev *loop.KeyEvent) error {
|
||||||
if ev.MatchesRelease("q") || ev.MatchesRelease("esc") {
|
if ev.MatchesPressOrRepeat("q") || ev.MatchesPressOrRepeat("esc") {
|
||||||
ev.Handled = true
|
ev.Handled = true
|
||||||
self.lp.Quit(0)
|
self.quit_on_next_key_release = 0
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if ev.MatchesRelease("a") {
|
if ev.MatchesPressOrRepeat("a") {
|
||||||
ev.Handled = true
|
ev.Handled = true
|
||||||
self.state = BROWSING
|
self.state = BROWSING
|
||||||
self.draw_screen()
|
self.draw_screen()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if ev.MatchesRelease("p") {
|
if ev.MatchesPressOrRepeat("p") {
|
||||||
ev.Handled = true
|
ev.Handled = true
|
||||||
self.themes_list.CurrentTheme().SaveInDir(utils.ConfigDir())
|
self.themes_list.CurrentTheme().SaveInDir(utils.ConfigDir())
|
||||||
self.update_recent()
|
self.update_recent()
|
||||||
self.lp.Quit(0)
|
self.lp.Quit(0)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if ev.MatchesRelease("m") {
|
if ev.MatchesPressOrRepeat("m") {
|
||||||
ev.Handled = true
|
ev.Handled = true
|
||||||
self.themes_list.CurrentTheme().SaveInConf(utils.ConfigDir(), self.opts.ReloadIn, self.opts.ConfigFileName)
|
self.themes_list.CurrentTheme().SaveInConf(utils.ConfigDir(), self.opts.ReloadIn, self.opts.ConfigFileName)
|
||||||
self.update_recent()
|
self.update_recent()
|
||||||
@ -556,18 +566,36 @@ func (self *handler) draw_accepting_screen() {
|
|||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
// searching {{{
|
// searching {{{
|
||||||
|
|
||||||
|
func (self *handler) update_search() {
|
||||||
|
text := self.rl.AllText()
|
||||||
|
if self.themes_list.UpdateSearch(text) {
|
||||||
|
self.set_colors_to_current_theme()
|
||||||
|
self.draw_screen()
|
||||||
|
} else {
|
||||||
|
self.draw_search_bar()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *handler) on_text(text string, a, b bool) error {
|
||||||
|
if self.state == SEARCHING {
|
||||||
|
err := self.rl.OnText(text, a, b)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
self.update_search()
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (self *handler) on_searching_key_event(ev *loop.KeyEvent) error {
|
func (self *handler) on_searching_key_event(ev *loop.KeyEvent) error {
|
||||||
if ev.MatchesRelease("enter") {
|
if ev.MatchesPressOrRepeat("enter") {
|
||||||
ev.Handled = true
|
ev.Handled = true
|
||||||
self.state = BROWSING
|
self.state = BROWSING
|
||||||
self.draw_bottom_bar()
|
self.draw_bottom_bar()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if ev.MatchesPressOrRepeat("enter") || ev.MatchesPressOrRepeat("esc") {
|
if ev.MatchesPressOrRepeat("esc") {
|
||||||
ev.Handled = true
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if ev.MatchesRelease("esc") {
|
|
||||||
ev.Handled = true
|
ev.Handled = true
|
||||||
self.state = BROWSING
|
self.state = BROWSING
|
||||||
self.themes_list.UpdateSearch("")
|
self.themes_list.UpdateSearch("")
|
||||||
@ -579,12 +607,8 @@ func (self *handler) on_searching_key_event(ev *loop.KeyEvent) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
text := self.rl.AllText()
|
if ev.Handled {
|
||||||
if self.themes_list.UpdateSearch(text) {
|
self.update_search()
|
||||||
self.set_colors_to_current_theme()
|
|
||||||
self.draw_screen()
|
|
||||||
} else {
|
|
||||||
self.draw_search_bar()
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ package themes
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"archive/zip"
|
"archive/zip"
|
||||||
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -20,6 +21,7 @@ import (
|
|||||||
|
|
||||||
"kitty/tools/cli"
|
"kitty/tools/cli"
|
||||||
"kitty/tools/config"
|
"kitty/tools/config"
|
||||||
|
"kitty/tools/tty"
|
||||||
"kitty/tools/tui/subseq"
|
"kitty/tools/tui/subseq"
|
||||||
"kitty/tools/utils"
|
"kitty/tools/utils"
|
||||||
"kitty/tools/utils/style"
|
"kitty/tools/utils/style"
|
||||||
@ -31,6 +33,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var _ = fmt.Print
|
var _ = fmt.Print
|
||||||
|
var DebugPrintln = tty.DebugPrintln
|
||||||
|
|
||||||
var AllColorSettingNames = map[string]bool{ // {{{
|
var AllColorSettingNames = map[string]bool{ // {{{
|
||||||
// generated by gen-config.py do not edit
|
// generated by gen-config.py do not edit
|
||||||
@ -325,12 +328,33 @@ type JSONMetadata struct {
|
|||||||
|
|
||||||
var ErrNoCacheFound = errors.New("No cache found and max cache age is negative")
|
var ErrNoCacheFound = errors.New("No cache found and max cache age is negative")
|
||||||
|
|
||||||
|
func set_comment_in_zip_file(path string, comment string) error {
|
||||||
|
src, err := zip.OpenReader(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer src.Close()
|
||||||
|
buf := bytes.Buffer{}
|
||||||
|
dest := zip.NewWriter(&buf)
|
||||||
|
dest.SetComment(comment)
|
||||||
|
for _, sf := range src.File {
|
||||||
|
err = dest.Copy(sf)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dest.Close()
|
||||||
|
utils.AtomicUpdateFile(path, buf.Bytes(), 0o644)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func fetch_cached(name, url, cache_path string, max_cache_age time.Duration) (string, error) {
|
func fetch_cached(name, url, cache_path string, max_cache_age time.Duration) (string, error) {
|
||||||
cache_path = filepath.Join(cache_path, name+".zip")
|
cache_path = filepath.Join(cache_path, name+".zip")
|
||||||
zf, err := zip.OpenReader(cache_path)
|
zf, err := zip.OpenReader(cache_path)
|
||||||
if err != nil && !errors.Is(err, fs.ErrNotExist) {
|
if err != nil && !errors.Is(err, fs.ErrNotExist) {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
defer zf.Close()
|
||||||
|
|
||||||
var jm JSONMetadata
|
var jm JSONMetadata
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@ -362,6 +386,12 @@ func fetch_cached(name, url, cache_path string, max_cache_age time.Duration) (st
|
|||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
if resp.StatusCode == http.StatusNotModified {
|
if resp.StatusCode == http.StatusNotModified {
|
||||||
|
jm.Timestamp = utils.ISO8601Format(time.Now())
|
||||||
|
comment, _ := json.Marshal(jm)
|
||||||
|
err = set_comment_in_zip_file(cache_path, utils.UnsafeBytesToString(comment))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
return cache_path, nil
|
return cache_path, nil
|
||||||
}
|
}
|
||||||
return "", fmt.Errorf("Failed to download %s with HTTP error: %s", url, resp.Status)
|
return "", fmt.Errorf("Failed to download %s with HTTP error: %s", url, resp.Status)
|
||||||
@ -760,14 +790,18 @@ func (self *Themes) At(x int) *Theme {
|
|||||||
}
|
}
|
||||||
func (self *Themes) Names() []string { return self.index_map }
|
func (self *Themes) Names() []string { return self.index_map }
|
||||||
|
|
||||||
|
func (self *Themes) create_index_map() {
|
||||||
|
self.index_map = maps.Keys(self.name_map)
|
||||||
|
self.index_map = utils.StableSortWithKey(self.index_map, strings.ToLower)
|
||||||
|
}
|
||||||
|
|
||||||
func (self *Themes) Filtered(is_ok func(*Theme) bool) *Themes {
|
func (self *Themes) Filtered(is_ok func(*Theme) bool) *Themes {
|
||||||
themes := utils.Filter(maps.Values(self.name_map), is_ok)
|
themes := utils.Filter(maps.Values(self.name_map), is_ok)
|
||||||
ans := Themes{name_map: make(map[string]*Theme, len(themes))}
|
ans := Themes{name_map: make(map[string]*Theme, len(themes))}
|
||||||
for _, theme := range themes {
|
for _, theme := range themes {
|
||||||
ans.name_map[theme.metadata.Name] = theme
|
ans.name_map[theme.metadata.Name] = theme
|
||||||
}
|
}
|
||||||
ans.index_map = maps.Keys(ans.name_map)
|
ans.create_index_map()
|
||||||
ans.index_map = utils.StableSortWithKey(ans.index_map, strings.ToLower)
|
|
||||||
return &ans
|
return &ans
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -873,23 +907,24 @@ func (self *Themes) ApplySearch(expression string, marks ...string) []string {
|
|||||||
if len(marks) == 2 {
|
if len(marks) == 2 {
|
||||||
mark_before, mark_after = marks[0], marks[1]
|
mark_before, mark_after = marks[0], marks[1]
|
||||||
}
|
}
|
||||||
results := match(expression, maps.Keys(self.name_map))
|
results := utils.Filter(match(expression, self.index_map), func(x *subseq.Match) bool { return x.Score > 0 })
|
||||||
name_map := make(map[string]*Theme, len(results))
|
name_map := make(map[string]*Theme, len(results))
|
||||||
|
for _, m := range results {
|
||||||
|
name_map[m.Text] = self.name_map[m.Text]
|
||||||
|
}
|
||||||
|
self.name_map = name_map
|
||||||
|
self.index_map = self.index_map[:0]
|
||||||
ans := make([]string, 0, len(results))
|
ans := make([]string, 0, len(results))
|
||||||
for _, m := range results {
|
for _, m := range results {
|
||||||
k := m.Text
|
|
||||||
text := m.Text
|
text := m.Text
|
||||||
positions := m.Positions
|
positions := m.Positions
|
||||||
for i := len(positions) - 1; i >= 0; i-- {
|
for i := len(positions) - 1; i >= 0; i-- {
|
||||||
p := positions[i]
|
p := positions[i]
|
||||||
text = text[:p] + mark_before + text[p:p+1] + mark_after + text[p+1:]
|
text = text[:p] + mark_before + text[p:p+1] + mark_after + text[p+1:]
|
||||||
}
|
}
|
||||||
name_map[k] = self.name_map[k]
|
|
||||||
ans = append(ans, text)
|
ans = append(ans, text)
|
||||||
|
self.index_map = append(self.index_map, m.Text)
|
||||||
}
|
}
|
||||||
self.name_map = name_map
|
|
||||||
self.index_map = maps.Keys(name_map)
|
|
||||||
self.index_map = utils.StableSortWithKey(self.index_map, strings.ToLower)
|
|
||||||
return ans
|
return ans
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -905,8 +940,7 @@ func LoadThemes(cache_age time.Duration) (ans *Themes, closer io.Closer, err err
|
|||||||
if err = ans.add_from_dir(filepath.Join(utils.ConfigDir(), "themes")); err != nil {
|
if err = ans.add_from_dir(filepath.Join(utils.ConfigDir(), "themes")); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
ans.index_map = maps.Keys(ans.name_map)
|
ans.create_index_map()
|
||||||
ans.index_map = utils.StableSortWithKey(ans.index_map, strings.ToLower)
|
|
||||||
return ans, closer, nil
|
return ans, closer, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -55,7 +55,9 @@ func (self *Readline) all_text() string {
|
|||||||
func (self *Readline) set_text(text string) {
|
func (self *Readline) set_text(text string) {
|
||||||
self.move_to_start()
|
self.move_to_start()
|
||||||
self.erase_chars_after_cursor(123456789, true)
|
self.erase_chars_after_cursor(123456789, true)
|
||||||
self.add_text(text)
|
if text != "" {
|
||||||
|
self.add_text(text)
|
||||||
|
}
|
||||||
self.move_to_end()
|
self.move_to_end()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user