From f68996decffa7b4cccaaea1f75ddc0c170bb8ec2 Mon Sep 17 00:00:00 2001 From: sloumdrone Date: Mon, 16 Dec 2019 22:18:28 -0800 Subject: [PATCH] Beginnings of text search... semi-working --- client.go | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- cui/cui.go | 4 +-- page.go | 27 +++++++++++++++++- 3 files changed, 110 insertions(+), 5 deletions(-) diff --git a/client.go b/client.go index b0270ac..d43ca28 100644 --- a/client.go +++ b/client.go @@ -235,6 +235,41 @@ func (c *client) TakeControlInput() { // Toggle bookmark browser focus on/off c.BookMarks.ToggleFocused() c.Draw() + case 'n': + // Next search item + c.ClearMessage() + err := c.NextSearchItem() + if err != nil { + c.SetMessage(err.Error(), false) + c.DrawMessage() + } + case 'N': + // Previous search item + c.ClearMessage() + err := c.PreviousSearchItem() + if err != nil { + c.SetMessage(err.Error(), false) + c.DrawMessage() + } + case '/': + // Search for text + c.ClearMessage() + c.ClearMessageLine() + if c.Options["theme"] == "normal" || c.Options["theme"] == "color" { + fmt.Printf("\033[7m%*.*s\r", c.Width, c.Width, "") + } + entry, err := cui.GetLine("/") + c.ClearMessageLine() + if err != nil { + c.SetMessage(err.Error(), true) + c.DrawMessage() + break + } + err = c.find(entry) + if err != nil { + c.SetMessage(err.Error(), true) + c.DrawMessage() + } case ':', ' ': // Process a command c.ClearMessage() @@ -242,7 +277,7 @@ func (c *client) TakeControlInput() { if c.Options["theme"] == "normal" || c.Options["theme"] == "color" { fmt.Printf("\033[7m%*.*s\r", c.Width, c.Width, "") } - entry, err := cui.GetLine() + entry, err := cui.GetLine(": ") c.ClearMessageLine() if err != nil { c.SetMessage(err.Error(), true) @@ -644,7 +679,7 @@ func (c *client) search(query, url, question string) { fmt.Printf("\033[7m%*.*s\r", c.Width, c.Width, "") } fmt.Print(question) - entry, err = cui.GetLine() + entry, err = cui.GetLine("?") c.ClearMessageLine() if err != nil { c.SetMessage(err.Error(), true) @@ -1051,6 +1086,51 @@ func (c *client) handleWeb(u Url) { } } +func (c *client) find(s string) error { + c.PageState.History[c.PageState.Position].SearchTerm = s + c.PageState.History[c.PageState.Position].FindText() + if len(c.PageState.History[c.PageState.Position].FoundLinkLines) == 0 { + return fmt.Errorf("No text matching %q was found", s) + } + loc := c.PageState.History[c.PageState.Position].ScrollPosition + diff := c.PageState.History[c.PageState.Position].FoundLinkLines[0] - loc + c.Scroll(diff) + c.Draw() + return nil +} + +func (c *client) NextSearchItem() error { + if len(c.PageState.History[c.PageState.Position].FoundLinkLines) == 0 { + return fmt.Errorf("The search is over before it has begun") + } + c.PageState.History[c.PageState.Position].SearchIndex++ + if c.PageState.History[c.PageState.Position].SearchIndex >= len(c.PageState.History[c.PageState.Position].FoundLinkLines) { + c.PageState.History[c.PageState.Position].SearchIndex = 0 + } + + loc := c.PageState.History[c.PageState.Position].ScrollPosition + diff := c.PageState.History[c.PageState.Position].FoundLinkLines[c.PageState.History[c.PageState.Position].SearchIndex] - loc + c.Scroll(diff) + c.Draw() + return nil +} + +func (c *client) PreviousSearchItem() error { + if len(c.PageState.History[c.PageState.Position].FoundLinkLines) == 0 { + return fmt.Errorf("The search is over before it has begun") + } + c.PageState.History[c.PageState.Position].SearchIndex-- + if c.PageState.History[c.PageState.Position].SearchIndex < 0 { + c.PageState.History[c.PageState.Position].SearchIndex = len(c.PageState.History[c.PageState.Position].FoundLinkLines) - 1 + } + + loc := c.PageState.History[c.PageState.Position].ScrollPosition + diff := c.PageState.History[c.PageState.Position].FoundLinkLines[c.PageState.History[c.PageState.Position].SearchIndex] - loc + c.Scroll(diff) + c.Draw() + return nil +} + //------------------------------------------------\\ // + + + F U N C T I O N S + + + \\ //--------------------------------------------------\\ diff --git a/cui/cui.go b/cui/cui.go index b6ca90b..f294ea0 100644 --- a/cui/cui.go +++ b/cui/cui.go @@ -96,11 +96,11 @@ func Getch() rune { return char } -func GetLine() (string, error) { +func GetLine(prefix string) (string, error) { SetLineMode() reader := bufio.NewReader(os.Stdin) - fmt.Print(": ") + fmt.Print(prefix) text, err := reader.ReadString('\n') if err != nil { return "", err diff --git a/page.go b/page.go index 6ef719e..e32bd58 100644 --- a/page.go +++ b/page.go @@ -1,6 +1,7 @@ package main import ( + "fmt" "strings" ) @@ -17,6 +18,9 @@ type Page struct { Links []string Location Url ScrollPosition int + FoundLinkLines []int + SearchTerm string + SearchIndex int } //------------------------------------------------\\ @@ -112,6 +116,27 @@ func (p *Page) WrapContent(width int, color bool) { } p.WrappedContent = strings.Split(content.String(), "\n") + p.FindText() +} + +func (p *Page) FindText() { + matchLines := make([]int, 0) + s := p.SearchTerm + p.SearchIndex = 0 + if s == "" { + p.FoundLinkLines = matchLines + return + } + for i, ln := range p.WrappedContent { + found := strings.Index(ln, s) + if found < 0 { + continue + } + ln = strings.ReplaceAll(ln, s, fmt.Sprintf("\033[7m%s\033[0m", s)) + p.WrappedContent[i] = ln + matchLines = append(matchLines, i) + } + p.FoundLinkLines = matchLines } //------------------------------------------------\\ @@ -120,6 +145,6 @@ func (p *Page) WrapContent(width int, color bool) { // MakePage returns a Page struct with default values func MakePage(url Url, content string, links []string) Page { - p := Page{make([]string, 0), content, links, url, 0} + p := Page{make([]string, 0), content, links, url, 0, make([]int, 0), "", 0} return p }