1
0
mirror of https://github.com/makew0rld/amfora.git synced 2024-11-03 02:37:23 -05:00

🐛 Capture all scrolling keys

This commit is contained in:
makeworld 2021-05-14 18:09:04 -04:00
parent 4da7816a3a
commit ed36eee83c
8 changed files with 147 additions and 96 deletions

26
cache/page.go vendored
View File

@ -13,7 +13,7 @@ var pages = make(map[string]*structs.Page) // The actual cache
var urls = make([]string, 0) // Duplicate of the keys in the `pages` map, but in order of being added
var maxPages = 0 // Max allowed number of pages in cache
var maxSize = 0 // Max allowed cache size in bytes
var lock = sync.RWMutex{}
var mu = sync.RWMutex{}
var timeout = time.Duration(0)
// SetMaxPages sets the max number of pages the cache can hold.
@ -79,8 +79,8 @@ func AddPage(p *structs.Page) {
RemovePage(urls[0])
}
lock.Lock()
defer lock.Unlock()
mu.Lock()
defer mu.Unlock()
pages[p.URL] = p
// Remove the URL if it was already there, then add it to the end
removeURL(p.URL)
@ -90,24 +90,24 @@ func AddPage(p *structs.Page) {
// RemovePage will remove a page from the cache.
// Even if the page doesn't exist there will be no error.
func RemovePage(url string) {
lock.Lock()
defer lock.Unlock()
mu.Lock()
defer mu.Unlock()
delete(pages, url)
removeURL(url)
}
// ClearPages removes all pages from the cache.
func ClearPages() {
lock.Lock()
defer lock.Unlock()
mu.Lock()
defer mu.Unlock()
pages = make(map[string]*structs.Page)
urls = make([]string, 0)
}
// SizePages returns the approx. current size of the cache in bytes.
func SizePages() int {
lock.RLock()
defer lock.RUnlock()
mu.RLock()
defer mu.RUnlock()
n := 0
for _, page := range pages {
n += page.Size()
@ -116,16 +116,16 @@ func SizePages() int {
}
func NumPages() int {
lock.RLock()
defer lock.RUnlock()
mu.RLock()
defer mu.RUnlock()
return len(pages)
}
// GetPage returns the page struct, and a bool indicating if the page was in the cache or not.
// (nil, false) is returned if the page isn't in the cache.
func GetPage(url string) (*structs.Page, bool) {
lock.RLock()
defer lock.RUnlock()
mu.RLock()
defer mu.RUnlock()
p, ok := pages[url]
if ok && (timeout == 0 || time.Since(p.MadeAt) < timeout) {

View File

@ -248,6 +248,8 @@ func Init() error {
viper.SetDefault("keybindings.bind_tab0", ")")
viper.SetDefault("keybindings.bind_copy_page_url", "C")
viper.SetDefault("keybindings.bind_copy_target_url", "c")
viper.SetDefault("keybindings.bind_beginning", []string{"Home", "g"})
viper.SetDefault("keybindings.bind_end", []string{"End", "G"})
viper.SetDefault("keybindings.shift_numbers", "")
viper.SetDefault("url-handlers.other", "off")
viper.SetDefault("cache.max_size", 0)

View File

@ -164,6 +164,8 @@ scrollbar = "auto"
# bind_add_sub
# bind_copy_page_url
# bind_copy_target_url
# bind_beginning: moving to beginning of page (top left)
# bind_end: same but the for the end (bottom left)
[url-handlers]
# Allows setting the commands to run for various URL schemes.

View File

@ -59,6 +59,8 @@ const (
CmdAddSub
CmdCopyPageURL
CmdCopyTargetURL
CmdBeginning
CmdEnd
)
type keyBinding struct {
@ -189,6 +191,8 @@ func KeyInit() {
CmdAddSub: "keybindings.bind_add_sub",
CmdCopyPageURL: "keybindings.bind_copy_page_url",
CmdCopyTargetURL: "keybindings.bind_copy_target_url",
CmdBeginning: "keybindings.bind_beginning",
CmdEnd: "keybindings.bind_end",
}
// 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
@ -212,10 +216,15 @@ func KeyInit() {
tcellKeys[kname] = k
}
// Set cview navigation keys to use user-set ones
cview.Keys.MoveUp2 = viper.GetStringSlice(configBindings[CmdMoveUp])
cview.Keys.MoveDown2 = viper.GetStringSlice(configBindings[CmdMoveDown])
cview.Keys.MoveLeft2 = viper.GetStringSlice(configBindings[CmdMoveLeft])
cview.Keys.MoveRight2 = viper.GetStringSlice(configBindings[CmdMoveRight])
cview.Keys.MoveFirst = viper.GetStringSlice(configBindings[CmdBeginning])
cview.Keys.MoveFirst2 = nil
cview.Keys.MoveLast = viper.GetStringSlice(configBindings[CmdEnd])
cview.Keys.MoveLast2 = nil
for c, allb := range configBindings {
for _, b := range viper.GetStringSlice(allb) {

View File

@ -161,6 +161,8 @@ scrollbar = "auto"
# bind_add_sub
# bind_copy_page_url
# bind_copy_target_url
# bind_beginning: moving to beginning of page (top left)
# bind_end: same but the for the end (bottom left)
[url-handlers]
# Allows setting the commands to run for various URL schemes.

View File

@ -9,7 +9,6 @@ import (
"sync"
"code.rocketnine.space/tslocum/cview"
"github.com/atotto/clipboard"
"github.com/gdamore/tcell/v2"
"github.com/makeworld-the-better-one/amfora/cache"
"github.com/makeworld-the-better-one/amfora/config"
@ -302,31 +301,6 @@ func Init(version, commit, builtBy string) {
case config.CmdHome:
URL(viper.GetString("a-general.home"))
return nil
case config.CmdBookmarks:
Bookmarks(tabs[curTab])
tabs[curTab].addToHistory("about:bookmarks")
return nil
case config.CmdAddBookmark:
go addBookmark()
return nil
case config.CmdPgup:
tabs[curTab].pageUp()
return nil
case config.CmdPgdn:
tabs[curTab].pageDown()
return nil
case config.CmdSave:
if tabs[curTab].hasContent() {
savePath, err := downloadPage(tabs[curTab].page)
if err != nil {
Error("Download Error", fmt.Sprintf("Error saving page content: %v", err))
} else {
Info(fmt.Sprintf("Page content saved to %s. ", savePath))
}
} else {
Info("The current page has no content, so it couldn't be downloaded.")
}
return nil
case config.CmdBottom:
// Space starts typing, like Bombadillo
bottomBar.SetLabel("[::b]URL/Num./Search: [::-]")
@ -340,58 +314,9 @@ func Init(version, commit, builtBy string) {
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 config.CmdAddSub:
go addSubscription()
return nil
case config.CmdCopyPageURL:
currentURL := tabs[curTab].page.URL
err := clipboard.WriteAll(currentURL)
if err != nil {
Error("Copy Error", err.Error())
return nil
}
return nil
case config.CmdCopyTargetURL:
currentURL := tabs[curTab].page.URL
selectedURL := tabs[curTab].HighlightedURL()
if selectedURL == "" {
return nil
}
u, _ := url.Parse(currentURL)
copiedURL, err := u.Parse(selectedURL)
if err != nil {
err := clipboard.WriteAll(selectedURL)
if err != nil {
Error("Copy Error", err.Error())
return nil
}
return nil
}
err = clipboard.WriteAll(copiedURL.String())
if err != nil {
Error("Copy Error", err.Error())
return nil
}
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
}
}
}

View File

@ -16,8 +16,8 @@ var helpCells = strings.TrimSpace(
"Arrow keys, %s(left)/%s(down)/%s(up)/%s(right)\tScroll and move a page.\n" +
"%s\tGo up a page in document\n" +
"%s\tGo down a page in document\n" +
"g\tGo to top of document\n" +
"G\tGo to bottom of document\n" +
"%s\tGo to top of document\n" +
"%s\tGo to bottom of document\n" +
"Tab\tNavigate to the next item in a popup.\n" +
"Shift-Tab\tNavigate to the previous item in a popup.\n" +
"%s\tGo back in the history\n" +
@ -86,6 +86,8 @@ func helpInit() {
config.GetKeyBinding(config.CmdMoveRight),
config.GetKeyBinding(config.CmdPgup),
config.GetKeyBinding(config.CmdPgdn),
config.GetKeyBinding(config.CmdBeginning),
config.GetKeyBinding(config.CmdEnd),
config.GetKeyBinding(config.CmdBack),
config.GetKeyBinding(config.CmdForward),
config.GetKeyBinding(config.CmdBottom),

View File

@ -1,10 +1,13 @@
package display
import (
"fmt"
"net/url"
"strconv"
"strings"
"code.rocketnine.space/tslocum/cview"
"github.com/atotto/clipboard"
"github.com/gdamore/tcell/v2"
"github.com/makeworld-the-better-one/amfora/config"
"github.com/makeworld-the-better-one/amfora/structs"
@ -124,11 +127,96 @@ func makeNewTab() *tab {
t.view.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
// Capture scrolling and change the left margin size accordingly, see #197
// This was also touched by #222
// This also captures any tab-specific events now
if t.mode != tabModeDone {
// Any events that should be caught when the tab is loading is handled in display.go
return nil
}
cmd := config.TranslateKeyEvent(event)
// Cmds that aren't single row/column scrolling
switch cmd {
case config.CmdBookmarks:
Bookmarks(&t)
t.addToHistory("about:bookmarks")
return nil
case config.CmdAddBookmark:
go addBookmark()
return nil
case config.CmdPgup:
t.pageUp()
return nil
case config.CmdPgdn:
t.pageDown()
return nil
case config.CmdSave:
if t.hasContent() {
savePath, err := downloadPage(t.page)
if err != nil {
Error("Download Error", fmt.Sprintf("Error saving page content: %v", err))
} else {
Info(fmt.Sprintf("Page content saved to %s. ", savePath))
}
} else {
Info("The current page has no content, so it couldn't be downloaded.")
}
return nil
case config.CmdBack:
histBack(&t)
return nil
case config.CmdForward:
histForward(&t)
return nil
case config.CmdSub:
Subscriptions(&t, "about:subscriptions")
tabs[curTab].addToHistory("about:subscriptions")
return nil
case config.CmdCopyPageURL:
currentURL := tabs[curTab].page.URL
err := clipboard.WriteAll(currentURL)
if err != nil {
Error("Copy Error", err.Error())
return nil
}
return nil
case config.CmdCopyTargetURL:
currentURL := t.page.URL
selectedURL := t.HighlightedURL()
if selectedURL == "" {
return nil
}
u, _ := url.Parse(currentURL)
copiedURL, err := u.Parse(selectedURL)
if err != nil {
err := clipboard.WriteAll(selectedURL)
if err != nil {
Error("Copy Error", err.Error())
return nil
}
return nil
}
err = clipboard.WriteAll(copiedURL.String())
if err != nil {
Error("Copy Error", err.Error())
return nil
}
return nil
}
// Number key: 1-9, 0, LINK1-LINK10
if cmd >= config.CmdLink1 && cmd <= config.CmdLink0 {
if int(cmd) <= len(t.page.Links) {
// It's a valid link number
followLink(&t, t.page.URL, t.page.Links[cmd-1])
return nil
}
}
// Scrolling stuff
key := event.Key()
mod := event.Modifiers()
cmd := config.TranslateKeyEvent(event)
height, width := t.view.GetBufferSize()
_, _, boxW, boxH := t.view.GetInnerRect()
@ -175,6 +263,18 @@ func makeNewTab() *tab {
t.page.Row++
}
return event
} else if cmd == config.CmdBeginning {
t.page.Row = 0
// This is required because cview will also set the column (incorrectly)
// if it handles this event itself
t.applyScroll()
App.Draw()
return nil
} else if cmd == config.CmdEnd {
t.page.Row = height
t.applyScroll()
App.Draw()
return nil
} else {
// Some other key, stop processing it
return event
@ -202,14 +302,23 @@ func (t *tab) addToHistory(u string) {
// pageUp scrolls up 75% of the height of the terminal, like Bombadillo.
func (t *tab) pageUp() {
row, col := t.view.GetScrollOffset()
t.view.ScrollTo(row-(termH/4)*3, col)
t.page.Row -= (termH / 4) * 3
if t.page.Row < 0 {
t.page.Row = 0
}
t.applyScroll()
}
// pageDown scrolls down 75% of the height of the terminal, like Bombadillo.
func (t *tab) pageDown() {
row, col := t.view.GetScrollOffset()
t.view.ScrollTo(row+(termH/4)*3, col)
height, _ := t.view.GetBufferSize()
t.page.Row += (termH / 4) * 3
if t.page.Row > height {
t.page.Row = height
}
t.applyScroll()
}
// hasContent returns false when the tab's page is malformed,