diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2e07554..8d4592c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,9 +8,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- `ansi` config setting, to disable ANSI colors in pages (#79, #86)
- Edit current URL with e (#87)
+- If `emoji_favicons` is enabled, new bookmarks will have the domain's favicon prepended (#69, #90)
+- The `BROWSER` env var is now also checked when opening web links on Unix (#93)
### Changed
- Disabling the `color` config setting also disables ANSI colors in pages (#79, #86)
+- Updated [go-isemoji](https://github.com/makeworld-the-better-one/go-isemoji) to v1.1.0 to support Emoji 13.1 for favicons
+- The web browser code doesn't check for Xorg anymore, just display variables (#93)
+- Bookmarks can be made to non-gemini URLs (#94)
+
+### Fixed
+- XDG user dir file is parsed instead of looking for XDG env vars (#97, #100)
## [v1.5.0] - 2020-09-01
diff --git a/Makefile b/Makefile
index 8df09ad..3738545 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
GITV != git describe --tags
GITC != git rev-parse --verify HEAD
-SRC != find -type f -name '*.go' ! -name '*_test.go'
-TEST != find -type f -name '*_test.go'
+SRC != find . -type f -name '*.go' ! -name '*_test.go'
+TEST != find . -type f -name '*_test.go'
PREFIX ?= /usr/local
VERSION ?= $(GITV)
diff --git a/README.md b/README.md
index 12c265a..5c27aff 100644
--- a/README.md
+++ b/README.md
@@ -61,22 +61,35 @@ brew upgrade amfora
```
### From Source
-This section is for programmers who want to install from source. Make sure you're using Go 1.13 at least, as earlier versions will fail to build.
+This section is for advanced users who want to install the latest (possibly unstable) version of Amfora.
-The recommended way of installing Amfora fom source is using the Makefile.
+**Requirements:**
+- Go 1.13 or later
+- GNU Make
-On Windows, you need install make, which can be done with [Chocolatey](https://chocolatey.org/install): `choco install make`. Please note the Makefile does not intend to support Windows, and so there may be issues.
+Please note the Makefile does not intend to support Windows, and so there may be issues.
```shell
git clone https://github.com/makeworld-the-better-one/amfora
cd amfora
# git checkout v1.2.3 # Optionally pin to a specific version instead of the latest commit
-make
+make # Might be gmake on macOS
sudo make install # If you want to install the binary for all users
```
Because you installed with the Makefile, running `amfora -v` will tell you exactly what commit the binary was built from.
+MacOS users can also use [Homebrew](https://brew.sh/) to install the latest commit of Amfora:
+
+```
+brew tap makeworld-the-better-one/tap
+brew install --HEAD amfora
+```
+You can update it with:
+```
+brew upgrade --fetch-HEAD amfora
+```
+
## Usage
Just call `amfora` or `amfora ` on the terminal. On Windows it might be `amfora.exe` instead.
diff --git a/config/config.go b/config/config.go
index 128affc..01746c7 100644
--- a/config/config.go
+++ b/config/config.go
@@ -14,6 +14,8 @@ import (
"github.com/gdamore/tcell"
"github.com/makeworld-the-better-one/amfora/cache"
homedir "github.com/mitchellh/go-homedir"
+ "github.com/rkoesters/xdg/basedir"
+ "github.com/rkoesters/xdg/userdirs"
"github.com/spf13/viper"
"gitlab.com/tslocum/cview"
)
@@ -67,12 +69,11 @@ func Init() error {
configDir = amforaAppData
} else {
// Unix / POSIX system
- xdg_config, ok := os.LookupEnv("XDG_CONFIG_HOME")
- if ok && strings.TrimSpace(xdg_config) != "" {
- configDir = filepath.Join(xdg_config, "amfora")
- } else {
+ if basedir.ConfigHome == "" {
// Default to ~/.config/amfora
configDir = filepath.Join(home, ".config", "amfora")
+ } else {
+ configDir = filepath.Join(basedir.ConfigHome, "amfora")
}
}
configPath = filepath.Join(configDir, "config.toml")
@@ -90,12 +91,11 @@ func Init() error {
tofuDBDir = amforaAppData
} else {
// XDG cache dir on POSIX systems
- xdg_cache, ok := os.LookupEnv("XDG_CACHE_HOME")
- if ok && strings.TrimSpace(xdg_cache) != "" {
- tofuDBDir = filepath.Join(xdg_cache, "amfora")
- } else {
+ if basedir.CacheHome == "" {
// Default to ~/.cache/amfora
tofuDBDir = filepath.Join(home, ".cache", "amfora")
+ } else {
+ tofuDBDir = filepath.Join(basedir.CacheHome, "amfora")
}
}
tofuDBPath = filepath.Join(tofuDBDir, "tofu.toml")
@@ -106,12 +106,11 @@ func Init() error {
bkmkDir = amforaAppData
} else {
// XDG data dir on POSIX systems
- xdg_data, ok := os.LookupEnv("XDG_DATA_HOME")
- if ok && strings.TrimSpace(xdg_data) != "" {
- bkmkDir = filepath.Join(xdg_data, "amfora")
- } else {
+ if basedir.DataHome == "" {
// Default to ~/.local/share/amfora
bkmkDir = filepath.Join(home, ".local", "share", "amfora")
+ } else {
+ bkmkDir = filepath.Join(basedir.DataHome, "amfora")
}
}
bkmkPath = filepath.Join(bkmkDir, "bookmarks.toml")
@@ -181,7 +180,11 @@ func Init() error {
if viper.GetString("a-general.downloads") == "" {
// Find default Downloads dir
// This seems to work for all OSes?
- DownloadsDir = filepath.Join(home, "Downloads")
+ if userdirs.Download == "" {
+ DownloadsDir = filepath.Join(home, "Downloads")
+ } else {
+ DownloadsDir = userdirs.Download
+ }
// Create it just in case
err = os.MkdirAll(DownloadsDir, 0755)
if err != nil {
diff --git a/display/bookmarks.go b/display/bookmarks.go
index 7dd6ca9..017c19d 100644
--- a/display/bookmarks.go
+++ b/display/bookmarks.go
@@ -3,7 +3,6 @@ package display
import (
"fmt"
"strconv"
- "strings"
"github.com/gdamore/tcell"
"github.com/makeworld-the-better-one/amfora/bookmarks"
@@ -71,7 +70,7 @@ func bkmkInit() {
// It also accepts a bool indicating whether this page already has a bookmark.
// It returns the bookmark name and the bookmark action:
// 1, 0, -1 for add/update, cancel, and remove
-func openBkmkModal(name string, exists bool) (string, int) {
+func openBkmkModal(name string, exists bool, favicon string) (string, int) {
// Basically a copy of Input()
// Reset buttons before input field, to make sure the input is in focus
@@ -86,6 +85,9 @@ func openBkmkModal(name string, exists bool) (string, int) {
// Remove and re-add input field - to clear the old text
bkmkModal.GetForm().Clear(false)
+ if favicon != "" && !exists {
+ name = favicon + " " + name
+ }
bkmkModalText = ""
bkmkModal.GetForm().AddInputField("Name: ", name, 0, nil,
func(text string) {
@@ -133,20 +135,22 @@ func Bookmarks(t *tab) {
// It is the high-level way of doing it. It should be called in a goroutine.
// It can also be called to edit an existing bookmark.
func addBookmark() {
- if !strings.HasPrefix(tabs[curTab].page.URL, "gemini://") {
- // Can't make bookmarks for other kinds of URLs
+ t := tabs[curTab]
+ p := t.page
+
+ if !t.hasContent() {
+ // It's an about: page, or a malformed one
return
}
-
- name, exists := bookmarks.Get(tabs[curTab].page.URL)
+ name, exists := bookmarks.Get(p.URL)
// Open a bookmark modal with the current name of the bookmark, if it exists
- newName, action := openBkmkModal(name, exists)
+ newName, action := openBkmkModal(name, exists, p.Favicon)
switch action {
case 1:
// Add/change the bookmark
- bookmarks.Set(tabs[curTab].page.URL, newName)
+ bookmarks.Set(p.URL, newName)
case -1:
- bookmarks.Remove(tabs[curTab].page.URL)
+ bookmarks.Remove(p.URL)
}
// Other case is action = 0, meaning "Cancel", so nothing needs to happen
}
diff --git a/go.mod b/go.mod
index 2f77ed8..bc129f0 100644
--- a/go.mod
+++ b/go.mod
@@ -8,12 +8,13 @@ require (
github.com/gdamore/tcell v1.3.1-0.20200608133353-cb1e5d6fa606
github.com/google/go-cmp v0.5.0 // indirect
github.com/makeworld-the-better-one/go-gemini v0.8.4
- github.com/makeworld-the-better-one/go-isemoji v1.0.0
+ github.com/makeworld-the-better-one/go-isemoji v1.1.0
github.com/makeworld-the-better-one/progressbar/v3 v3.3.5-0.20200710151429-125743e22b4f
github.com/mitchellh/go-homedir v1.1.0
github.com/mitchellh/mapstructure v1.3.1 // indirect
github.com/mmcdole/gofeed v1.0.0
github.com/pelletier/go-toml v1.8.0 // indirect
+ github.com/rkoesters/xdg v0.0.0-20181125232953-edd15b846f9b
github.com/spf13/afero v1.2.2 // indirect
github.com/spf13/cast v1.3.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
diff --git a/go.sum b/go.sum
index 129a600..d8f5d5d 100644
--- a/go.sum
+++ b/go.sum
@@ -132,8 +132,8 @@ github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzR
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/makeworld-the-better-one/go-gemini v0.8.4 h1:ntsQ9HnlJCmC9PDqXp/f1SCALjBMwh69BbT4BhFRFaw=
github.com/makeworld-the-better-one/go-gemini v0.8.4/go.mod h1:P7/FbZ+IEIbA/d+A0Y3w2GNgD8SA2AcNv7aDGJbaWG4=
-github.com/makeworld-the-better-one/go-isemoji v1.0.0 h1:W3O4+qwtXeT8PUDzcQ1UjxiupQWgc/oJHpqwrllx3xM=
-github.com/makeworld-the-better-one/go-isemoji v1.0.0/go.mod h1:FBjkPl9rr0G4vlZCc+Mr+QcnOfGCTbGWYW8/1sp06I0=
+github.com/makeworld-the-better-one/go-isemoji v1.1.0 h1:wZBHOKB5zAIgaU2vaWnXFDDhatebB8TySrNVxjVV84g=
+github.com/makeworld-the-better-one/go-isemoji v1.1.0/go.mod h1:FBjkPl9rr0G4vlZCc+Mr+QcnOfGCTbGWYW8/1sp06I0=
github.com/makeworld-the-better-one/progressbar/v3 v3.3.5-0.20200710151429-125743e22b4f h1:YEUlTs5gb35UlBLTgqrub9axWTYB3d7/8TxrkJDZpRI=
github.com/makeworld-the-better-one/progressbar/v3 v3.3.5-0.20200710151429-125743e22b4f/go.mod h1:X6sxWNi9PBgQybpR4fpXPVD5fm7svLqZTQ5DJuERIoM=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
@@ -186,6 +186,8 @@ github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7z
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+github.com/rkoesters/xdg v0.0.0-20181125232953-edd15b846f9b h1:8NiY6v9/IlFU8osj1L7kqzRbrG6e3izRQQjGze1Q1R0=
+github.com/rkoesters/xdg v0.0.0-20181125232953-edd15b846f9b/go.mod h1:T1HolqzmdHnJIH6p7A9LDuvYGQgEHx9ijX3vKgDKU60=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
diff --git a/webbrowser/open_browser_darwin.go b/webbrowser/open_browser_darwin.go
index e9992b7..44c522e 100644
--- a/webbrowser/open_browser_darwin.go
+++ b/webbrowser/open_browser_darwin.go
@@ -4,6 +4,7 @@ package webbrowser
import "os/exec"
+// Open opens `url` in default system browser.
func Open(url string) (string, error) {
err := exec.Command("open", url).Start()
if err != nil {
diff --git a/webbrowser/open_browser_other.go b/webbrowser/open_browser_other.go
index 706953f..9501034 100644
--- a/webbrowser/open_browser_other.go
+++ b/webbrowser/open_browser_other.go
@@ -4,6 +4,7 @@ package webbrowser
import "fmt"
+// Open opens `url` in default system browser, but not on this OS.
func Open(url string) (string, error) {
return "", fmt.Errorf("unsupported OS for default HTTP handling. Set a command in the config")
}
diff --git a/webbrowser/open_browser_unix.go b/webbrowser/open_browser_unix.go
index 99ecbb5..4d265be 100644
--- a/webbrowser/open_browser_unix.go
+++ b/webbrowser/open_browser_unix.go
@@ -9,27 +9,40 @@ import (
"os/exec"
)
-// OpenInBrowser checks for the presence of a display server
-// and environment variables indicating a gui is present. If found
-// then xdg-open is called on a url to open said url in the default
-// gui web browser for the system
+// Open opens `url` in default system browser. It tries to do so in two
+// ways (xdg-open and $BROWSER). It only works if there is a display
+// server working.
+//
+// bouncepaw: I tried to support TTYs as well. The idea was to open
+// a browser in foreground and return back to amfora after the browser
+// is closed. While all browsers I tested opened correctly (w3m, lynx),
+// I couldn't make it restore amfora correctly. The screen always ended
+// up distorted. None of my stunts with altscreen buffers helped.
func Open(url string) (string, error) {
- disp := os.Getenv("DISPLAY")
- wayland := os.Getenv("WAYLAND_DISPLAY")
- _, err := exec.LookPath("Xorg")
- if disp == "" && wayland == "" && err != nil {
- return "", fmt.Errorf("no gui is available")
+ var (
+ // In prev versions there was also Xorg executable checked for.
+ // I don't see any reason to check for it.
+ xorgDisplay = os.Getenv("DISPLAY")
+ waylandDisplay = os.Getenv("WAYLAND_DISPLAY")
+ xdgOpenPath, xdgOpenNotFoundErr = exec.LookPath("xdg-open")
+ envBrowser = os.Getenv("BROWSER")
+ )
+ switch {
+ case xorgDisplay == "" && waylandDisplay == "":
+ return "", fmt.Errorf("no display server was found")
+ case xdgOpenNotFoundErr == nil: // Prefer xdg-open over $BROWSER
+ // Use start rather than run or output in order
+ // to make browser running in background.
+ if err := exec.Command(xdgOpenPath, url).Start(); err != nil {
+ return "", err
+ }
+ return "Opened in system default web browser", nil
+ case envBrowser != "":
+ if err := exec.Command(envBrowser, url).Start(); err != nil {
+ return "", err
+ }
+ return "Opened in system default web browser", nil
+ default:
+ return "", fmt.Errorf("could not determine system browser")
}
-
- _, err = exec.LookPath("xdg-open")
- if err != nil {
- return "", fmt.Errorf("xdg-open command not found, cannot open in web browser")
- }
- // Use start rather than run or output in order
- // to release the process and not block
- err = exec.Command("xdg-open", url).Start()
- if err != nil {
- return "", err
- }
- return "Opened in system default web browser", nil
}
diff --git a/webbrowser/open_browser_windows.go b/webbrowser/open_browser_windows.go
index 61b4bb4..66b8c46 100644
--- a/webbrowser/open_browser_windows.go
+++ b/webbrowser/open_browser_windows.go
@@ -5,6 +5,7 @@ package webbrowser
import "os/exec"
+// Open opens `url` in default system browser.
func Open(url string) (string, error) {
err := exec.Command("rundll32", "url.dll,FileProtocolHandler", url).Start()
if err != nil {