diff --git a/README.md b/README.md index 744a190..3c4ed43 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Amfora aims to be the best looking [Gemini](https://gemini.circumlunar.space/) c It also aims to be completely cross platform, with full Windows support. If you're on Windows, I would not recommend using the default terminal software. Maybe use [Cmder](https://cmder.net/) instead? -It fully passes Sean Conman's client torture test. It mostly passes the Egsam test. +It fully passes Sean Conman's client torture test, including the new Unicode tests. It mostly passes the Egsam test. ## Installation @@ -34,7 +34,7 @@ The project keeps many standard terminal keybindings and is intuitive. Press Ctrl-F - [ ] Download pages and arbitrary data diff --git a/config/default.go b/config/default.go index 3abf1a3..cc96d5a 100644 --- a/config/default.go +++ b/config/default.go @@ -4,10 +4,16 @@ package config var defaultConf = []byte(`# This is the default config file. # It also shows all the default values, if you don't create the file. -# All URL values may omit the scheme and/or port. +# All URL values may omit the scheme and/or port, as well as the beginning double slash +# Valid URL examples: +# gemini://example.com +# //example.com +# example.com +# example.com:1901 [a-general] home = "gemini://gemini.circumlunar.space" + # What command to run to open a HTTP URL. Set to "default" to try to guess the browser, # or set to "off" to not open HTTP URLs. # If a command is set, than the URL will be added (in quotes) to the end of the command. @@ -29,5 +35,5 @@ wrap_width = 100 # How many columns to wrap a page's text to. Preformatted bloc [cache] # Zero values mean there is no limit max_size = 0 # Size in bytes -max_pages = 30 # The maximum number of pages the cache can store +max_pages = 30 # The maximum number of pages the cache will store `) diff --git a/default-config.toml b/default-config.toml index 70263d7..b74706b 100644 --- a/default-config.toml +++ b/default-config.toml @@ -1,10 +1,16 @@ # This is the default config file. # It also shows all the default values, if you don't create the file. -# All URL values may omit the scheme and/or port. +# All URL values may omit the scheme and/or port, as well as the beginning double slash +# Valid URL examples: +# gemini://example.com +# //example.com +# example.com +# example.com:1901 [a-general] home = "gemini://gemini.circumlunar.space" + # What command to run to open a HTTP URL. Set to "default" to try to guess the browser, # or set to "off" to not open HTTP URLs. # If a command is set, than the URL will be added (in quotes) to the end of the command. @@ -26,4 +32,4 @@ wrap_width = 100 # How many columns to wrap a page's text to. Preformatted bloc [cache] # Zero values mean there is no limit max_size = 0 # Size in bytes -max_pages = 30 # The maximum number of pages the cache can store +max_pages = 30 # The maximum number of pages the cache will store diff --git a/display/display.go b/display/display.go index 135b808..23a4ce5 100644 --- a/display/display.go +++ b/display/display.go @@ -119,7 +119,9 @@ func Init() { // TODO: Support search // Send the URL/number typed in - if strings.TrimSpace(bottomBar.GetText()) == "" { + query := bottomBar.GetText() + + if strings.TrimSpace(query) == "" { // Ignore bottomBar.SetLabel("") bottomBar.SetText(tabMap[curTab].Url) @@ -127,15 +129,21 @@ func Init() { return } - i, err := strconv.Atoi(bottomBar.GetText()) + i, err := strconv.Atoi(query) if err != nil { - // It's a full URL - URL(bottomBar.GetText()) + // It's a full URL or search term + // Detect if it's a search or URL + if strings.Contains(query, " ") || (!strings.Contains(query, "//") && !strings.Contains(query, ".")) { + URL(viper.GetString("a-general.search") + "?" + pathEscape(query)) + } else { + // Full URL + URL(query) + } bottomBar.SetLabel("") return } if i <= len(tabMap[curTab].Links) && i > 0 { - // Valid link number + // It's a valid link number followLink(tabMap[curTab].Url, tabMap[curTab].Links[i-1]) bottomBar.SetLabel("") return @@ -195,7 +203,7 @@ func Init() { switch string(event.Rune()) { case " ": // Space starts typing, like Bombadillo - bottomBar.SetLabel("[::b]URL: [::-]") + bottomBar.SetLabel("[::b]URL or search: [::-]") bottomBar.SetText("") App.SetFocus(bottomBar) return nil diff --git a/display/private.go b/display/private.go index b4fae8d..8300cdc 100644 --- a/display/private.go +++ b/display/private.go @@ -18,6 +18,11 @@ import ( // This file contains the functions that aren't part of the public API. +// pathEscape is the same as url.PathEscape, but it also replaces the +. +func pathEscape(path string) string { + return strings.ReplaceAll(url.PathEscape(path), "+", "%2B") +} + // tabHasContent returns true when the current tab has a page being displayed. // The most likely situation where false would be returned is when the default // new tab content is being displayed. @@ -185,7 +190,7 @@ func handleURL(u string) (string, bool) { if ok { // Make another request with the query string added // + chars are replaced because PathEscape doesn't do that - parsed.RawQuery = strings.ReplaceAll(url.PathEscape(userInput), "+", "%2B") + parsed.RawQuery = pathEscape(userInput) return handleURL(parsed.String()) } return "", false