Skip to content

Commit

Permalink
Add customization of keybinds (#60)
Browse files Browse the repository at this point in the history
  • Loading branch information
zMoooooritz committed Jan 13, 2024
1 parent a6bd244 commit 7c1f867
Show file tree
Hide file tree
Showing 7 changed files with 195 additions and 74 deletions.
42 changes: 41 additions & 1 deletion configs/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,50 @@ Settings:
HideHelpOnStartup: true
PreloadThumbnails: true

# Configuration of keybinds used in the application
Keys:
Up:
- k
- up
Down:
- j
- down
Left:
- h
- left
Right:
- l
- right
Prev:
- shift+tab
Next:
- tab
Full:
- f
Start:
- g
- home
End:
- G
- end
Quit:
- q
- esc
- ctrl+c
ToggleThumbnail:
- i
OpenArticle:
- o
OpenVideo:
- v
OpenShortNews:
- s
Help:
- "?"

# Configuration of how to open specific resources
# Via the args it is possible to provide flags to the application
# the arg $ will be replaced by the url of the resource
#
Application:
Image:
Path: sxiv
Expand Down
40 changes: 40 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

type Configuration struct {
Settings Settings `yaml:"Settings,omitempty"`
Keys Keys `yaml:"Keys,omitempty"`
Applications Applications `yaml:"Application,omitempty"`
Theme Theme `yaml:"Theme,omitempty"`
}
Expand All @@ -18,6 +19,24 @@ type Settings struct {
PreloadThumbnails bool `yaml:"PreloadThumbnails"`
}

type Keys struct {
Up []string `yaml:"Up"`
Down []string `yaml:"Down"`
Left []string `yaml:"Left"`
Right []string `yaml:"Right"`
Prev []string `yaml:"Prev"`
Next []string `yaml:"Next"`
Full []string `yaml:"Full"`
Start []string `yaml:"Start"`
End []string `yaml:"End"`
Quit []string `yaml:"Quit"`
ToggleThumbnail []string `yaml:"ToggleThumbnail"`
OpenArticle []string `yaml:"OpenArticle"`
OpenVideo []string `yaml:"OpenVideo"`
OpenShortNews []string `yaml:"OpenShortNews"`
Help []string `yaml:"Help"`
}

type Theme struct {
PrimaryColor string `yaml:"PrimaryColor"`
ShadedColor string `yaml:"ShadedColor"`
Expand Down Expand Up @@ -67,11 +86,32 @@ func defaultConfiguration() Configuration {
HideHelpOnStartup: false,
PreloadThumbnails: false,
},
Keys: defaultKeys(),
Applications: Applications{},
Theme: gruvboxTheme(),
}
}

func defaultKeys() Keys {
return Keys{
Up: []string{"k", "up"},
Down: []string{"j", "down"},
Left: []string{"h", "left"},
Right: []string{"l", "right"},
Prev: []string{"shift+tab"},
Next: []string{"tab"},
Full: []string{"f"},
Start: []string{"g", "home"},
End: []string{"G", "end"},
Quit: []string{"q", "esc", "ctrl+c"},
ToggleThumbnail: []string{"i"},
OpenArticle: []string{"o"},
OpenVideo: []string{"v"},
OpenShortNews: []string{"s"},
Help: []string{"?"},
}
}

