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
|
### Added
|
||||||
- `ansi` config setting, to disable ANSI colors in pages (#79, #86)
|
- `ansi` config setting, to disable ANSI colors in pages (#79, #86)
|
||||||
- Edit current URL with <kbd>e</kbd> (#87)
|
- 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
|
### Changed
|
||||||
- Disabling the `color` config setting also disables ANSI colors in pages (#79, #86)
|
- 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
|
## [v1.5.0] - 2020-09-01
|
||||||
|
4
Makefile
4
Makefile
@ -1,7 +1,7 @@
|
|||||||
GITV != git describe --tags
|
GITV != git describe --tags
|
||||||
GITC != git rev-parse --verify HEAD
|
GITC != git rev-parse --verify HEAD
|
||||||
SRC != find -type f -name '*.go' ! -name '*_test.go'
|
SRC != find . -type f -name '*.go' ! -name '*_test.go'
|
||||||
TEST != find -type f -name '*_test.go'
|
TEST != find . -type f -name '*_test.go'
|
||||||
|
|
||||||
PREFIX ?= /usr/local
|
PREFIX ?= /usr/local
|
||||||
VERSION ?= $(GITV)
|
VERSION ?= $(GITV)
|
||||||
|
21
README.md
21
README.md
@ -61,22 +61,35 @@ brew upgrade amfora
|
|||||||
```
|
```
|
||||||
|
|
||||||
### From Source
|
### 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
|
```shell
|
||||||
git clone https://github.com/makeworld-the-better-one/amfora
|
git clone https://github.com/makeworld-the-better-one/amfora
|
||||||
cd amfora
|
cd amfora
|
||||||
# git checkout v1.2.3 # Optionally pin to a specific version instead of the latest commit
|
# 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
|
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.
|
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
|
## Usage
|
||||||
|
|
||||||
Just call `amfora` or `amfora <url>` on the terminal. On Windows it might be `amfora.exe` instead.
|
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/gdamore/tcell"
|
||||||
"github.com/makeworld-the-better-one/amfora/cache"
|
"github.com/makeworld-the-better-one/amfora/cache"
|
||||||
homedir "github.com/mitchellh/go-homedir"
|
homedir "github.com/mitchellh/go-homedir"
|
||||||
|
"github.com/rkoesters/xdg/basedir"
|
||||||
|
"github.com/rkoesters/xdg/userdirs"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
"gitlab.com/tslocum/cview"
|
"gitlab.com/tslocum/cview"
|
||||||
)
|
)
|
||||||
@ -67,12 +69,11 @@ func Init() error {
|
|||||||
configDir = amforaAppData
|
configDir = amforaAppData
|
||||||
} else {
|
} else {
|
||||||
// Unix / POSIX system
|
// Unix / POSIX system
|
||||||
xdg_config, ok := os.LookupEnv("XDG_CONFIG_HOME")
|
if basedir.ConfigHome == "" {
|
||||||
if ok && strings.TrimSpace(xdg_config) != "" {
|
|
||||||
configDir = filepath.Join(xdg_config, "amfora")
|
|
||||||
} else {
|
|
||||||
// Default to ~/.config/amfora
|
// Default to ~/.config/amfora
|
||||||
configDir = filepath.Join(home, ".config", "amfora")
|
configDir = filepath.Join(home, ".config", "amfora")
|
||||||
|
} else {
|
||||||
|
configDir = filepath.Join(basedir.ConfigHome, "amfora")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
configPath = filepath.Join(configDir, "config.toml")
|
configPath = filepath.Join(configDir, "config.toml")
|
||||||
@ -90,12 +91,11 @@ func Init() error {
|
|||||||
tofuDBDir = amforaAppData
|
tofuDBDir = amforaAppData
|
||||||
} else {
|
} else {
|
||||||
// XDG cache dir on POSIX systems
|
// XDG cache dir on POSIX systems
|
||||||
xdg_cache, ok := os.LookupEnv("XDG_CACHE_HOME")
|
if basedir.CacheHome == "" {
|
||||||
if ok && strings.TrimSpace(xdg_cache) != "" {
|
|
||||||
tofuDBDir = filepath.Join(xdg_cache, "amfora")
|
|
||||||
} else {
|
|
||||||
// Default to ~/.cache/amfora
|
// Default to ~/.cache/amfora
|
||||||
tofuDBDir = filepath.Join(home, ".cache", "amfora")
|
tofuDBDir = filepath.Join(home, ".cache", "amfora")
|
||||||
|
} else {
|
||||||
|
tofuDBDir = filepath.Join(basedir.CacheHome, "amfora")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tofuDBPath = filepath.Join(tofuDBDir, "tofu.toml")
|
tofuDBPath = filepath.Join(tofuDBDir, "tofu.toml")
|
||||||
@ -106,12 +106,11 @@ func Init() error {
|
|||||||
bkmkDir = amforaAppData
|
bkmkDir = amforaAppData
|
||||||
} else {
|
} else {
|
||||||
// XDG data dir on POSIX systems
|
// XDG data dir on POSIX systems
|
||||||
xdg_data, ok := os.LookupEnv("XDG_DATA_HOME")
|
if basedir.DataHome == "" {
|
||||||
if ok && strings.TrimSpace(xdg_data) != "" {
|
|
||||||
bkmkDir = filepath.Join(xdg_data, "amfora")
|
|
||||||
} else {
|
|
||||||
// Default to ~/.local/share/amfora
|
// Default to ~/.local/share/amfora
|
||||||
bkmkDir = filepath.Join(home, ".local", "share", "amfora")
|
bkmkDir = filepath.Join(home, ".local", "share", "amfora")
|
||||||
|
} else {
|
||||||
|
bkmkDir = filepath.Join(basedir.DataHome, "amfora")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bkmkPath = filepath.Join(bkmkDir, "bookmarks.toml")
|
bkmkPath = filepath.Join(bkmkDir, "bookmarks.toml")
|
||||||
@ -181,7 +180,11 @@ func Init() error {
|
|||||||
if viper.GetString("a-general.downloads") == "" {
|
if viper.GetString("a-general.downloads") == "" {
|
||||||
// Find default Downloads dir
|
// Find default Downloads dir
|
||||||
// This seems to work for all OSes?
|
// 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
|
// Create it just in case
|
||||||
err = os.MkdirAll(DownloadsDir, 0755)
|
err = os.MkdirAll(DownloadsDir, 0755)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -3,7 +3,6 @@ package display
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/gdamore/tcell"
|
"github.com/gdamore/tcell"
|
||||||
"github.com/makeworld-the-better-one/amfora/bookmarks"
|
"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 also accepts a bool indicating whether this page already has a bookmark.
|
||||||
// It returns the bookmark name and the bookmark action:
|
// It returns the bookmark name and the bookmark action:
|
||||||
// 1, 0, -1 for add/update, cancel, and remove
|
// 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()
|
// Basically a copy of Input()
|
||||||
|
|
||||||
// Reset buttons before input field, to make sure the input is in focus
|
// 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
|
// Remove and re-add input field - to clear the old text
|
||||||
bkmkModal.GetForm().Clear(false)
|
bkmkModal.GetForm().Clear(false)
|
||||||
|
if favicon != "" && !exists {
|
||||||
|
name = favicon + " " + name
|
||||||
|
}
|
||||||
bkmkModalText = ""
|
bkmkModalText = ""
|
||||||
bkmkModal.GetForm().AddInputField("Name: ", name, 0, nil,
|
bkmkModal.GetForm().AddInputField("Name: ", name, 0, nil,
|
||||||
func(text string) {
|
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 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.
|
// It can also be called to edit an existing bookmark.
|
||||||
func addBookmark() {
|
func addBookmark() {
|
||||||
if !strings.HasPrefix(tabs[curTab].page.URL, "gemini://") {
|
t := tabs[curTab]
|
||||||
// Can't make bookmarks for other kinds of URLs
|
p := t.page
|
||||||
|
|
||||||
|
if !t.hasContent() {
|
||||||
|
// It's an about: page, or a malformed one
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
name, exists := bookmarks.Get(p.URL)
|
||||||
name, exists := bookmarks.Get(tabs[curTab].page.URL)
|
|
||||||
// Open a bookmark modal with the current name of the bookmark, if it exists
|
// 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 {
|
switch action {
|
||||||
case 1:
|
case 1:
|
||||||
// Add/change the bookmark
|
// Add/change the bookmark
|
||||||
bookmarks.Set(tabs[curTab].page.URL, newName)
|
bookmarks.Set(p.URL, newName)
|
||||||
case -1:
|
case -1:
|
||||||
bookmarks.Remove(tabs[curTab].page.URL)
|
bookmarks.Remove(p.URL)
|
||||||
}
|
}
|
||||||
// Other case is action = 0, meaning "Cancel", so nothing needs to happen
|
// 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/gdamore/tcell v1.3.1-0.20200608133353-cb1e5d6fa606
|
||||||
github.com/google/go-cmp v0.5.0 // indirect
|
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-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/makeworld-the-better-one/progressbar/v3 v3.3.5-0.20200710151429-125743e22b4f
|
||||||
github.com/mitchellh/go-homedir v1.1.0
|
github.com/mitchellh/go-homedir v1.1.0
|
||||||
github.com/mitchellh/mapstructure v1.3.1 // indirect
|
github.com/mitchellh/mapstructure v1.3.1 // indirect
|
||||||
github.com/mmcdole/gofeed v1.0.0
|
github.com/mmcdole/gofeed v1.0.0
|
||||||
github.com/pelletier/go-toml v1.8.0 // indirect
|
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/afero v1.2.2 // indirect
|
||||||
github.com/spf13/cast v1.3.1 // indirect
|
github.com/spf13/cast v1.3.1 // indirect
|
||||||
github.com/spf13/jwalterweatherman v1.1.0 // 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/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 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-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.1.0 h1:wZBHOKB5zAIgaU2vaWnXFDDhatebB8TySrNVxjVV84g=
|
||||||
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/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 h1:YEUlTs5gb35UlBLTgqrub9axWTYB3d7/8TxrkJDZpRI=
|
||||||
github.com/makeworld-the-better-one/progressbar/v3 v3.3.5-0.20200710151429-125743e22b4f/go.mod h1:X6sxWNi9PBgQybpR4fpXPVD5fm7svLqZTQ5DJuERIoM=
|
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=
|
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/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 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY=
|
||||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
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/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/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=
|
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"
|
import "os/exec"
|
||||||
|
|
||||||
|
// Open opens `url` in default system browser.
|
||||||
func Open(url string) (string, error) {
|
func Open(url string) (string, error) {
|
||||||
err := exec.Command("open", url).Start()
|
err := exec.Command("open", url).Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -4,6 +4,7 @@ package webbrowser
|
|||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
|
// Open opens `url` in default system browser, but not on this OS.
|
||||||
func Open(url string) (string, error) {
|
func Open(url string) (string, error) {
|
||||||
return "", fmt.Errorf("unsupported OS for default HTTP handling. Set a command in the config")
|
return "", fmt.Errorf("unsupported OS for default HTTP handling. Set a command in the config")
|
||||||
}
|
}
|
||||||
|
@ -9,27 +9,40 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
)
|
)
|
||||||
|
|
||||||
// OpenInBrowser checks for the presence of a display server
|
// Open opens `url` in default system browser. It tries to do so in two
|
||||||
// and environment variables indicating a gui is present. If found
|
// ways (xdg-open and $BROWSER). It only works if there is a display
|
||||||
// then xdg-open is called on a url to open said url in the default
|
// server working.
|
||||||
// gui web browser for the system
|
//
|
||||||
|
// 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) {
|
func Open(url string) (string, error) {
|
||||||
disp := os.Getenv("DISPLAY")
|
var (
|
||||||
wayland := os.Getenv("WAYLAND_DISPLAY")
|
// In prev versions there was also Xorg executable checked for.
|
||||||
_, err := exec.LookPath("Xorg")
|
// I don't see any reason to check for it.
|
||||||
if disp == "" && wayland == "" && err != nil {
|
xorgDisplay = os.Getenv("DISPLAY")
|
||||||
return "", fmt.Errorf("no gui is available")
|
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"
|
import "os/exec"
|
||||||
|
|
||||||
|
// Open opens `url` in default system browser.
|
||||||
func Open(url string) (string, error) {
|
func Open(url string) (string, error) {
|
||||||
err := exec.Command("rundll32", "url.dll,FileProtocolHandler", url).Start()
|
err := exec.Command("rundll32", "url.dll,FileProtocolHandler", url).Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user