mirror of
https://github.com/makeworld-the-better-one/amfora.git
synced 2024-11-22 07:23:05 +03:00
🔀 Merge branch 'master' into feeds
This commit is contained in:
commit
e6a081000b
@ -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 <kbd>e</kbd> (#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
|
||||
|
4
Makefile
4
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)
|
||||
|
21
README.md
21
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 <url>` on the terminal. On Windows it might be `amfora.exe` instead.
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
|
3
go.mod
3
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
|
||||
|
6
go.sum
6
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=
|
||||
|
@ -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 {
|
||||
|
@ -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")
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user