func gruvboxTheme() Theme {
return Theme{
PrimaryColor: "#EBDBB2",
Expand Down
6 changes: 4 additions & 2 deletions pkg/tui/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ type ImageViewer struct {
image image.Image
}

func NewImageViewer(s config.Style) ImageViewer {
func NewImageViewer(s config.Style, km viewport.KeyMap) ImageViewer {
vp := viewport.New(0, 0)
vp.KeyMap = km
return ImageViewer{
style: s,
isActive: false,
viewport: viewport.New(0, 0),
viewport: vp,
image: image.Rect(0, 0, 1, 1),
}
}
Expand Down
160 changes: 98 additions & 62 deletions pkg/tui/keybinds.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package tui

import "github.com/charmbracelet/bubbles/key"
import (
"github.com/charmbracelet/bubbles/key"
"github.com/charmbracelet/bubbles/list"
"github.com/charmbracelet/bubbles/viewport"
"github.com/zMoooooritz/nachrichten/pkg/config"
)

type KeyMap struct {
quit key.Binding
Expand All @@ -20,71 +25,102 @@ type KeyMap struct {
help key.Binding
}

func GetKeyMap() KeyMap {
func GetKeyMap(keys config.Keys) KeyMap {
return KeyMap{
quit: key.NewBinding(
key.WithKeys("q", "esc", "ctrl+c"),
key.WithHelp("q", "quit"),
),
right: key.NewBinding(
key.WithKeys("l", "right"),
key.WithHelp("→/l", "right"),
),
left: key.NewBinding(
key.WithKeys("h", "left"),
key.WithHelp("←/h", "left"),
),
up: key.NewBinding(
key.WithKeys("j", "down"),
key.WithHelp("↓/j", "down"),
),
down: key.NewBinding(
key.WithKeys("k", "up"),
key.WithHelp("↑/k", "up"),
),
next: key.NewBinding(
key.WithKeys("tab"),
key.WithHelp("tab", "next"),
),
prev: key.NewBinding(
key.WithKeys("shift+tab"),
key.WithHelp("shift+tab", "prev"),
),
full: key.NewBinding(
key.WithKeys("f"),
key.WithHelp("f", "full"),
),
start: key.NewBinding(
key.WithKeys("g", "home"),
key.WithHelp("g/home", "start"),
),
end: key.NewBinding(
key.WithKeys("G", "end"),
key.WithHelp("G/end", "end"),
),
image: key.NewBinding(
key.WithKeys("i"),
key.WithHelp("i", "image"),
),
open: key.NewBinding(
key.WithKeys("o"),
key.WithHelp("o", "open"),
),
video: key.NewBinding(
key.WithKeys("v"),
key.WithHelp("v", "video"),
),
shortNews: key.NewBinding(
key.WithKeys("s"),
key.WithHelp("s", "shortnews"),
),
help: key.NewBinding(
key.WithKeys("?"),
key.WithHelp("?", "help"),
),
quit: toHelpBinding(keys.Quit, "quit"),
right: toHelpBinding(keys.Right, "right"),
left: toHelpBinding(keys.Left, "left"),
up: toHelpBinding(keys.Up, "up"),
down: toHelpBinding(keys.Down, "down"),
next: toHelpBinding(keys.Next, "next"),
prev: toHelpBinding(keys.Prev, "prev"),
full: toHelpBinding(keys.Full, "full"),
start: toHelpBinding(keys.Start, "start"),
end: toHelpBinding(keys.End, "end"),
image: toHelpBinding(keys.ToggleThumbnail, "image"),
open: toHelpBinding(keys.OpenArticle, "open"),
video: toHelpBinding(keys.OpenVideo, "video"),
shortNews: toHelpBinding(keys.OpenShortNews, "shortnews"),
help: toHelpBinding(keys.Help, "help"),
}
}

func toHelpBinding(binds []string, name string) key.Binding {
if len(binds) == 0 {
binds = append(binds, "NOKEY")
}

return key.NewBinding(
key.WithKeys(binds...),
key.WithHelp(keybindsToHelpText(binds), name),
)
}

func keybindsToHelpText(keybinds []string) string {
for i := range keybinds {
if keybinds[i] == "up" {
keybinds[i] = "↑"
}
if keybinds[i] == "down" {
keybinds[i] = "↓"
}
if keybinds[i] == "left" {
keybinds[i] = "←"
}
if keybinds[i] == "right" {
keybinds[i] = "→"
}
}

if len(keybinds) == 1 && keybinds[0] == "NOKEY" {
return "NOKEY"
}

if len(keybinds) == 2 {
return keybinds[0] + "/" + keybinds[1]
}

return keybinds[0]
}

func viewportKeymap(k config.Keys) viewport.KeyMap {
km := viewport.DefaultKeyMap()
km.Up = toBinding(k.Up)
km.Down = toBinding(k.Down)
km.PageUp = toBinding(k.Start)
km.PageDown = toBinding(k.End)
km.HalfPageUp = disabledBinding()
km.HalfPageDown = disabledBinding()
return km
}

func listKeymap(k config.Keys) list.KeyMap {
km := list.DefaultKeyMap()
km.CursorUp = toBinding(k.Up)
km.CursorDown = toBinding(k.Down)
km.GoToStart = toBinding(k.Start)
km.GoToEnd = toBinding(k.End)
km.PrevPage = disabledBinding()
km.NextPage = disabledBinding()
km.Filter = disabledBinding()
km.ClearFilter = disabledBinding()
km.CancelWhileFiltering = disabledBinding()
km.AcceptWhileFiltering = disabledBinding()
km.ShowFullHelp = disabledBinding()
km.CloseFullHelp = disabledBinding()
km.Quit = disabledBinding()
km.ForceQuit = disabledBinding()
return km
}

func toBinding(keybinds []string) key.Binding {
return key.NewBinding(key.WithKeys(keybinds...))
}

func disabledBinding() key.Binding {
return key.NewBinding(key.WithDisabled())
}

func (k KeyMap) ShortHelp() []key.Binding {
return []key.Binding{k.left, k.right, k.up, k.down, k.next, k.help, k.quit}
}
Expand Down
6 changes: 4 additions & 2 deletions pkg/tui/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ type Reader struct {
viewport viewport.Model
}

func NewReader(s config.Style) Reader {
func NewReader(s config.Style, km viewport.KeyMap) Reader {
vp := viewport.New(0, 0)
vp.KeyMap = km
return Reader{
style: s,
isActive: true,
viewport: viewport.New(0, 0),
viewport: vp,
}
}

Expand Down
7 changes: 4 additions & 3 deletions pkg/tui/selector.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,26 @@ type Selector struct {
listHeight int
}

func NewSelector(s config.Style) Selector {
func NewSelector(s config.Style, km list.KeyMap) Selector {
return Selector{
style: s,
lists: InitLists(s, 2),
lists: InitLists(s, km, 2),
listsActiveIndeces: []int{},
activeListIndex: 0,
isFocused: true,
isVisible: true,
}
}

func InitLists(s config.Style, count int) []list.Model {
func InitLists(s config.Style, km list.KeyMap, count int) []list.Model {
var lists []list.Model
for i := 0; i < count; i++ {
newList := list.New([]list.Item{}, NewNewsDelegate(s), 0, 0)
newList.SetFilteringEnabled(false)
newList.SetShowTitle(false)
newList.SetShowStatusBar(false)
newList.SetShowHelp(false)
newList.KeyMap = km
lists = append(lists, newList)
}
return lists
Expand Down
8 changes: 4 additions & 4 deletions pkg/tui/tui.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,14 @@ func InitialModel(c config.Configuration) Model {

m := Model{
opener: util.NewOpener(c.Applications),
keymap: GetKeyMap(),
keymap: GetKeyMap(c.Keys),
style: style,
ready: false,
help: NewHelper(style),
helpMode: helpMode,
selector: NewSelector(style),
reader: NewReader(style),
imageViewer: NewImageViewer(style),
selector: NewSelector(style, listKeymap(c.Keys)),
reader: NewReader(style, viewportKeymap(c.Keys)),
imageViewer: NewImageViewer(style, viewportKeymap(c.Keys)),
spinner: NewDotSpinner(),
config: c,
width: 0,
Expand Down

0 comments on commit 7c1f867

Please sign in to comment.