1
0
Fork 0

Compare commits

...

16 Commits

Author SHA1 Message Date
mntn da797aca40
Merge 1a5ea27080 into 1a0d2b6d5a 2023-11-11 04:38:07 -07:00
makeworld 1a0d2b6d5a
update doc 2023-11-03 11:36:46 -04:00
Marc Ransome 6a92dd336b
Update URLs for official Project Gemini capsule (#342)
* Update URLs for official Project Gemini capsule

* Update disabled tests
2023-11-03 11:34:18 -04:00
mntn 1a5ea27080 Run go fmt to fix issue from merge 2022-01-01 20:31:30 -05:00
mntn 3b3d77447e
Merge branch 'master' into commands 2022-01-01 20:26:47 -05:00
mntn f13018bded Use goroutines for Error/Info calls 2022-01-01 20:25:26 -05:00
mntn 774554ac22 Further clarify comment 2022-01-01 20:21:52 -05:00
mntn 416f4b300c Merge branch 'commands' of github.com:mntn-xyz/amfora into commands 2022-01-01 20:13:55 -05:00
mntn 96add16a83
Merge branch 'master' into commands 2021-12-22 20:44:41 -05:00
mntn 5ecc1a3c89
Merge branch 'master' into commands 2021-12-10 23:41:32 -05:00
mntn ea7e024515 Fix typo 2021-12-10 23:12:15 -05:00
mntn 4c85e1efbe Fix linting issues 2021-12-10 22:39:18 -05:00
mntn cf07d9ee2c Merge branch 'master' into commands 2021-12-10 22:35:36 -05:00
mntn e797ce2d90 Merge branch 'master' into commands 2021-12-07 23:51:07 -05:00
mntn e9fecaca25 Merge changes from master 2021-12-07 23:28:48 -05:00
mntn 7fa774b7f7 Adds support for custom commands
Supports up to 10 custom commands, defined in the configuration file.
The current or selected URL can be passed to the command by placing
${url} in the command string.

Default hotkeys are Alt-1 through Alt-0 for triggering the command
with the selected link URL as a parameter, or Alt-Shift-1 through
Alt-Shift-0 for triggering the command with the current page URL
as a parameter. This follows the convention set by the copy page
URL (C) and copy selected URL (c) defaults.

Custom commands must be available in the $PATH or use absolute
paths. Relative paths are not supported, neither are pipes or
shell redirections.
2021-10-16 15:31:52 -04:00
13 changed files with 287 additions and 30 deletions

View File

@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Paging up or down scrolls by 50% instead of 75%, to match `less` (#303)
- Update deps, require Go 1.17 (#336)
- Show local directory index file if available (#319)
- Updated Project Gemini URLs (#342)
### Fixed
- Modal can't be closed when opening non-gemini text URLs from the commandline (#283, #284)

View File

@ -147,6 +147,7 @@ Features in *italics* are in the master branch, but not in the latest release.
- [x] Open non-text files in another application
- [x] Ability to stream content instead of downloading it first
- [x] *Highlighting of preformatted code blocks that list a language in the alt text*
- [x] *Run custom commands using the current or selected URL as an argument*
- [ ] Stream support
- [ ] Table of contents for pages
- [ ] Search in pages with <kbd>Ctrl-F</kbd>

View File

@ -29,3 +29,4 @@ Thank you to the following contributors, who have helped make Amfora great. FOSS
* Maxime Bouillot (@Arkaeriit)
* Emily (@emily-is-my-username)
* Autumn! (@autumnull)
* William Rehwinkel (@FiskFan1999)

View File

@ -24,9 +24,9 @@ var normalizeURLTests = []struct {
{"https://example.com", "https://example.com"},
// Fixing URL tests
// Some commented out due to #324
//{"gemini://gemini.circumlunar.space/%64%6f%63%73/%66%61%71%2e%67%6d%69", "gemini://gemini.circumlunar.space/docs/faq.gmi"},
//{"gemini://geminiprotocol.net/%64%6f%63%73/%66%61%71%2e%67%6d%69", "gemini://geminiprotocol.net/docs/faq.gmi"},
{"gemini://example.com/蛸", "gemini://example.com/%E8%9B%B8"},
//{"gemini://gemini.circumlunar.space/%64%6f%63%73/;;.'%66%61%71蛸%2e%67%6d%69", "gemini://gemini.circumlunar.space/docs/%3B%3B.%27faq%E8%9B%B8.gmi"},
//{"gemini://geminiprotocol.net/%64%6f%63%73/;;.'%66%61%71蛸%2e%67%6d%69", "gemini://geminiprotocol.net/docs/%3B%3B.%27faq%E8%9B%B8.gmi"},
{"gemini://example.com/?%2Ch%64ello蛸", "gemini://example.com/?%2Chdello%E8%9B%B8"},
// IPv6 tests, see #195
{"gemini://[::1]", "gemini://[::1]/"},

22
command/command.go Normal file
View File

@ -0,0 +1,22 @@
package command
import (
"os/exec"
"strings"
)
// RunCommand runs `command`, replacing the string "${url}" with `url`.
func RunCommand(command string, url string) (string, error) {
cmdWithURL := strings.ReplaceAll(command, "${url}", url)
cmdSplit := strings.SplitN(cmdWithURL, " ", 2)
if len(cmdSplit) > 1 {
if err := exec.Command(cmdSplit[0], cmdSplit[1]).Start(); err != nil {
return "", err
}
return "Ran command " + cmdSplit[0] + " with args " + cmdSplit[1], nil
}
if err := exec.Command(cmdWithURL).Start(); err != nil {
return "", err
}
return "Ran command " + cmdWithURL, nil
}

View File

@ -190,7 +190,7 @@ func Init() error {
// Setup main config
viper.SetDefault("a-general.home", "gemini://gemini.circumlunar.space")
viper.SetDefault("a-general.home", "gemini://geminiprotocol.net")
viper.SetDefault("a-general.auto_redirect", false)
viper.SetDefault("a-general.http", "default")
viper.SetDefault("a-general.search", "gemini://geminispace.info/search")
@ -207,6 +207,16 @@ func Init() error {
viper.SetDefault("a-general.page_max_time", 10)
viper.SetDefault("a-general.scrollbar", "auto")
viper.SetDefault("a-general.underline", true)
viper.SetDefault("commands.command1", "")
viper.SetDefault("commands.command2", "")
viper.SetDefault("commands.command3", "")
viper.SetDefault("commands.command4", "")
viper.SetDefault("commands.command5", "")
viper.SetDefault("commands.command6", "")
viper.SetDefault("commands.command7", "")
viper.SetDefault("commands.command8", "")
viper.SetDefault("commands.command9", "")
viper.SetDefault("commands.command0", "")
viper.SetDefault("keybindings.bind_reload", []string{"R", "Ctrl-R"})
viper.SetDefault("keybindings.bind_home", "Backspace")
viper.SetDefault("keybindings.bind_bookmarks", "Ctrl-B")
@ -250,6 +260,26 @@ func Init() error {
viper.SetDefault("keybindings.bind_tab8", "*")
viper.SetDefault("keybindings.bind_tab9", "(")
viper.SetDefault("keybindings.bind_tab0", ")")
viper.SetDefault("keybindings.bind_command1", "Alt-!")
viper.SetDefault("keybindings.bind_command2", "Alt-@")
viper.SetDefault("keybindings.bind_command3", "Alt-#")
viper.SetDefault("keybindings.bind_command4", "Alt-$")
viper.SetDefault("keybindings.bind_command5", "Alt-%")
viper.SetDefault("keybindings.bind_command6", "Alt-^")
viper.SetDefault("keybindings.bind_command7", "Alt-&")
viper.SetDefault("keybindings.bind_command8", "Alt-*")
viper.SetDefault("keybindings.bind_command9", "Alt-(")
viper.SetDefault("keybindings.bind_command0", "Alt-)")
viper.SetDefault("keybindings.bind_command_target1", "Alt-1")
viper.SetDefault("keybindings.bind_command_target2", "Alt-2")
viper.SetDefault("keybindings.bind_command_target3", "Alt-3")
viper.SetDefault("keybindings.bind_command_target4", "Alt-4")
viper.SetDefault("keybindings.bind_command_target5", "Alt-5")
viper.SetDefault("keybindings.bind_command_target6", "Alt-6")
viper.SetDefault("keybindings.bind_command_target7", "Alt-7")
viper.SetDefault("keybindings.bind_command_target8", "Alt-8")
viper.SetDefault("keybindings.bind_command_target9", "Alt-9")
viper.SetDefault("keybindings.bind_command_target0", "Alt-0")
viper.SetDefault("keybindings.bind_copy_page_url", "C")
viper.SetDefault("keybindings.bind_copy_target_url", "c")
viper.SetDefault("keybindings.bind_beginning", []string{"Home", "g"})

View File

@ -25,7 +25,7 @@ var defaultConf = []byte(`# This is the default config file.
[a-general]
# Press Ctrl-H to access it
home = "gemini://gemini.circumlunar.space"
home = "gemini://geminiprotocol.net"
# Follow up to 5 Gemini redirects without prompting.
# A prompt is always shown after the 5th redirect and for redirects to protocols other than Gemini.
@ -112,6 +112,26 @@ underline = true
# Same as [auth.certs] but the path is to the client key file.
[commands]
# Define up to 10 custom commands to execute on the corresponding hotkey press.
# Commands are run in a new process and will not terminate when Amfora is closed.
# If you need your command to accept additional input, it is recommended to open
# a GUI or use a terminal multiplexer like screen or tmux. The string ${url} will
# be replaced with the current or selected URL. Note that pipes and redirections
# are not allowed, if these are needed then you should set up a script. Use only
# absolute paths and/or reference executables in your $PATH.
# command1 = "my-script -a -b -c ${url}"
# command2 = ""
# command3 = ""
# command4 = ""
# command5 = ""
# command6 = ""
# command7 = ""
# command8 = ""
# command9 = ""
# command0 = ""
[keybindings]
# If you have a non-US keyboard, use bind_tab1 through bind_tab0 to
# setup the shift-number bindings: Eg, for US keyboards (the default):
@ -159,6 +179,32 @@ underline = true
# bind_link9 = "9"
# bind_link0 = "0"
# The bind_command[0-9] options are for the command hotkeys. This will pass the URL of the
# current tab as an argument.
# bind_command1 = "Alt-!"
# bind_command2 = "Alt-@"
# bind_command3 = "Alt-#"
# bind_command4 = "Alt-$"
# bind_command5 = "Alt-%"
# bind_command6 = "Alt-^"
# bind_command7 = "Alt-&"
# bind_command8 = "Alt-*"
# bind_command9 = "Alt-("
# bind_command0 = "Alt-)"
# The bind_commandtarget[0-9] options are for command hotkeys that operate on the currently
# highlighted link. This will pass the URL of the highlighted link as an argument.
# bind_command_target1 = "Alt-1"
# bind_command_target2 = "Alt-2"
# bind_command_target3 = "Alt-3"
# bind_command_target4 = "Alt-4"
# bind_command_target5 = "Alt-5"
# bind_command_target6 = "Alt-6"
# bind_command_target7 = "Alt-7"
# bind_command_target8 = "Alt-8"
# bind_command_target9 = "Alt-9"
# bind_command_target0 = "Alt-0"
# All keybindings:
#
# bind_bottom

View File

@ -8,33 +8,55 @@ import (
"github.com/spf13/viper"
)
// NOTE: CmdLink[1-90] and CmdTab[1-90] need to be in-order and consecutive
// This property is used to simplify key handling in display/display.go
// NOTE: CmdLink[1-90], CmdTab[1-90], CmdCommand[1-90], and
// CmdCommandTarget[1-90] need to be in-order and consecutive. This
// property is used to simplify key handling in display/display.go
// and display/tab.go
type Command int
const (
CmdInvalid Command = 0
CmdLink1 = 1
CmdLink2 = 2
CmdLink3 = 3
CmdLink4 = 4
CmdLink5 = 5
CmdLink6 = 6
CmdLink7 = 7
CmdLink8 = 8
CmdLink9 = 9
CmdLink0 = 10
CmdTab1 = 11
CmdTab2 = 12
CmdTab3 = 13
CmdTab4 = 14
CmdTab5 = 15
CmdTab6 = 16
CmdTab7 = 17
CmdTab8 = 18
CmdTab9 = 19
CmdTab0 = 20
CmdBottom = iota
CmdInvalid Command = 0
CmdLink1 = 1
CmdLink2 = 2
CmdLink3 = 3
CmdLink4 = 4
CmdLink5 = 5
CmdLink6 = 6
CmdLink7 = 7
CmdLink8 = 8
CmdLink9 = 9
CmdLink0 = 10
CmdTab1 = 11
CmdTab2 = 12
CmdTab3 = 13
CmdTab4 = 14
CmdTab5 = 15
CmdTab6 = 16
CmdTab7 = 17
CmdTab8 = 18
CmdTab9 = 19
CmdTab0 = 20
CmdCommand1 = 21
CmdCommand2 = 22
CmdCommand3 = 23
CmdCommand4 = 24
CmdCommand5 = 25
CmdCommand6 = 26
CmdCommand7 = 27
CmdCommand8 = 28
CmdCommand9 = 29
CmdCommand0 = 30
CmdCommandTarget1 = 31
CmdCommandTarget2 = 32
CmdCommandTarget3 = 33
CmdCommandTarget4 = 34
CmdCommandTarget5 = 35
CmdCommandTarget6 = 36
CmdCommandTarget7 = 37
CmdCommandTarget8 = 38
CmdCommandTarget9 = 39
CmdCommandTarget0 = 40
CmdBottom = iota
CmdEdit
CmdHome
CmdBookmarks
@ -200,6 +222,26 @@ func KeyInit() {
CmdBeginning: "keybindings.bind_beginning",
CmdEnd: "keybindings.bind_end",
CmdURLHandlerOpen: "keybindings.bind_url_handler_open",
CmdCommand1: "keybindings.bind_command1",
CmdCommand2: "keybindings.bind_command2",
CmdCommand3: "keybindings.bind_command3",
CmdCommand4: "keybindings.bind_command4",
CmdCommand5: "keybindings.bind_command5",
CmdCommand6: "keybindings.bind_command6",
CmdCommand7: "keybindings.bind_command7",
CmdCommand8: "keybindings.bind_command8",
CmdCommand9: "keybindings.bind_command9",
CmdCommand0: "keybindings.bind_command0",
CmdCommandTarget1: "keybindings.bind_command_target1",
CmdCommandTarget2: "keybindings.bind_command_target2",
CmdCommandTarget3: "keybindings.bind_command_target3",
CmdCommandTarget4: "keybindings.bind_command_target4",
CmdCommandTarget5: "keybindings.bind_command_target5",
CmdCommandTarget6: "keybindings.bind_command_target6",
CmdCommandTarget7: "keybindings.bind_command_target7",
CmdCommandTarget8: "keybindings.bind_command_target8",
CmdCommandTarget9: "keybindings.bind_command_target9",
CmdCommandTarget0: "keybindings.bind_command_target0",
}
// This is split off to allow shift_numbers to override bind_tab[1-90]
// (This is needed for older configs so that the default bind_tab values

View File

@ -22,7 +22,7 @@
[a-general]
# Press Ctrl-H to access it
home = "gemini://gemini.circumlunar.space"
home = "gemini://geminiprotocol.net"
# Follow up to 5 Gemini redirects without prompting.
# A prompt is always shown after the 5th redirect and for redirects to protocols other than Gemini.
@ -109,6 +109,26 @@ underline = true
# Same as [auth.certs] but the path is to the client key file.
[commands]
# Define up to 10 custom commands to execute on the corresponding hotkey press.
# Commands are run in a new process and will not terminate when Amfora is closed.
# If you need your command to accept additional input, it is recommended to open
# a GUI or use a terminal multiplexer like screen or tmux. The string ${url} will
# be replaced with the current or selected URL. Note that pipes and redirections
# are not allowed, if these are needed then you should set up a script. Use only
# absolute paths and/or reference executables in your $PATH.
# command1 = "my-script -a -b -c ${url}"
# command2 = ""
# command3 = ""
# command4 = ""
# command5 = ""
# command6 = ""
# command7 = ""
# command8 = ""
# command9 = ""
# command0 = ""
[keybindings]
# If you have a non-US keyboard, use bind_tab1 through bind_tab0 to
# setup the shift-number bindings: Eg, for US keyboards (the default):
@ -156,6 +176,32 @@ underline = true
# bind_link9 = "9"
# bind_link0 = "0"
# The bind_command[0-9] options are for the command hotkeys. This will pass the URL of the
# current tab as an argument.
# bind_command1 = "Alt-!"
# bind_command2 = "Alt-@"
# bind_command3 = "Alt-#"
# bind_command4 = "Alt-$"
# bind_command5 = "Alt-%"
# bind_command6 = "Alt-^"
# bind_command7 = "Alt-&"
# bind_command8 = "Alt-*"
# bind_command9 = "Alt-("
# bind_command0 = "Alt-)"
# The bind_commandtarget[0-9] options are for command hotkeys that operate on the currently
# highlighted link. This will pass the URL of the highlighted link as an argument.
# bind_command_target1 = "Alt-1"
# bind_command_target2 = "Alt-2"
# bind_command_target3 = "Alt-3"
# bind_command_target4 = "Alt-4"
# bind_command_target5 = "Alt-5"
# bind_command_target6 = "Alt-6"
# bind_command_target7 = "Alt-7"
# bind_command_target8 = "Alt-8"
# bind_command_target9 = "Alt-9"
# bind_command_target0 = "Alt-0"
# All keybindings:
#
# bind_bottom

35
display/command.go Normal file
View File

@ -0,0 +1,35 @@
package display
import (
"strconv"
"github.com/makeworld-the-better-one/amfora/command"
"github.com/spf13/viper"
)
// CustomCommand runs custom commands as defined in the app configuration.
// Commands are zero-indexed, so 0 is command1 and 9 is command0 (10).
func CustomCommand(num int, url string) {
if num < 0 {
num = 0
}
num++
if num > 9 {
num = 0
}
cmd := viper.GetString("commands.command" + strconv.Itoa(num))
if len(cmd) > 0 {
msg, err := command.RunCommand(cmd, url)
if err != nil {
go Error("Command Error", err.Error())
return
}
go Info(msg)
} else {
go Error("Command Error", "Command "+strconv.Itoa(num)+" not defined")
return
}
App.Draw()
}

View File

@ -49,6 +49,10 @@ var helpCells = strings.TrimSpace(
"%s\tSave the current page to your downloads.\n" +
"%s\tView subscriptions\n" +
"%s\tAdd or update a subscription\n" +
"%s\tExecute a custom command using the current page URL as an argument.\n" +
"\t(Default: Alt-Shift-NUMBER)\n" +
"%s\tExecute a custom command using the selected URL as an argument.\n" +
"\t(Default: Alt-NUMBER)\n" +
"%s\tQuit\n")
var helpTable = cview.NewTextView()
@ -79,6 +83,10 @@ func helpInit() {
strings.Split(config.GetKeyBinding(config.CmdTab9), ",")[0])
linkKeys := fmt.Sprintf("%s to %s", strings.Split(config.GetKeyBinding(config.CmdLink1), ",")[0],
strings.Split(config.GetKeyBinding(config.CmdLink0), ",")[0])
commandKeys := fmt.Sprintf("%s to %s", strings.Split(config.GetKeyBinding(config.CmdCommand1), ",")[0],
strings.Split(config.GetKeyBinding(config.CmdCommand0), ",")[0])
commandTargetKeys := fmt.Sprintf("%s to %s", strings.Split(config.GetKeyBinding(config.CmdCommandTarget1), ",")[0],
strings.Split(config.GetKeyBinding(config.CmdCommandTarget0), ",")[0])
helpCells = fmt.Sprintf(helpCells,
config.GetKeyBinding(config.CmdMoveLeft),
@ -110,6 +118,8 @@ func helpInit() {
config.GetKeyBinding(config.CmdSave),
config.GetKeyBinding(config.CmdSub),
config.GetKeyBinding(config.CmdAddSub),
commandKeys,
commandTargetKeys,
config.GetKeyBinding(config.CmdQuit),
)

View File

@ -29,7 +29,7 @@ Happy browsing!
=> https://github.com/makeworld-the-better-one/amfora/wiki Amfora Wiki [GitHub]
=> gemini://makeworld.space/amfora-wiki/ Amfora Wiki [On Gemini!]
=> gemini://gemini.circumlunar.space Project Gemini
=> gemini://geminiprotocol.net Project Gemini
`
// Read the new tab content from a file if it exists or fallback to a default page.

View File

@ -240,6 +240,29 @@ func makeNewTab() *tab {
return nil
}
}
// Command key: 1-9, 0, COMMAND1
if cmd >= config.CmdCommand1 && cmd <= config.CmdCommand0 {
commandNum := int(cmd - config.CmdCommand1)
tabURL := tabs[curTab].page.URL
CustomCommand(commandNum, tabURL)
return nil
}
// Target link command key: 1-9, 0, COMMANDTARGET1-COMMANDTARGET10
if cmd >= config.CmdCommandTarget1 && cmd <= config.CmdCommandTarget0 {
commandNum := int(cmd - config.CmdCommandTarget1)
currentURL := t.page.URL
selectedURL := t.highlightedURL()
if selectedURL == "" {
return nil
}
u, _ := url.Parse(currentURL)
parsedURL, err := u.Parse(selectedURL)
if err == nil {
CustomCommand(commandNum, parsedURL.String())
}
return nil
}
// Scrolling stuff
// Copied in scrollTo