*: switch to golang

Signed-off-by: Vincent Batts <vbatts@hashbangbash.com>
This commit is contained in:
Vincent Batts 2024-05-25 11:41:39 -04:00
parent 5c9fd8cbda
commit b89aa4d153
Signed by: vbatts
GPG key ID: E30EFAA812C6E5ED
7 changed files with 144 additions and 16 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
*~
terminal-url-open

View file

@ -9,18 +9,17 @@ default: help
help: help:
@echo " - help - this text" @echo " - help - this text"
@echo " - user-install - install the 'terminal://' handler for only $(USER)" @echo " - user-install - install the 'terminal://' handler for only $(USER)"
@echo " - lint - run shellcheck"
@echo " - get-default - see the xdg-settings default handler for 'terminal://' scheme" @echo " - get-default - see the xdg-settings default handler for 'terminal://' scheme"
user-install: user-install: terminal-url-open
mkdir -p ~/.local/bin && \ mkdir -p ~/.local/bin && \
ln -sf $(shell realpath $(SCRIPT_FILE)) ~/.local/bin && \ ln -sf $(shell realpath $(SCRIPT_FILE)) ~/.local/bin && \
mkdir -p ~/.local/share/applications && \ mkdir -p ~/.local/share/applications && \
ln -sf $(shell realpath $(DESKTOP_FILE)) ~/.local/share/applications/ && \ ln -sf $(shell realpath $(DESKTOP_FILE)) ~/.local/share/applications/ && \
update-desktop-database ~/.local/share/applications update-desktop-database ~/.local/share/applications
lint: terminal-url-open: terminal-url-open.go
shellcheck $(SCRIPT_FILE) go build -o $@ ./$<
get-default: get-default:
xdg-settings get default-url-scheme-handler terminal xdg-settings get default-url-scheme-handler terminal

View file

@ -8,6 +8,8 @@ Something simple like a [URI](https://en.wikipedia.org/wiki/Uniform_Resource_Ide
## install ## install
This requires a golang compiler.
```shell ```shell
git clone https://github.com/vbatts/terminal-url-handler git clone https://github.com/vbatts/terminal-url-handler
cd terminal-url-handler cd terminal-url-handler
@ -29,18 +31,45 @@ i.e. [terminal-url-handler](terminal://~/src/terminal-url-handler)
<a href="terminal://~/src/terminal-url-handler">terminal-url-handler</a> <a href="terminal://~/src/terminal-url-handler">terminal-url-handler</a>
``` ```
## Types of URIs
multiple cases of URIs, and we are not dealing with query parameters.
No shell execution.
- terminal:///home/user
- terminal://host:/home/user
- terminal://host/home/user
- terminal://user@host:/home/user
- terminal://user@host:port/home/user
## default terminal?
On most Linux desktops, the `x-terminal-emulator` is an [`update-alternatives`](https://www.man7.org/linux/man-pages/man1/update-alternatives.1.html) symlink to a Terminal app like `gnome-terminal` or whatever.
To see alternatives for `x-terminal-emulator`, run:
```shell
$ update-alternatives --list x-terminal-emulator
/usr/bin/gnome-terminal.wrapper
/usr/bin/koi8rxterm
/usr/bin/lxterm
/usr/bin/uxterm
/usr/bin/xfce4-terminal.wrapper
/usr/bin/xterm
```
To change this, say to `xfce4-terminal`, run:
```shell
sudo update-alternatives --set x-terminal-emulator /usr/bin/xfce4-terminal.wrapper
```
## development ## development
happy to take contributions or enhancements. happy to take contributions or enhancements.
This seems like something that ought to be built-in for most desktops. This seems like something that ought to be built-in for most desktops.
### lint
```shell
make lint
```
### XDG ### XDG
all this business of `x-scheme-handlers` and desktop files, I am surprised there isn't a simple GUI that can help creating and indexing them. all this business of `x-scheme-handlers` and desktop files, I am surprised there isn't a simple GUI that can help creating and indexing them.

7
go.mod Normal file
View file

@ -0,0 +1,7 @@
module github.com/vbatts/terminal-url-handler
go 1.22.1
require github.com/sirupsen/logrus v1.9.3
require golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect

15
go.sum Normal file
View file

@ -0,0 +1,15 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View file

@ -1,6 +0,0 @@
#!/bin/bash
set -ue
dir="${1#terminal://}"
x-terminal-emulator -e "sh -c 'cd "${dir}" && \$SHELL'"

82
terminal-url-open.go Normal file
View file

@ -0,0 +1,82 @@
package main
// multiple cases of URIs, and we are not dealing with query parameters.
// No shell execution.
// - terminal:///home/user
// - terminal://host:/home/user
// - terminal://host/home/user
// - terminal://user@host:/home/user
// - terminal://user@host:port/home/user
import (
"flag"
"fmt"
"net/url"
"os"
"os/exec"
"strings"
"github.com/sirupsen/logrus"
)
var defaultTerminal string = "x-terminal-emulator"
func main() {
flag.Parse()
if flag.NArg() == 0 {
logrus.Fatal("no URI provided!")
}
u, err := url.Parse(flag.Args()[0])
if err != nil {
logrus.Fatalf("failed to parse %q: %s", flag.Args()[0], err)
}
logrus.Infof("%#v", u)
if u.Host != "" {
logrus.Infof("need to use ssh to connect to %q", u.Host)
var user string
if u.User != nil && u.User.Username() != "" {
user = u.User.Username()
} else {
var ok bool
user, ok = os.LookupEnv("USER")
if !ok {
logrus.Fatal("could not determine username to ssh as")
}
}
host := u.Host
port := "22"
if strings.Contains(host, ":") {
args := strings.Split(host, ":")
host = args[0]
if args[1] != "" {
port = args[1]
}
}
cmd := exec.Command(defaultTerminal,
"-e",
fmt.Sprintf(`sh -c 'ssh -p %s -t %s@%s -- "cd %s && $SHELL -l"'`, port, user, host, u.Path),
)
logrus.Infof("local path shell command(simple): %s", cmd.String())
logrus.Infof("local path shell command(struct): %#v", cmd)
if err := cmd.Run(); err != nil {
logrus.Fatalf("failed to run the terminal in a local path: %s", err)
}
} else {
cmd := exec.Command(defaultTerminal,
"-e",
fmt.Sprintf(`sh -c 'if [ -d %q ] ; then cd %q && $SHELL ; else echo "WARNING: %q not found" && $SHELL ; fi'`, u.Path, u.Path, u.Path),
)
logrus.Infof("local path shell command(simple): %s", cmd.String())
logrus.Infof("local path shell command(struct): %#v", cmd)
if err := cmd.Run(); err != nil {
logrus.Fatalf("failed to run the terminal in a local path: %s", err)
}
}
}
// TODO maybe not _all_ terminals accept the same flags as gnome and xfce terminal. May need a case statement for generic situations.