From 444c3551174f45f7d1eb5c4ec9e8d210e08442e1 Mon Sep 17 00:00:00 2001 From: EnumDev Date: Thu, 12 Jun 2025 21:01:37 +0300 Subject: [PATCH] Add configuration files for styles, keybindings and other options --- Makefile | 2 + config/config.yml | 6 + config/keybindings.yml | 40 ++++++ config/styles/classic.yml | 21 ++++ config/styles/default-fallback.yml | 21 ++++ config/styles/default.yml | 21 ++++ src/config.go | 55 +++++++++ src/dropdown.go | 4 +- src/go.mod | 1 + src/go.sum | 3 + src/input_bar.go | 2 +- src/keybindings.go | 140 +++++++++------------ src/line_index.go | 2 +- src/main.go | 12 +- src/message_bar.go | 2 +- src/style.go | 187 +++++++++++++++++++++++++++++ src/top_menu.go | 2 +- src/window.go | 28 +++-- 18 files changed, 450 insertions(+), 99 deletions(-) create mode 100644 config/config.yml create mode 100644 config/keybindings.yml create mode 100644 config/styles/classic.yml create mode 100644 config/styles/default-fallback.yml create mode 100644 config/styles/default.yml create mode 100644 src/config.go create mode 100644 src/style.go diff --git a/Makefile b/Makefile index f8eb227..eff5382 100644 --- a/Makefile +++ b/Makefile @@ -13,8 +13,10 @@ build: install: build/typer # Create directories install -dm755 $(DESTDIR)$(BINDIR) + install -dm755 $(DESTDIR)$(SYSCONFDIR) # Install files install -Dm755 build/typer $(DESTDIR)$(BINDIR)/typer + cp -r config -T $(DESTDIR)$(SYSCONFDIR)/typer uninstall: rm $(DESTDIR)$(BINDIR)/typer diff --git a/config/config.yml b/config/config.yml new file mode 100644 index 0000000..ae6fad0 --- /dev/null +++ b/config/config.yml @@ -0,0 +1,6 @@ +# Editor style option +selected_style: "default" # Style for 256-color and true-color capable terminals +selected_style_fallback: "default-fallback" # Style for 8-color capable terminals (Like TTYs) + +# Other +tab_indentation: 4 # Length of tab characters \ No newline at end of file diff --git a/config/keybindings.yml b/config/keybindings.yml new file mode 100644 index 0000000..f1be915 --- /dev/null +++ b/config/keybindings.yml @@ -0,0 +1,40 @@ +keybindings: + - keybinding: "Ctrl-Q" + cursor_modes: ["buffer"] + command: "quit" + - keybinding: "Ctrl-C" + cursor_modes: ["buffer"] + command: "copy" + - keybinding: "Ctrl-V" + cursor_modes: ["buffer"] + command: "paste" + - keybinding: "Ctrl-S" + cursor_modes: ["buffer"] + command: "save" + - keybinding: "Ctrl-O" + cursor_modes: ["buffer"] + command: "open" + - keybinding: "Ctrl-R" + cursor_modes: ["buffer"] + command: "reload" + - keybinding: "PgUp" + cursor_modes: ["buffer"] + command: "prev-buffer" + - keybinding: "PgDn" + cursor_modes: ["buffer"] + command: "prev-buffer" + - keybinding: "Ctrl-N" + cursor_modes: ["buffer"] + command: "new-buffer" + - keybinding: "Delete" + cursor_modes: ["buffer"] + command: "close-buffer" + - keybinding: "F1" + cursor_modes: ["buffer","dropdown"] + command: "menu-file" + - keybinding: "F2" + cursor_modes: ["buffer","dropdown"] + command: "menu-edit" + - keybinding: "F3" + cursor_modes: ["buffer","dropdown"] + command: "menu-buffers" \ No newline at end of file diff --git a/config/styles/classic.yml b/config/styles/classic.yml new file mode 100644 index 0000000..88c4ec0 --- /dev/null +++ b/config/styles/classic.yml @@ -0,0 +1,21 @@ +# Metadata +name: "classic" +description: "Style imitating the look of classic text editors and IDEs from the and 90s" +style_type: "256-color" + +# Colors +colors: + buffer_area_bg: "darkblue" # Buffer area background color + buffer_area_fg: "white" # Buffer area text color + buffer_area_sel: "blue" # Buffer area selected text and cursor background color + top_menu_bg: "245" # Top menu background color + top_menu_fg: "black" # Top menu text color + dropdown_bg: "lightgray" # Dropdown background color + dropdown_fg: "black" # Dropdown text color + dropdown_sel: "blue" # Dropdown selected option background color + line_index_bg: "247" # Line index background color + line_index_fg: "black" # Line index text color + message_bar_bg: "245" # Message bar background color + message_bar_fg: "black" # Message bar text color + input_bar_bg: "245" # Input bar background color + input_bar_fg: "black" # Input bar text color diff --git a/config/styles/default-fallback.yml b/config/styles/default-fallback.yml new file mode 100644 index 0000000..7a62322 --- /dev/null +++ b/config/styles/default-fallback.yml @@ -0,0 +1,21 @@ +# Metadata +name: "default-fallback" +description: "The default look of Typer - Fallback style" +style_type: "8-color" + +# Colors +colors: + buffer_area_bg: "black" # Buffer area background color + buffer_area_fg: "white" # Buffer area text color + buffer_area_sel: "navy" # Buffer area selected text and cursor background color + top_menu_bg: "white" # Top menu background color + top_menu_fg: "black" # Top -menu text color + dropdown_bg: "white" # Dropdown background color + dropdown_fg: "black" # Dropdown text color + dropdown_sel: "navy" # Dropdown selected option background color + line_index_bg: "white" # Line index background color + line_index_fg: "black" # Line index text color + message_bar_bg: "white" # Message bar background color + message_bar_fg: "black" # Message bar text color + input_bar_bg: "white" # Input bar background color + input_bar_fg: "black" # Input bar text color diff --git a/config/styles/default.yml b/config/styles/default.yml new file mode 100644 index 0000000..a2a7955 --- /dev/null +++ b/config/styles/default.yml @@ -0,0 +1,21 @@ +# Metadata +name: "default" +description: "The default look of Typer" +style_type: "256-color" + +# Colors +colors: + buffer_area_bg: "234" # Buffer area background color + buffer_area_fg: "white" # Buffer area text color + buffer_area_sel: "243" # Buffer area selected text and cursor background color + top_menu_bg: "236" # Top menu background color + top_menu_fg: "white" # Top menu text color + dropdown_bg: "236" # Dropdown background color + dropdown_fg: "white" # Dropdown text color + dropdown_sel: "240" # Dropdown selected option background color + line_index_bg: "235" # Line index background color + line_index_fg: "dimgray" # Line index text color + message_bar_bg: "236" # Message bar background color + message_bar_fg: "white" # Message bar text color + input_bar_bg: "236" # Input bar background color + input_bar_fg: "white" # Input bar text color \ No newline at end of file diff --git a/src/config.go b/src/config.go new file mode 100644 index 0000000..6451b05 --- /dev/null +++ b/src/config.go @@ -0,0 +1,55 @@ +package main + +import ( + "gopkg.in/yaml.v3" + "log" + "os" + "path" +) + +type TyperConfig struct { + SelectedStyle string `yaml:"selected_style,omitempty"` + FallbackStyle string `yaml:"fallback_style,omitempty"` + TabIndentation int `yaml:"tab_indentation,omitempty"` +} + +var Config TyperConfig + +func readConfig() { + Config = TyperConfig{ + SelectedStyle: "default", + FallbackStyle: "default-fallback", + TabIndentation: 4, + } + + homeDir, err := os.UserHomeDir() + if err != nil { + log.Fatalf("Could not get home directory: %s", err) + } + + if _, err := os.Stat(path.Join(homeDir, ".config/typer/config.yml")); err == nil { + data, err := os.ReadFile(path.Join(homeDir, ".config/typer/config.yml")) + if err != nil { + log.Fatalf("Could not read config.yml: %s", err) + } + err = yaml.Unmarshal(data, &Config) + if err != nil { + log.Fatalf("Could not unmarshal config.yml: %s", err) + } + } else if _, err := os.Stat("/etc/typer/config.yml"); err == nil { + reader, err := os.Open("/etc/typer/config.yml") + if err != nil { + log.Fatalf("Could not read config.yml: %s", err) + } + err = yaml.NewDecoder(reader).Decode(&Config) + if err != nil { + log.Fatalf("Could not read config.yml: %s", err) + } + reader.Close() + } + + // Validate config options + if Config.TabIndentation < 1 { + Config.TabIndentation = 1 + } +} diff --git a/src/dropdown.go b/src/dropdown.go index 707c312..097f482 100644 --- a/src/dropdown.go +++ b/src/dropdown.go @@ -50,13 +50,13 @@ func ClearDropdowns() { } func drawDropdowns(window *Window) { - dropdownStyle := tcell.StyleDefault.Foreground(tcell.ColorWhite).Background(tcell.Color236) + dropdownStyle := tcell.StyleDefault.Background(CurrentStyle.DropdownBg).Foreground(CurrentStyle.DropdownFg) for _, d := range dropdowns { drawBox(window.screen, d.PosX, d.PosY, d.PosX+d.Width+1, d.PosY+len(d.Options)+1, dropdownStyle) line := d.PosY for i, option := range d.Options { if d.Selected == i { - drawText(window.screen, d.PosX+1, d.PosY+line, d.PosX+d.Width+1, d.PosY+line, dropdownStyle.Background(tcell.Color240), option) + drawText(window.screen, d.PosX+1, d.PosY+line, d.PosX+d.Width+1, d.PosY+line, dropdownStyle.Background(CurrentStyle.DropdownSel), option) } else { drawText(window.screen, d.PosX+1, d.PosY+line, d.PosX+d.Width+1, d.PosY+line, dropdownStyle, option) } diff --git a/src/go.mod b/src/go.mod index 982257d..f18e453 100644 --- a/src/go.mod +++ b/src/go.mod @@ -12,4 +12,5 @@ require ( golang.org/x/sys v0.33.0 // indirect golang.org/x/term v0.32.0 // indirect golang.org/x/text v0.26.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/src/go.sum b/src/go.sum index c4793d0..575e8fa 100644 --- a/src/go.sum +++ b/src/go.sum @@ -79,3 +79,6 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/src/input_bar.go b/src/input_bar.go index 200cadd..7bc59b8 100644 --- a/src/input_bar.go +++ b/src/input_bar.go @@ -42,7 +42,7 @@ func drawInputBar(window *Window) { screen := window.screen - inputBarStyle := tcell.StyleDefault.Foreground(tcell.ColorWhite).Background(tcell.Color236) + inputBarStyle := tcell.StyleDefault.Background(CurrentStyle.InputBarBg).Foreground(CurrentStyle.InputBarFg) sizeX, sizeY := screen.Size() diff --git a/src/keybindings.go b/src/keybindings.go index 68ac689..0588cc1 100644 --- a/src/keybindings.go +++ b/src/keybindings.go @@ -2,106 +2,86 @@ package main import ( "github.com/gdamore/tcell/v2" + "gopkg.in/yaml.v3" + "log" + "os" + "path" "strings" ) +type TyperKeybindings struct { + Keybindings []Keybinding `yaml:"keybindings"` +} + type Keybinding struct { - keybind string - cursorModes []CursorMode - command string + Keybinding string `yaml:"keybinding"` + CursorModes []string `yaml:"cursor_modes"` + Command string `yaml:"command"` } -var Keybinds = make([]Keybinding, 0) +var Keybindings TyperKeybindings -func initKeybindings() { - // Add key bindings - Keybinds = append(Keybinds, Keybinding{ - keybind: "Ctrl-Q", - cursorModes: []CursorMode{CursorModeBuffer}, - command: "quit", - }) - Keybinds = append(Keybinds, Keybinding{ - keybind: "Ctrl-C", - cursorModes: []CursorMode{CursorModeBuffer}, - command: "copy", - }) - Keybinds = append(Keybinds, Keybinding{ - keybind: "Ctrl-V", - cursorModes: []CursorMode{CursorModeBuffer}, - command: "paste", - }) - Keybinds = append(Keybinds, Keybinding{ - keybind: "Ctrl-S", - cursorModes: []CursorMode{CursorModeBuffer}, - command: "save", - }) - Keybinds = append(Keybinds, Keybinding{ - keybind: "Ctrl-O", - cursorModes: []CursorMode{CursorModeBuffer}, - command: "open", - }) - Keybinds = append(Keybinds, Keybinding{ - keybind: "Ctrl-R", - cursorModes: []CursorMode{CursorModeBuffer}, - command: "reload", - }) - Keybinds = append(Keybinds, Keybinding{ - keybind: "PgUp", - cursorModes: []CursorMode{CursorModeBuffer}, - command: "prev-buffer", - }) - Keybinds = append(Keybinds, Keybinding{ - keybind: "PgDn", - cursorModes: []CursorMode{CursorModeBuffer}, - command: "next-buffer", - }) - Keybinds = append(Keybinds, Keybinding{ - keybind: "Ctrl-N", - cursorModes: []CursorMode{CursorModeBuffer}, - command: "new-buffer", - }) - Keybinds = append(Keybinds, Keybinding{ - keybind: "Delete", - cursorModes: []CursorMode{CursorModeBuffer}, - command: "close-buffer", - }) - Keybinds = append(Keybinds, Keybinding{ - keybind: "Ctrl-Q", - cursorModes: []CursorMode{CursorModeBuffer}, - command: "quit", - }) - Keybinds = append(Keybinds, Keybinding{ - keybind: "F1", - cursorModes: []CursorMode{CursorModeBuffer, CursorModeDropdown}, - command: "menu-file", - }) - Keybinds = append(Keybinds, Keybinding{ - keybind: "F2", - cursorModes: []CursorMode{CursorModeBuffer, CursorModeDropdown}, - command: "menu-edit", - }) - Keybinds = append(Keybinds, Keybinding{ - keybind: "F3", - cursorModes: []CursorMode{CursorModeBuffer, CursorModeDropdown}, - command: "menu-buffers", - }) +func readKeybindings() { + Keybindings = TyperKeybindings{ + Keybindings: make([]Keybinding, 0), + } + + homeDir, err := os.UserHomeDir() + if err != nil { + log.Fatalf("Could not get home directory: %s", err) + } + + if _, err := os.Stat(path.Join(homeDir, ".config/typer/keybindings.yml")); err == nil { + data, err := os.ReadFile(path.Join(homeDir, ".config/typer/keybindings.yml")) + if err != nil { + log.Fatalf("Could not read keybindings.yml: %s", err) + } + err = yaml.Unmarshal(data, &Keybindings) + if err != nil { + log.Fatalf("Could not unmarshal keybindings.yml: %s", err) + } + } else if _, err := os.Stat("/etc/typer/keybindings.yml"); err == nil { + reader, err := os.Open("/etc/typer/keybindings.yml") + if err != nil { + log.Fatalf("Could not read keybindings.yml: %s", err) + } + err = yaml.NewDecoder(reader).Decode(&Keybindings) + if err != nil { + log.Fatalf("Could not read keybindings.yml: %s", err) + } + reader.Close() + } } -func (keybind *Keybinding) IsPressed(ev *tcell.EventKey) bool { - keys := strings.SplitN(keybind.keybind, "+", 2) +func (keybinding *Keybinding) GetCursorModes() []CursorMode { + ret := make([]CursorMode, 0) + + for _, cursorModeStr := range keybinding.CursorModes { + for key, value := range CursorModeNames { + if cursorModeStr == value { + ret = append(ret, key) + } + } + } + + return ret +} + +func (keybinding *Keybinding) IsPressed(ev *tcell.EventKey) bool { + keys := strings.SplitN(keybinding.Keybinding, "+", 2) if len(keys) == 0 { return false } else if len(keys) == 1 { for k, v := range tcell.KeyNames { if k != tcell.KeyRune { - if keybind.keybind == v { + if keybinding.Keybinding == v { if ev.Key() == k { return true } } } else { - if keybind.keybind == string(ev.Rune()) { + if keybinding.Keybinding == string(ev.Rune()) { return true } } diff --git a/src/line_index.go b/src/line_index.go index 513d061..97417bd 100644 --- a/src/line_index.go +++ b/src/line_index.go @@ -10,7 +10,7 @@ func drawLineIndex(window *Window) { screen := window.screen buffer := window.CurrentBuffer - lineIndexStyle := tcell.StyleDefault.Foreground(tcell.ColorDimGray).Background(tcell.Color235) + lineIndexStyle := tcell.StyleDefault.Background(CurrentStyle.LineIndexBg).Foreground(CurrentStyle.LineIndexFg) _, sizeY := screen.Size() diff --git a/src/main.go b/src/main.go index e687d08..aec86da 100644 --- a/src/main.go +++ b/src/main.go @@ -6,12 +6,18 @@ import ( ) func main() { + // Read config + readConfig() + + // Read key bindings + readKeybindings() + + // Read styles + readStyles() + // Initialize commands initCommands() - // Initialize key bindings - initKeybindings() - window, err := CreateWindow() if err != nil { log.Fatalf("Failed to create window: %v", err) diff --git a/src/message_bar.go b/src/message_bar.go index 9658be7..976c762 100644 --- a/src/message_bar.go +++ b/src/message_bar.go @@ -33,7 +33,7 @@ func PrintMessage(window *Window, message string) { func drawMessageBar(window *Window) { screen := window.screen - messageBarStyle := tcell.StyleDefault.Foreground(tcell.ColorWhite).Background(tcell.Color236) + messageBarStyle := tcell.StyleDefault.Background(CurrentStyle.MessageBarBg).Foreground(CurrentStyle.MessageBarFg) sizeX, sizeY := screen.Size() diff --git a/src/style.go b/src/style.go new file mode 100644 index 0000000..e625c73 --- /dev/null +++ b/src/style.go @@ -0,0 +1,187 @@ +package main + +import ( + "fmt" + "github.com/gdamore/tcell/v2" + "gopkg.in/yaml.v3" + "log" + "os" + "path" + "reflect" + "slices" + "strconv" + "strings" +) + +type TyperStyle struct { + // Metadata + Name string + Description string + StyleType string + + // Colors + BufferAreaBg tcell.Color `name:"buffer_area_bg"` + BufferAreaFg tcell.Color `name:"buffer_area_fg"` + BufferAreaSel tcell.Color `name:"buffer_area_sel"` + TopMenuBg tcell.Color `name:"top_menu_bg"` + TopMenuFg tcell.Color `name:"top_menu_fg"` + DropdownBg tcell.Color `name:"dropdown_bg"` + DropdownFg tcell.Color `name:"dropdown_fg"` + DropdownSel tcell.Color `name:"dropdown_sel"` + LineIndexBg tcell.Color `name:"line_index_bg"` + LineIndexFg tcell.Color `name:"line_index_fg"` + MessageBarBg tcell.Color `name:"message_bar_bg"` + MessageBarFg tcell.Color `name:"message_bar_fg"` + InputBarBg tcell.Color `name:"input_bar_bg"` + InputBarFg tcell.Color `name:"input_bar_fg"` +} + +type typerStyleYaml struct { + // Metadata + Name string `yaml:"name"` + Description string `yaml:"description"` + StyleType string `yaml:"style_type"` + + // Colors + Colors map[string]string `yaml:"colors"` +} + +var AvailableStyles = make(map[string]TyperStyle) +var CurrentStyle TyperStyle + +func readStyles() { + homeDir, err := os.UserHomeDir() + if err != nil { + log.Fatalf("Could not get home directory: %s", err) + } + + if stat, err := os.Stat(path.Join(homeDir, ".config/typer/styles/")); err == nil && stat.IsDir() { + entries, err := os.ReadDir(path.Join(homeDir, ".config/typer/styles/")) + if err != nil { + log.Fatalf("Could not read user style directory: %s", err) + } + + for _, entry := range entries { + entryPath := path.Join(homeDir, ".config/typer/styles/", entry.Name()) + style, err := readStyleYamlFile(entryPath) + if err != nil { + log.Fatalf("Could not read style file (%s): %s", entryPath, err) + } + + if _, ok := AvailableStyles[style.Name]; !ok { + AvailableStyles[style.Name] = style + } + } + } + if stat, err := os.Stat("/etc/typer/styles/"); err == nil && stat.IsDir() { + entries, err := os.ReadDir("/etc/typer/styles/") + if err != nil { + log.Fatalf("Could not read user style directory: %s", err) + } + + for _, entry := range entries { + entryPath := path.Join("/etc/typer/styles/", entry.Name()) + style, err := readStyleYamlFile(entryPath) + if err != nil { + log.Fatalf("Could not read style file (%s): %s", entryPath, err) + } + if _, ok := AvailableStyles[style.Name]; !ok { + AvailableStyles[style.Name] = style + } + } + } +} + +func readStyleYamlFile(filepath string) (TyperStyle, error) { + styleYaml := typerStyleYaml{} + + data, err := os.ReadFile(filepath) + if err != nil { + return TyperStyle{}, fmt.Errorf("could not read file: %s", err) + } + err = yaml.Unmarshal(data, &styleYaml) + if err != nil { + return TyperStyle{}, fmt.Errorf("could not unmarshal style: %s", err) + } + + style := TyperStyle{ + Name: styleYaml.Name, + Description: styleYaml.Description, + StyleType: styleYaml.StyleType, + } + + for name, colorStr := range styleYaml.Colors { + var color tcell.Color + + if n, err := strconv.Atoi(colorStr); err == nil && n >= 0 && n < 256 { + color = tcell.ColorValid + tcell.Color(n) + } else if strings.HasPrefix(colorStr, "#") && len(colorStr) == 7 { + n, err := strconv.ParseInt(colorStr[1:], 16, 32) + if err != nil { + return TyperStyle{}, fmt.Errorf("could not parse color (%s): %s", colorStr, err) + } + + color = tcell.NewHexColor(int32(n)) + } else if c, ok := tcell.ColorNames[colorStr]; ok { + color = c + } else { + return TyperStyle{}, fmt.Errorf("could not parse color (%s): %s", colorStr, err) + } + + pt := reflect.TypeOf(&style) + t := pt.Elem() + pv := reflect.ValueOf(&style) + v := pv.Elem() + + for i := 0; i < t.NumField(); i++ { + field := v.Field(i) + + if tag, ok := t.Field(i).Tag.Lookup("name"); ok && tag == name { + field.Set(reflect.ValueOf(color)) + } + } + } + + return style, nil +} + +func SetCurrentStyle(screen tcell.Screen) { + availableTypes := make([]string, 1) + availableTypes[0] = "8-color" + if screen.Colors() >= 16 { + availableTypes = append(availableTypes, "16-color") + } + if screen.Colors() >= 256 { + availableTypes = append(availableTypes, "256-color") + } + if screen.Colors() >= 16777216 { + availableTypes = append(availableTypes, "true-color") + } + + if style, ok := AvailableStyles[Config.SelectedStyle]; ok && slices.Index(availableTypes, style.StyleType) != -1 { + CurrentStyle = style + } else if style, ok := AvailableStyles[Config.FallbackStyle]; ok { + CurrentStyle = style + } else { + CurrentStyle = TyperStyle{ + Name: "fallback", + Description: "Fallback style", + StyleType: "8-color", + + BufferAreaBg: tcell.ColorBlack, + BufferAreaFg: tcell.ColorWhite, + BufferAreaSel: tcell.ColorNavy, + TopMenuBg: tcell.ColorWhite, + TopMenuFg: tcell.ColorBlack, + DropdownBg: tcell.ColorWhite, + DropdownFg: tcell.ColorBlack, + DropdownSel: tcell.ColorNavy, + LineIndexBg: tcell.ColorWhite, + LineIndexFg: tcell.ColorBlack, + MessageBarBg: tcell.ColorWhite, + MessageBarFg: tcell.ColorBlack, + InputBarBg: tcell.ColorWhite, + InputBarFg: tcell.ColorBlack, + } + } +} diff --git a/src/top_menu.go b/src/top_menu.go index bdf14e4..4857898 100644 --- a/src/top_menu.go +++ b/src/top_menu.go @@ -100,7 +100,7 @@ func initTopMenu() { func drawTopMenu(window *Window) { screen := window.screen - topMenuStyle := tcell.StyleDefault.Foreground(tcell.ColorWhite).Background(tcell.Color236) + topMenuStyle := tcell.StyleDefault.Background(CurrentStyle.TopMenuBg).Foreground(CurrentStyle.TopMenuFg) sizeX, _ := screen.Size() diff --git a/src/window.go b/src/window.go index 8c223fd..c19ccd9 100644 --- a/src/window.go +++ b/src/window.go @@ -16,6 +16,13 @@ const ( CursorModeInputBar ) +var CursorModeNames = map[CursorMode]string{ + CursorModeDisabled: "disabled", + CursorModeBuffer: "buffer", + CursorModeDropdown: "dropdown", + CursorModeInputBar: "input_bar", +} + type Window struct { ShowTopMenu bool ShowLineIndex bool @@ -57,7 +64,8 @@ func CreateWindow() (*Window, error) { } // Set screen style - screen.SetStyle(tcell.StyleDefault.Foreground(tcell.ColorWhite).Background(tcell.Color234)) + SetCurrentStyle(screen) + screen.SetStyle(tcell.StyleDefault.Foreground(CurrentStyle.BufferAreaFg).Background(CurrentStyle.BufferAreaBg)) // Enable mouse screen.EnableMouse() @@ -81,21 +89,21 @@ func (window *Window) drawCurrentBuffer() { for i, r := range buffer.Contents + " " { if x-buffer.OffsetX >= bufferX && y-buffer.OffsetY >= bufferY { // Default style - style := tcell.StyleDefault.Foreground(tcell.ColorWhite).Background(tcell.Color234) + style := tcell.StyleDefault.Background(CurrentStyle.BufferAreaBg).Foreground(CurrentStyle.BufferAreaFg) // Change background if under cursor if i == buffer.CursorPos { - style = style.Background(tcell.Color243) + style = style.Background(CurrentStyle.BufferAreaSel) } // Change background if selected if buffer.Selection != nil { if edge1, edge2 := buffer.GetSelectionEdges(); i >= edge1 && i <= edge2 { - style = style.Background(tcell.Color243) + style = style.Background(CurrentStyle.BufferAreaSel) // Show selection on entire tab space if r == '\t' { - for j := 0; j < 4; j++ { + for j := 0; j < int(Config.TabIndentation); j++ { window.screen.SetContent(x+j-buffer.OffsetX, y-buffer.OffsetY, r, nil, style) } } @@ -110,7 +118,7 @@ func (window *Window) drawCurrentBuffer() { x = bufferX y++ } else if r == '\t' { - x += 4 + x += int(Config.TabIndentation) } else { x++ } @@ -327,9 +335,9 @@ func (window *Window) input(ev *tcell.EventKey) { } // Check key bindings - for _, keybinding := range Keybinds { - if keybinding.IsPressed(ev) && slices.Index(keybinding.cursorModes, window.CursorMode) != -1 { - RunCommand(window, keybinding.command) + for _, keybinding := range Keybindings.Keybindings { + if keybinding.IsPressed(ev) && slices.Index(keybinding.GetCursorModes(), window.CursorMode) != -1 { + RunCommand(window, keybinding.Command) return } } @@ -603,7 +611,7 @@ func (window *Window) AbsolutePosToCursorPos2D(x, y int) (int, int) { posInLine := make([]int, 0) for i, char := range []rune(line) { if char == '\t' { - for j := 0; j < 4; j++ { + for j := 0; j < Config.TabIndentation; j++ { posInLine = append(posInLine, i) } } else {