mirror of
https://github.com/makeworld-the-better-one/amfora.git
synced 2024-11-25 13:52:16 +03:00
Keybinding system for global keys (#135)
Co-authored-by: makeworld <25111343+makeworld-the-better-one@users.noreply.github.com>
This commit is contained in:
parent
6e3e8a0584
commit
f10337e429
@ -194,7 +194,46 @@ func Init() error {
|
||||
viper.SetDefault("a-general.page_max_size", 2097152)
|
||||
viper.SetDefault("a-general.page_max_time", 10)
|
||||
viper.SetDefault("a-general.emoji_favicons", false)
|
||||
viper.SetDefault("keybindings.shift_numbers", "!@#$%^&*()")
|
||||
viper.SetDefault("keybindings.bind_reload", []string{"R", "Ctrl-R"})
|
||||
viper.SetDefault("keybindings.bind_home", "Backspace")
|
||||
viper.SetDefault("keybindings.bind_bookmarks", "Ctrl-B")
|
||||
viper.SetDefault("keybindings.bind_add_bookmark", "Ctrl-D")
|
||||
viper.SetDefault("keybindings.bind_sub", "Ctrl-A")
|
||||
viper.SetDefault("keybindings.bind_add_sub", "Ctrl-X")
|
||||
viper.SetDefault("keybindings.bind_save", "Ctrl-S")
|
||||
viper.SetDefault("keybindings.bind_pgup", []string{"PgUp", "u"})
|
||||
viper.SetDefault("keybindings.bind_pgdn", []string{"PgDn", "d"})
|
||||
viper.SetDefault("keybindings.bind_bottom", "Space")
|
||||
viper.SetDefault("keybindings.bind_edit", "e")
|
||||
viper.SetDefault("keybindings.bind_back", []string{"b", "Alt-Left"})
|
||||
viper.SetDefault("keybindings.bind_forward", []string{"f", "Alt-Right"})
|
||||
viper.SetDefault("keybindings.bind_new_tab", "Ctrl-T")
|
||||
viper.SetDefault("keybindings.bind_close_tab", "Ctrl-W")
|
||||
viper.SetDefault("keybindings.bind_next_tab", "F2")
|
||||
viper.SetDefault("keybindings.bind_prev_tab", "F1")
|
||||
viper.SetDefault("keybindings.bind_quit", []string{"Ctrl-C", "Ctrl-Q", "q"})
|
||||
viper.SetDefault("keybindings.bind_help", "?")
|
||||
viper.SetDefault("keybindings.bind_link1", "1")
|
||||
viper.SetDefault("keybindings.bind_link2", "2")
|
||||
viper.SetDefault("keybindings.bind_link3", "3")
|
||||
viper.SetDefault("keybindings.bind_link4", "4")
|
||||
viper.SetDefault("keybindings.bind_link5", "5")
|
||||
viper.SetDefault("keybindings.bind_link6", "6")
|
||||
viper.SetDefault("keybindings.bind_link7", "7")
|
||||
viper.SetDefault("keybindings.bind_link8", "8")
|
||||
viper.SetDefault("keybindings.bind_link9", "9")
|
||||
viper.SetDefault("keybindings.bind_link0", "0")
|
||||
viper.SetDefault("keybindings.bind_tab1", "!")
|
||||
viper.SetDefault("keybindings.bind_tab2", "@")
|
||||
viper.SetDefault("keybindings.bind_tab3", "#")
|
||||
viper.SetDefault("keybindings.bind_tab4", "$")
|
||||
viper.SetDefault("keybindings.bind_tab5", "%")
|
||||
viper.SetDefault("keybindings.bind_tab6", "^")
|
||||
viper.SetDefault("keybindings.bind_tab7", "&")
|
||||
viper.SetDefault("keybindings.bind_tab8", "*")
|
||||
viper.SetDefault("keybindings.bind_tab9", "(")
|
||||
viper.SetDefault("keybindings.bind_tab0", ")")
|
||||
viper.SetDefault("keybindings.shift_numbers", "")
|
||||
viper.SetDefault("url-handlers.other", "off")
|
||||
viper.SetDefault("cache.max_size", 0)
|
||||
viper.SetDefault("cache.max_pages", 20)
|
||||
@ -211,6 +250,9 @@ func Init() error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Setup the key bindings
|
||||
KeyInit()
|
||||
|
||||
// *** Downloads paths, setup, and creation ***
|
||||
|
||||
// Setup downloads dir
|
||||
|
@ -90,12 +90,51 @@ emoji_favicons = false
|
||||
|
||||
|
||||
[keybindings]
|
||||
# In the future there will be more settings here.
|
||||
# If you have a non-US keyboard, use bind_tab1 through bind_tab0 to
|
||||
# setup the shift-number bindings: Eg, for US keyboards (the default):
|
||||
# bind_tab1 = "!"
|
||||
# bind_tab2 = "@"
|
||||
# bind_tab3 = "#"
|
||||
# bind_tab4 = "$"
|
||||
# bind_tab5 = "%"
|
||||
# bind_tab6 = "^"
|
||||
# bind_tab7 = "&"
|
||||
# bind_tab8 = "*"
|
||||
# bind_tab9 = "("
|
||||
# bind_tab0 = ")"
|
||||
|
||||
# Hold down shift and press the numbers on your keyboard (1,2,3,4,5,6,7,8,9,0) to set this up.
|
||||
# It is default set to be accurate for US keyboards.
|
||||
shift_numbers = "!@#$%^&*()"
|
||||
# Whitespace is not allowed in any of the keybindings! Use 'Space' and 'Tab' to bind to those keys.
|
||||
# Multiple keys can be bound to one command, just use a TOML array.
|
||||
# To add the Alt modifier, the binding must start with Alt-, should be reasonably universal
|
||||
# Ctrl- won't work on all keys, see this for a list:
|
||||
# https://github.com/gdamore/tcell/blob/cb1e5d6fa606/key.go#L83
|
||||
|
||||
# An example of a TOML array for multiple keys being bound to one command is the default
|
||||
# binding for reload:
|
||||
# bind_reload = ["R","Ctrl-R"]
|
||||
# One thing to note here is that "R" is capitalization sensitive, so it means shift-r.
|
||||
# "Ctrl-R" means both ctrl-r and ctrl-shift-R (this is a quirk of what ctrl-r means on
|
||||
# an ANSI terminal)
|
||||
|
||||
# The default binding for opening the bottom bar for entering a URL or link number is:
|
||||
# bind_bottom = "Space"
|
||||
# This is how to get the Spacebar as a keybinding, if you try to use " ", it won't work.
|
||||
# And, finally, an example of a simple, unmodified character is:
|
||||
# bind_edit = "e"
|
||||
# This binds the "e" key to the command to edit the current URL.
|
||||
|
||||
# The bind_link[1-90] options are for the commands to go to the first 10 links on a page,
|
||||
# typically these are bound to the number keys:
|
||||
# bind_link1 = "1"
|
||||
# bind_link2 = "2"
|
||||
# bind_link3 = "3"
|
||||
# bind_link4 = "4"
|
||||
# bind_link5 = "5"
|
||||
# bind_link6 = "6"
|
||||
# bind_link7 = "7"
|
||||
# bind_link8 = "8"
|
||||
# bind_link9 = "9"
|
||||
# bind_link0 = "0"
|
||||
|
||||
[url-handlers]
|
||||
# Allows setting the commands to run for various URL schemes.
|
||||
|
@ -1,6 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
head -n 3 default.go | tee default.go > /dev/null
|
||||
cat > default.go <<-EOF
|
||||
package config
|
||||
|
||||
//go:generate ./default.sh
|
||||
EOF
|
||||
echo -n 'var defaultConf = []byte(`' >> default.go
|
||||
cat ../default-config.toml >> default.go
|
||||
echo '`)' >> default.go
|
||||
echo '`)' >> default.go
|
||||
|
@ -1,24 +1,237 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/gdamore/tcell"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// KeyToNum returns the number on the user's keyboard they pressed,
|
||||
// using the rune returned when when they press Shift+Num.
|
||||
// The error is not nil if the provided key is invalid.
|
||||
func KeyToNum(key rune) (int, error) {
|
||||
runes := []rune(viper.GetString("keybindings.shift_numbers"))
|
||||
for i := range runes {
|
||||
if key == runes[i] {
|
||||
if i == len(runes)-1 {
|
||||
// Last key is 0, not 10
|
||||
return 0, nil
|
||||
// NOTE: CmdLink[1-90] and CmdTab[1-90] need to be in-order and consecutive
|
||||
// This property is used to simplify key handling in display/display.go
|
||||
type Command int
|
||||
|
||||
const (
|
||||
CmdInvalid Command = 0
|
||||
CmdLink1 = 1
|
||||
CmdLink2 = 2
|
||||
CmdLink3 = 3
|
||||
CmdLink4 = 4
|
||||
CmdLink5 = 5
|
||||
CmdLink6 = 6
|
||||
CmdLink7 = 7
|
||||
CmdLink8 = 8
|
||||
CmdLink9 = 9
|
||||
CmdLink0 = 10
|
||||
CmdTab1 = 11
|
||||
CmdTab2 = 12
|
||||
CmdTab3 = 13
|
||||
CmdTab4 = 14
|
||||
CmdTab5 = 15
|
||||
CmdTab6 = 16
|
||||
CmdTab7 = 17
|
||||
CmdTab8 = 18
|
||||
CmdTab9 = 19
|
||||
CmdTab0 = 20
|
||||
CmdBottom = iota
|
||||
CmdEdit
|
||||
CmdHome
|
||||
CmdBookmarks
|
||||
CmdAddBookmark
|
||||
CmdSave
|
||||
CmdReload
|
||||
CmdBack
|
||||
CmdForward
|
||||
CmdPgup
|
||||
CmdPgdn
|
||||
CmdNewTab
|
||||
CmdCloseTab
|
||||
CmdNextTab
|
||||
CmdPrevTab
|
||||
CmdQuit
|
||||
CmdHelp
|
||||
CmdSub
|
||||
CmdAddSub
|
||||
)
|
||||
|
||||
type keyBinding struct {
|
||||
key tcell.Key
|
||||
mod tcell.ModMask
|
||||
r rune
|
||||
}
|
||||
|
||||
// Map of active keybindings to commands.
|
||||
var bindings map[keyBinding]Command
|
||||
|
||||
// inversion of tcell.KeyNames, used to simplify config parsing.
|
||||
// used by parseBinding() below.
|
||||
var tcellKeys map[string]tcell.Key
|
||||
|
||||
// helper function that takes a single keyBinding object and returns
|
||||
// a string in the format used by the configuration file. Support
|
||||
// function for GetKeyBinding(), used to make the help panel helpful.
|
||||
func keyBindingToString(kb keyBinding) (string, bool) {
|
||||
var prefix string = ""
|
||||
|
||||
if kb.mod&tcell.ModAlt == tcell.ModAlt {
|
||||
prefix = "Alt-"
|
||||
}
|
||||
|
||||
if kb.key == tcell.KeyRune {
|
||||
if kb.r == ' ' {
|
||||
return prefix + "Space", true
|
||||
}
|
||||
return prefix + string(kb.r), true
|
||||
}
|
||||
s, ok := tcell.KeyNames[kb.key]
|
||||
if ok {
|
||||
return prefix + s, true
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
// Get all keybindings for a Command as a string.
|
||||
// Used by the help panel so bindable keys display with their
|
||||
// bound values rather than hardcoded defaults.
|
||||
func GetKeyBinding(cmd Command) string {
|
||||
var s string = ""
|
||||
for kb, c := range bindings {
|
||||
if c == cmd {
|
||||
t, ok := keyBindingToString(kb)
|
||||
if ok {
|
||||
s += t + ", "
|
||||
}
|
||||
return i + 1, nil
|
||||
}
|
||||
}
|
||||
return -1, errors.New("provided key is invalid") //nolint:goerr113
|
||||
|
||||
if len(s) > 0 {
|
||||
return s[:len(s)-2]
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Parse a single keybinding string and add it to the binding map
|
||||
func parseBinding(cmd Command, binding string) {
|
||||
var k tcell.Key
|
||||
var m tcell.ModMask = 0
|
||||
var r rune = 0
|
||||
|
||||
if strings.HasPrefix(binding, "Alt-") {
|
||||
m = tcell.ModAlt
|
||||
binding = binding[4:]
|
||||
}
|
||||
|
||||
if len(binding) == 1 {
|
||||
k = tcell.KeyRune
|
||||
r = []rune(binding)[0]
|
||||
} else if len(binding) == 0 {
|
||||
return
|
||||
} else if binding == "Space" {
|
||||
k = tcell.KeyRune
|
||||
r = ' '
|
||||
} else {
|
||||
var ok bool
|
||||
k, ok = tcellKeys[binding]
|
||||
if !ok { // Bad keybinding! Quietly ignore...
|
||||
return
|
||||
}
|
||||
if strings.HasPrefix(binding, "Ctrl") {
|
||||
m += tcell.ModCtrl
|
||||
}
|
||||
}
|
||||
|
||||
bindings[keyBinding{k, m, r}] = cmd
|
||||
}
|
||||
|
||||
// Generate the bindings map from the TOML configuration file.
|
||||
// Called by config.Init()
|
||||
func KeyInit() {
|
||||
configBindings := map[Command]string{
|
||||
CmdLink1: "keybindings.bind_link1",
|
||||
CmdLink2: "keybindings.bind_link2",
|
||||
CmdLink3: "keybindings.bind_link3",
|
||||
CmdLink4: "keybindings.bind_link4",
|
||||
CmdLink5: "keybindings.bind_link5",
|
||||
CmdLink6: "keybindings.bind_link6",
|
||||
CmdLink7: "keybindings.bind_link7",
|
||||
CmdLink8: "keybindings.bind_link8",
|
||||
CmdLink9: "keybindings.bind_link9",
|
||||
CmdLink0: "keybindings.bind_link0",
|
||||
CmdBottom: "keybindings.bind_bottom",
|
||||
CmdEdit: "keybindings.bind_edit",
|
||||
CmdHome: "keybindings.bind_home",
|
||||
CmdBookmarks: "keybindings.bind_bookmarks",
|
||||
CmdAddBookmark: "keybindings.bind_add_bookmark",
|
||||
CmdSave: "keybindings.bind_save",
|
||||
CmdReload: "keybindings.bind_reload",
|
||||
CmdBack: "keybindings.bind_back",
|
||||
CmdForward: "keybindings.bind_forward",
|
||||
CmdPgup: "keybindings.bind_pgup",
|
||||
CmdPgdn: "keybindings.bind_pgdn",
|
||||
CmdNewTab: "keybindings.bind_new_tab",
|
||||
CmdCloseTab: "keybindings.bind_close_tab",
|
||||
CmdNextTab: "keybindings.bind_next_tab",
|
||||
CmdPrevTab: "keybindings.bind_prev_tab",
|
||||
CmdQuit: "keybindings.bind_quit",
|
||||
CmdHelp: "keybindings.bind_help",
|
||||
CmdSub: "keybindings.bind_sub",
|
||||
CmdAddSub: "keybindings.bind_add_sub",
|
||||
}
|
||||
// This is split off to allow shift_numbers to override bind_tab[1-90]
|
||||
// (This is needed for older configs so that the default bind_tab values
|
||||
// aren't used)
|
||||
configTabNBindings := map[Command]string{
|
||||
CmdTab1: "keybindings.bind_tab1",
|
||||
CmdTab2: "keybindings.bind_tab2",
|
||||
CmdTab3: "keybindings.bind_tab3",
|
||||
CmdTab4: "keybindings.bind_tab4",
|
||||
CmdTab5: "keybindings.bind_tab5",
|
||||
CmdTab6: "keybindings.bind_tab6",
|
||||
CmdTab7: "keybindings.bind_tab7",
|
||||
CmdTab8: "keybindings.bind_tab8",
|
||||
CmdTab9: "keybindings.bind_tab9",
|
||||
CmdTab0: "keybindings.bind_tab0",
|
||||
}
|
||||
tcellKeys = make(map[string]tcell.Key)
|
||||
bindings = make(map[keyBinding]Command)
|
||||
|
||||
for k, kname := range tcell.KeyNames {
|
||||
tcellKeys[kname] = k
|
||||
}
|
||||
|
||||
for c, allb := range configBindings {
|
||||
for _, b := range viper.GetStringSlice(allb) {
|
||||
parseBinding(c, b)
|
||||
}
|
||||
}
|
||||
|
||||
// Backwards compatibility with the old shift_numbers config line.
|
||||
shiftNumbers := []rune(viper.GetString("keybindings.shift_numbers"))
|
||||
if len(shiftNumbers) > 0 && len(shiftNumbers) <= 10 {
|
||||
for i, r := range shiftNumbers {
|
||||
bindings[keyBinding{tcell.KeyRune, 0, r}] = CmdTab1 + Command(i)
|
||||
}
|
||||
} else {
|
||||
for c, allb := range configTabNBindings {
|
||||
for _, b := range viper.GetStringSlice(allb) {
|
||||
parseBinding(c, b)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Used by the display package to turn a tcell.EventKey into a Command
|
||||
func TranslateKeyEvent(e *tcell.EventKey) Command {
|
||||
var ok bool
|
||||
var cmd Command
|
||||
k := e.Key()
|
||||
if k == tcell.KeyRune {
|
||||
cmd, ok = bindings[keyBinding{k, e.Modifiers(), e.Rune()}]
|
||||
} else { // Sometimes tcell sets e.Rune() on non-KeyRune events.
|
||||
cmd, ok = bindings[keyBinding{k, e.Modifiers(), 0}]
|
||||
}
|
||||
if ok {
|
||||
return cmd
|
||||
}
|
||||
return CmdInvalid
|
||||
}
|
||||
|
@ -87,12 +87,51 @@ emoji_favicons = false
|
||||
|
||||
|
||||
[keybindings]
|
||||
# In the future there will be more settings here.
|
||||
# If you have a non-US keyboard, use bind_tab1 through bind_tab0 to
|
||||
# setup the shift-number bindings: Eg, for US keyboards (the default):
|
||||
# bind_tab1 = "!"
|
||||
# bind_tab2 = "@"
|
||||
# bind_tab3 = "#"
|
||||
# bind_tab4 = "$"
|
||||
# bind_tab5 = "%"
|
||||
# bind_tab6 = "^"
|
||||
# bind_tab7 = "&"
|
||||
# bind_tab8 = "*"
|
||||
# bind_tab9 = "("
|
||||
# bind_tab0 = ")"
|
||||
|
||||
# Hold down shift and press the numbers on your keyboard (1,2,3,4,5,6,7,8,9,0) to set this up.
|
||||
# It is default set to be accurate for US keyboards.
|
||||
shift_numbers = "!@#$%^&*()"
|
||||
# Whitespace is not allowed in any of the keybindings! Use 'Space' and 'Tab' to bind to those keys.
|
||||
# Multiple keys can be bound to one command, just use a TOML array.
|
||||
# To add the Alt modifier, the binding must start with Alt-, should be reasonably universal
|
||||
# Ctrl- won't work on all keys, see this for a list:
|
||||
# https://github.com/gdamore/tcell/blob/cb1e5d6fa606/key.go#L83
|
||||
|
||||
# An example of a TOML array for multiple keys being bound to one command is the default
|
||||
# binding for reload:
|
||||
# bind_reload = ["R","Ctrl-R"]
|
||||
# One thing to note here is that "R" is capitalization sensitive, so it means shift-r.
|
||||
# "Ctrl-R" means both ctrl-r and ctrl-shift-R (this is a quirk of what ctrl-r means on
|
||||
# an ANSI terminal)
|
||||
|
||||
# The default binding for opening the bottom bar for entering a URL or link number is:
|
||||
# bind_bottom = "Space"
|
||||
# This is how to get the Spacebar as a keybinding, if you try to use " ", it won't work.
|
||||
# And, finally, an example of a simple, unmodified character is:
|
||||
# bind_edit = "e"
|
||||
# This binds the "e" key to the command to edit the current URL.
|
||||
|
||||
# The bind_link[1-90] options are for the commands to go to the first 10 links on a page,
|
||||
# typically these are bound to the number keys:
|
||||
# bind_link1 = "1"
|
||||
# bind_link2 = "2"
|
||||
# bind_link3 = "3"
|
||||
# bind_link4 = "4"
|
||||
# bind_link5 = "5"
|
||||
# bind_link6 = "6"
|
||||
# bind_link7 = "7"
|
||||
# bind_link8 = "8"
|
||||
# bind_link9 = "9"
|
||||
# bind_link0 = "0"
|
||||
|
||||
[url-handlers]
|
||||
# Allows setting the commands to run for various URL schemes.
|
||||
|
@ -272,43 +272,36 @@ func Init(version, commit, builtBy string) {
|
||||
return event
|
||||
}
|
||||
|
||||
// To add a configurable global key command, you'll need to update one of
|
||||
// the two switch statements here. You'll also need to add an enum entry in
|
||||
// config/keybindings.go, update KeyInit() in config/keybindings.go, add a default
|
||||
// keybinding in config/config.go and update the help panel in display/help.go
|
||||
|
||||
cmd := config.TranslateKeyEvent(event)
|
||||
if tabs[curTab].mode == tabModeDone {
|
||||
// All the keys and operations that can only work while NOT loading
|
||||
|
||||
// History arrow keys
|
||||
if event.Modifiers() == tcell.ModAlt {
|
||||
if event.Key() == tcell.KeyLeft {
|
||||
histBack(tabs[curTab])
|
||||
return nil
|
||||
}
|
||||
if event.Key() == tcell.KeyRight {
|
||||
histForward(tabs[curTab])
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
//nolint:exhaustive
|
||||
switch event.Key() {
|
||||
case tcell.KeyCtrlR:
|
||||
switch cmd {
|
||||
case config.CmdReload:
|
||||
Reload()
|
||||
return nil
|
||||
case tcell.KeyCtrlH:
|
||||
case config.CmdHome:
|
||||
URL(viper.GetString("a-general.home"))
|
||||
return nil
|
||||
case tcell.KeyCtrlB:
|
||||
case config.CmdBookmarks:
|
||||
Bookmarks(tabs[curTab])
|
||||
tabs[curTab].addToHistory("about:bookmarks")
|
||||
return nil
|
||||
case tcell.KeyCtrlD:
|
||||
case config.CmdAddBookmark:
|
||||
go addBookmark()
|
||||
return nil
|
||||
case tcell.KeyPgUp:
|
||||
case config.CmdPgup:
|
||||
tabs[curTab].pageUp()
|
||||
return nil
|
||||
case tcell.KeyPgDn:
|
||||
case config.CmdPgdn:
|
||||
tabs[curTab].pageDown()
|
||||
return nil
|
||||
case tcell.KeyCtrlS:
|
||||
case config.CmdSave:
|
||||
if tabs[curTab].hasContent() {
|
||||
savePath, err := downloadPage(tabs[curTab].page)
|
||||
if err != nil {
|
||||
@ -320,66 +313,48 @@ func Init(version, commit, builtBy string) {
|
||||
Info("The current page has no content, so it couldn't be downloaded.")
|
||||
}
|
||||
return nil
|
||||
case tcell.KeyCtrlA:
|
||||
case config.CmdBottom:
|
||||
// Space starts typing, like Bombadillo
|
||||
bottomBar.SetLabel("[::b]URL/Num./Search: [::-]")
|
||||
bottomBar.SetText("")
|
||||
// Don't save bottom bar, so that whenever you switch tabs, it's not in that mode
|
||||
App.SetFocus(bottomBar)
|
||||
return nil
|
||||
case config.CmdEdit:
|
||||
// Letter e allows to edit current URL
|
||||
bottomBar.SetLabel("[::b]Edit URL: [::-]")
|
||||
bottomBar.SetText(tabs[curTab].page.URL)
|
||||
App.SetFocus(bottomBar)
|
||||
return nil
|
||||
case config.CmdBack:
|
||||
histBack(tabs[curTab])
|
||||
return nil
|
||||
case config.CmdForward:
|
||||
histForward(tabs[curTab])
|
||||
return nil
|
||||
case config.CmdSub:
|
||||
Subscriptions(tabs[curTab], "about:subscriptions")
|
||||
tabs[curTab].addToHistory("about:subscriptions")
|
||||
return nil
|
||||
case tcell.KeyCtrlX:
|
||||
case config.CmdAddSub:
|
||||
go addSubscription()
|
||||
return nil
|
||||
case tcell.KeyRune:
|
||||
// Regular key was sent
|
||||
switch string(event.Rune()) {
|
||||
case " ":
|
||||
// Space starts typing, like Bombadillo
|
||||
bottomBar.SetLabel("[::b]URL/Num./Search: [::-]")
|
||||
bottomBar.SetText("")
|
||||
// Don't save bottom bar, so that whenever you switch tabs, it's not in that mode
|
||||
App.SetFocus(bottomBar)
|
||||
return nil
|
||||
case "e":
|
||||
// Letter e allows to edit current URL
|
||||
bottomBar.SetLabel("[::b]Edit URL: [::-]")
|
||||
bottomBar.SetText(tabs[curTab].page.URL)
|
||||
App.SetFocus(bottomBar)
|
||||
return nil
|
||||
case "R":
|
||||
Reload()
|
||||
return nil
|
||||
case "b":
|
||||
histBack(tabs[curTab])
|
||||
return nil
|
||||
case "f":
|
||||
histForward(tabs[curTab])
|
||||
return nil
|
||||
case "u":
|
||||
tabs[curTab].pageUp()
|
||||
return nil
|
||||
case "d":
|
||||
tabs[curTab].pageDown()
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Number key: 1-9, 0
|
||||
i, err := strconv.Atoi(string(event.Rune()))
|
||||
if err == nil {
|
||||
if i == 0 {
|
||||
i = 10 // 0 key is for link 10
|
||||
}
|
||||
if i <= len(tabs[curTab].page.Links) && i > 0 {
|
||||
// It's a valid link number
|
||||
followLink(tabs[curTab], tabs[curTab].page.URL, tabs[curTab].page.Links[i-1])
|
||||
return nil
|
||||
}
|
||||
// Number key: 1-9, 0, LINK1-LINK10
|
||||
if cmd >= config.CmdLink1 && cmd <= config.CmdLink0 {
|
||||
if int(cmd) <= len(tabs[curTab].page.Links) {
|
||||
// It's a valid link number
|
||||
followLink(tabs[curTab], tabs[curTab].page.URL, tabs[curTab].page.Links[cmd-1])
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// All the keys and operations that can work while a tab IS loading
|
||||
|
||||
//nolint:exhaustive
|
||||
switch event.Key() {
|
||||
case tcell.KeyCtrlT:
|
||||
switch cmd {
|
||||
case config.CmdNewTab:
|
||||
if tabs[curTab].page.Mode == structs.ModeLinkSelect {
|
||||
next, err := resolveRelLink(tabs[curTab], tabs[curTab].page.URL, tabs[curTab].page.Selected)
|
||||
if err != nil {
|
||||
@ -392,45 +367,33 @@ func Init(version, commit, builtBy string) {
|
||||
NewTab()
|
||||
}
|
||||
return nil
|
||||
case tcell.KeyCtrlW:
|
||||
case config.CmdCloseTab:
|
||||
CloseTab()
|
||||
return nil
|
||||
case tcell.KeyCtrlQ:
|
||||
case config.CmdQuit:
|
||||
Stop()
|
||||
return nil
|
||||
case tcell.KeyCtrlC:
|
||||
Stop()
|
||||
return nil
|
||||
case tcell.KeyF1:
|
||||
case config.CmdPrevTab:
|
||||
// Wrap around, allow for modulo with negative numbers
|
||||
n := NumTabs()
|
||||
SwitchTab((((curTab - 1) % n) + n) % n)
|
||||
return nil
|
||||
case tcell.KeyF2:
|
||||
case config.CmdNextTab:
|
||||
SwitchTab((curTab + 1) % NumTabs())
|
||||
return nil
|
||||
case tcell.KeyRune:
|
||||
// Regular key was sent
|
||||
case config.CmdHelp:
|
||||
Help()
|
||||
return nil
|
||||
}
|
||||
|
||||
if num, err := config.KeyToNum(event.Rune()); err == nil {
|
||||
// It's a Shift+Num key
|
||||
if num == 0 {
|
||||
// Zero key goes to the last tab
|
||||
SwitchTab(NumTabs() - 1)
|
||||
} else {
|
||||
SwitchTab(num - 1)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
switch string(event.Rune()) {
|
||||
case "q":
|
||||
Stop()
|
||||
return nil
|
||||
case "?":
|
||||
Help()
|
||||
return nil
|
||||
if cmd >= config.CmdTab1 && cmd <= config.CmdTab0 {
|
||||
if cmd == config.CmdTab0 {
|
||||
// Zero key goes to the last tab
|
||||
SwitchTab(NumTabs() - 1)
|
||||
} else {
|
||||
SwitchTab(int(cmd - config.CmdTab1))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Let another element handle the event, it's not a special global key
|
||||
|
@ -1,10 +1,12 @@
|
||||
package display
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gdamore/tcell"
|
||||
"github.com/makeworld-the-better-one/amfora/config"
|
||||
"gitlab.com/tslocum/cview"
|
||||
)
|
||||
|
||||
@ -12,41 +14,39 @@ var helpCells = strings.TrimSpace(`
|
||||
?|Bring up this help. You can scroll!
|
||||
Esc|Leave the help
|
||||
Arrow keys, h/j/k/l|Scroll and move a page.
|
||||
PgUp, u|Go up a page in document
|
||||
PgDn, d|Go down a page in document
|
||||
%s|Go up a page in document
|
||||
%s|Go down a page in document
|
||||
g|Go to top of document
|
||||
G|Go to bottom of document
|
||||
Tab|Navigate to the next item in a popup.
|
||||
Shift-Tab|Navigate to the previous item in a popup.
|
||||
b, Alt-Left|Go back in the history
|
||||
f, Alt-Right|Go forward in the history
|
||||
spacebar|Open bar at the bottom - type a URL, link number, search term.
|
||||
%s|Go back in the history
|
||||
%s|Go forward in the history
|
||||
%s|Open bar at the bottom - type a URL, link number, search term.
|
||||
|You can also type two dots (..) to go up a directory in the URL.
|
||||
|Typing new:N will open link number N in a new tab
|
||||
|instead of the current one.
|
||||
Numbers|Go to links 1-10 respectively.
|
||||
e|Edit current URL
|
||||
%s|Go to links 1-10 respectively.
|
||||
%s|Edit current URL
|
||||
Enter, Tab|On a page this will start link highlighting.
|
||||
|Press Tab and Shift-Tab to pick different links.
|
||||
|Press Enter again to go to one, or Esc to stop.
|
||||
Shift-NUMBER|Go to a specific tab.
|
||||
Shift-0, )|Go to the last tab.
|
||||
F1|Previous tab
|
||||
F2|Next tab
|
||||
Ctrl-H|Go home
|
||||
Ctrl-T|New tab, or if a link is selected,
|
||||
%s|Go to a specific tab. (Default: Shift-NUMBER)
|
||||
%s|Go to the last tab.
|
||||
%s|Previous tab
|
||||
%s|Next tab
|
||||
%s|Go home
|
||||
%s|New tab, or if a link is selected,
|
||||
|this will open the link in a new tab.
|
||||
Ctrl-W|Close tab. For now, only the right-most tab can be closed.
|
||||
Ctrl-R, R|Reload a page, discarding the cached version.
|
||||
%s|Close tab. For now, only the right-most tab can be closed.
|
||||
%s|Reload a page, discarding the cached version.
|
||||
|This can also be used if you resize your terminal.
|
||||
Ctrl-B|View bookmarks
|
||||
Ctrl-D|Add, change, or remove a bookmark for the current page.
|
||||
Ctrl-S|Save the current page to your downloads.
|
||||
Ctrl-A|View subscriptions
|
||||
Ctrl-X|Add or update a subscription
|
||||
q, Ctrl-Q|Quit
|
||||
Ctrl-C|Hard quit. This can be used when in the middle of downloading,
|
||||
|for example.
|
||||
%s|View bookmarks
|
||||
%s|Add, change, or remove a bookmark for the current page.
|
||||
%s|Save the current page to your downloads.
|
||||
%s|View subscriptions
|
||||
%s|Add or update a subscription
|
||||
%s|Quit
|
||||
`)
|
||||
|
||||
var helpTable = cview.NewTable().
|
||||
@ -71,6 +71,36 @@ func helpInit() {
|
||||
App.Draw()
|
||||
}
|
||||
})
|
||||
|
||||
tabKeys := fmt.Sprintf("%s to %s", strings.Split(config.GetKeyBinding(config.CmdTab1), ",")[0],
|
||||
strings.Split(config.GetKeyBinding(config.CmdTab9), ",")[0])
|
||||
linkKeys := fmt.Sprintf("%s to %s", strings.Split(config.GetKeyBinding(config.CmdLink1), ",")[0],
|
||||
strings.Split(config.GetKeyBinding(config.CmdLink0), ",")[0])
|
||||
|
||||
helpCells = fmt.Sprintf(helpCells,
|
||||
config.GetKeyBinding(config.CmdPgup),
|
||||
config.GetKeyBinding(config.CmdPgdn),
|
||||
config.GetKeyBinding(config.CmdBack),
|
||||
config.GetKeyBinding(config.CmdForward),
|
||||
config.GetKeyBinding(config.CmdBottom),
|
||||
linkKeys,
|
||||
config.GetKeyBinding(config.CmdEdit),
|
||||
tabKeys,
|
||||
config.GetKeyBinding(config.CmdTab0),
|
||||
config.GetKeyBinding(config.CmdPrevTab),
|
||||
config.GetKeyBinding(config.CmdNextTab),
|
||||
config.GetKeyBinding(config.CmdHome),
|
||||
config.GetKeyBinding(config.CmdNewTab),
|
||||
config.GetKeyBinding(config.CmdCloseTab),
|
||||
config.GetKeyBinding(config.CmdReload),
|
||||
config.GetKeyBinding(config.CmdBookmarks),
|
||||
config.GetKeyBinding(config.CmdAddBookmark),
|
||||
config.GetKeyBinding(config.CmdSave),
|
||||
config.GetKeyBinding(config.CmdSub),
|
||||
config.GetKeyBinding(config.CmdAddSub),
|
||||
config.GetKeyBinding(config.CmdQuit),
|
||||
)
|
||||
|
||||
rows := strings.Count(helpCells, "\n") + 1
|
||||
cells := strings.Split(
|
||||
strings.ReplaceAll(helpCells, "\n", "|"),
|
||||
|
Loading…
Reference in New Issue
Block a user