Skip to content

Commit

Permalink
adding tabModeSearch to search in page (#240)
Browse files Browse the repository at this point in the history
* adding tabModeSearch to search in page

* skipping tag regions in text search

* formatted and fixed linter errors

* fixed non-exhaustive switch case

* adding keybindings to default-config.toml and help.go

* change search keybindings to vim/less defaults

* updated tag regex and compiled it once globally

* use existing bottomBar for search

* adding resetSearch helper function

* remove redundant bool

* go fmt

---------

Co-authored-by: Robin Schubert <[email protected]>
Co-authored-by: makeworld <[email protected]>
  • Loading branch information
3 people authored Dec 19, 2024
1 parent a8f2e0f commit 509d789
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 1 deletion.
3 changes: 3 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,9 @@ func Init() error {
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.bind_search", "/")
viper.SetDefault("keybindings.bind_next_match", "n")
viper.SetDefault("keybindings.bind_prev_match", "N")
viper.SetDefault("keybindings.shift_numbers", "")
viper.SetDefault("keybindings.bind_url_handler_open", "Ctrl-U")
viper.SetDefault("url-handlers.other", "default")
Expand Down
5 changes: 5 additions & 0 deletions config/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,11 @@ underline = true
# bind_end: same but the for the end (bottom left)
# bind_url_handler_open: Open highlighted URL with URL handler (#143)
# Search
# bind_search = "/"
# bind_next_match = "n"
# bind_prev_match = "N"
[url-handlers]
# Allows setting the commands to run for various URL schemes.
# E.g. to open FTP URLs with FileZilla set the following key:
Expand Down
6 changes: 6 additions & 0 deletions config/keybindings.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ const (
CmdBeginning
CmdEnd
CmdURLHandlerOpen // See #143
CmdSearch
CmdNextMatch
CmdPrevMatch
)

type keyBinding struct {
Expand Down Expand Up @@ -200,6 +203,9 @@ func KeyInit() {
CmdBeginning: "keybindings.bind_beginning",
CmdEnd: "keybindings.bind_end",
CmdURLHandlerOpen: "keybindings.bind_url_handler_open",
CmdSearch: "keybindings.bind_search",
CmdNextMatch: "keybindings.bind_next_match",
CmdPrevMatch: "keybindings.bind_prev_match",
}
// 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
Expand Down
5 changes: 5 additions & 0 deletions default-config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,11 @@ underline = true
# bind_end: same but the for the end (bottom left)
# bind_url_handler_open: Open highlighted URL with URL handler (#143)

# Search
# bind_search = "/"
# bind_next_match = "n"
# bind_prev_match = "N"

[url-handlers]
# Allows setting the commands to run for various URL schemes.
# E.g. to open FTP URLs with FileZilla set the following key:
Expand Down
108 changes: 108 additions & 0 deletions display/display.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ var termH int
// The user input and URL display bar at the bottom
var bottomBar = cview.NewInputField()

var originalText []byte
var tagsRegex = regexp.MustCompile(`\[[a-zA-Z0-9_,;: \-\."#]+[^\[]*\]`)
var searchMode = false
var searchString = ""
var bottomBarText = ""
var matches = 0
var curMatch = 0

// When the bottom bar string has a space, this regex decides whether it's
// a non-encoded URL or a search string.
// See this comment for details:
Expand Down Expand Up @@ -139,6 +147,9 @@ func Init(version, commit, builtBy string) {
// Reset func to set the bottomBar back to what it was before
// Use for errors.
reset := func() {
if searchMode {
resetSearch()
}
bottomBar.SetLabel("")
tabs[tab].applyAll()
App.SetFocus(tabs[tab].view)
Expand All @@ -147,6 +158,63 @@ func Init(version, commit, builtBy string) {
//nolint:exhaustive
switch key {
case tcell.KeyEnter:

if searchMode {
// Escape the search string to not find regexp symbols
searchString = regexp.QuoteMeta(bottomBar.GetText())

if strings.TrimSpace(searchString) == "" {
// Ignore
reset()
return
}

if tabs[tab].mode != tabModeSearch {
originalText = tabs[curTab].view.GetBytes(false)
}
tabs[tab].mode = tabModeSearch

// find all positions of the search string
searchRegex := regexp.MustCompile(searchString)
searchIdx := searchRegex.FindAllIndex(originalText, -1)

// find all positions of tags
tagsIdx := tagsRegex.FindAllIndex(originalText, -1)

text := make([]byte, 0)
matches = 0
lastMatch := 0

// loops through all occurrences and check if they
// discard if they lie within tags.
// []byte text is build from the original text buffer
// with the actual search strings replaced by tagged regions
// to highlight.
for i, match := range searchIdx {
for _, tag := range tagsIdx {
if match[0] >= tag[0] && match[1] <= tag[1] {
break
}
}

matches++
text = append(text, originalText[lastMatch:match[0]]...)
replacement := []byte(fmt.Sprint(`["search-`, i, `"]`, searchString, `[""]`))
text = append(text, replacement...)
lastMatch = match[0] + len(searchString)
}
text = append(text, originalText[lastMatch:]...)

tabs[curTab].view.SetBytes(text)

curMatch = 0
tabs[curTab].view.Highlight(fmt.Sprint("search-", "0"))
tabs[curTab].view.ScrollToHighlight()
App.SetFocus(tabs[tab].view)

return
}

// Figure out whether it's a URL, link number, or search
// And send out a request

Expand Down Expand Up @@ -305,6 +373,31 @@ func Init(version, commit, builtBy string) {
// keybinding in config/config.go and update the help panel in display/help.go

cmd := config.TranslateKeyEvent(event)
if tabs[curTab].mode == tabModeSearch {
switch cmd {
case config.CmdNextMatch:
if curMatch < (matches - 1) {
curMatch++
tabs[curTab].view.Highlight(fmt.Sprint("search-", curMatch))
}
tabs[curTab].view.ScrollToHighlight()
return nil
case config.CmdPrevMatch:
if curMatch > 0 {
curMatch--
tabs[curTab].view.Highlight(fmt.Sprint("search-", curMatch))
}
tabs[curTab].view.ScrollToHighlight()
return nil
case config.CmdInvalid:
if event.Key() == tcell.KeyEsc {
resetSearch()
return nil
}
}
return event
}

if tabs[curTab].mode == tabModeDone {
// All the keys and operations that can only work while NOT loading
//nolint:exhaustive
Expand All @@ -322,6 +415,13 @@ func Init(version, commit, builtBy string) {
// Don't save bottom bar, so that whenever you switch tabs, it's not in that mode
App.SetFocus(bottomBar)
return nil
case config.CmdSearch:
bottomBar.SetLabel("[::b]Search: [::-]")
bottomBarText = bottomBar.GetText()
bottomBar.SetText("")
searchMode = true
App.SetFocus(bottomBar)
return nil
case config.CmdEdit:
// Letter e allows to edit current URL
bottomBar.SetLabel("[::b]Edit URL: [::-]")
Expand Down Expand Up @@ -578,3 +678,11 @@ func renderPageFromString(str string) *structs.Page {
func NumTabs() int {
return len(tabs)
}

func resetSearch() {
tabs[curTab].view.SetBytes(originalText)
tabs[curTab].mode = tabModeDone
searchMode = false
bottomBar.SetLabel("")
bottomBar.SetText(bottomBarText)
}
6 changes: 6 additions & 0 deletions display/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ var helpCells = strings.TrimSpace(
"%s\tSave the current page to your downloads.\n" +
"%s\tView subscriptions\n" +
"%s\tAdd or update a subscription\n" +
"%s\tSearch the page content for a string\n" +
"%s\tFind next search match\n" +
"%s\tFind previous search match\n" +
"%s\tQuit\n")

var helpTable = cview.NewTextView()
Expand Down Expand Up @@ -110,6 +113,9 @@ func helpInit() {
config.GetKeyBinding(config.CmdSave),
config.GetKeyBinding(config.CmdSub),
config.GetKeyBinding(config.CmdAddSub),
config.GetKeyBinding(config.CmdSearch),
config.GetKeyBinding(config.CmdNextMatch),
config.GetKeyBinding(config.CmdPrevMatch),
config.GetKeyBinding(config.CmdQuit),
)

Expand Down
1 change: 1 addition & 0 deletions display/tab.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type tabMode int
const (
tabModeDone tabMode = iota
tabModeLoading
tabModeSearch
)

// tabHistoryPageCache is fields from the Page struct, cached here to solve #122
Expand Down
2 changes: 1 addition & 1 deletion display/thanks.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//nolint
// nolint
package display

//go:generate ./thanks.sh
Expand Down

0 comments on commit 509d789

Please sign in to comment.