mirror of
https://git.sr.ht/~rjarry/aerc
synced 2025-12-12 20:36:12 +01:00
Instead of having a hard-coded list of help topics, change the :help command completion to list available man pages as listed by: man -k aerc Append each man page short description to the completion choices. In case mandb isn't up to date, or if running aerc without installing it, fallback to a hard-coded list. I didn't try to walk the "doc" folder since the working directory isn't guaranteed. Also, in order for this to work properly, mandb must be executed after installing the man pages. This isn't part of the makefile since it would cause issues in downstream builds which install in staging directories. Add a mention of mandb in the installation instructions. Signed-off-by: Robin Jarry <robin@jarry.cc> Tested-by: Antonin Godard <antonin@godard.cc>
115 lines
2.4 KiB
Go
115 lines
2.4 KiB
Go
package commands
|
|
|
|
import (
|
|
"fmt"
|
|
"os/exec"
|
|
"regexp"
|
|
"sort"
|
|
"strings"
|
|
|
|
"git.sr.ht/~rjarry/aerc/app"
|
|
)
|
|
|
|
type Help struct {
|
|
Topic string `opt:"topic" action:"ParseTopic" default:"aerc" complete:"CompleteTopic" desc:"Help topic."`
|
|
}
|
|
|
|
func init() {
|
|
Register(Help{})
|
|
}
|
|
|
|
func (Help) Description() string {
|
|
return "Display one of aerc's man pages in the embedded terminal."
|
|
}
|
|
|
|
func (Help) Context() CommandContext {
|
|
return GLOBAL
|
|
}
|
|
|
|
func (Help) Aliases() []string {
|
|
return []string{"help", "man"}
|
|
}
|
|
|
|
var aproposRe = regexp.MustCompile(`(?m)^aerc(?:-([a-z]+))?\s+\([0-9]\)\s+-\s+(.+)$`)
|
|
|
|
func getTopics() map[string]string {
|
|
topics := map[string]string{"keys": "Display contextual key bindings."}
|
|
cmd := exec.Command("man", "-k", "aerc")
|
|
out, err := cmd.CombinedOutput()
|
|
if err != nil {
|
|
// mandb not up to date, return "something"
|
|
topics["aerc"] = ""
|
|
topics["accounts"] = ""
|
|
topics["binds"] = ""
|
|
topics["config"] = ""
|
|
topics["imap"] = ""
|
|
topics["jmap"] = ""
|
|
topics["maildir"] = ""
|
|
topics["notmuch"] = ""
|
|
topics["patch"] = ""
|
|
topics["search"] = ""
|
|
topics["sendmail"] = ""
|
|
topics["smtp"] = ""
|
|
topics["stylesets"] = ""
|
|
topics["templates"] = ""
|
|
topics["tutorial"] = ""
|
|
return topics
|
|
}
|
|
for _, match := range aproposRe.FindAllSubmatch(out, -1) {
|
|
name := string(match[1])
|
|
if name == "" {
|
|
name = "aerc"
|
|
}
|
|
desc := strings.ReplaceAll(string(match[2]), " for aerc(1)", "")
|
|
if !strings.HasSuffix(desc, ".") {
|
|
desc += "."
|
|
}
|
|
desc = strings.ToUpper(desc[0:1]) + desc[1:]
|
|
topics[name] = desc
|
|
}
|
|
return topics
|
|
}
|
|
|
|
func (*Help) CompleteTopic(arg string) []string {
|
|
var pages []string
|
|
for name, desc := range getTopics() {
|
|
if desc != "" {
|
|
name += "\n" + desc
|
|
}
|
|
pages = append(pages, name)
|
|
}
|
|
sort.Strings(pages)
|
|
return FilterList(pages, arg, nil)
|
|
}
|
|
|
|
func (h *Help) ParseTopic(arg string) error {
|
|
topics := getTopics()
|
|
if _, ok := topics[arg]; ok {
|
|
if arg != "aerc" {
|
|
arg = "aerc-" + arg
|
|
}
|
|
h.Topic = arg
|
|
return nil
|
|
}
|
|
return fmt.Errorf("unknown topic %q", arg)
|
|
}
|
|
|
|
func (h Help) Execute(args []string) error {
|
|
if h.Topic == "aerc-keys" {
|
|
app.AddDialog(app.DefaultDialog(
|
|
app.NewListBox(
|
|
"Bindings: Press <Esc> or <Enter> to close. "+
|
|
"Start typing to filter bindings.",
|
|
app.HumanReadableBindings(),
|
|
app.SelectedAccountUiConfig(),
|
|
func(_ string) {
|
|
app.CloseDialog()
|
|
},
|
|
),
|
|
))
|
|
return nil
|
|
}
|
|
term := Term{Cmd: []string{"man", h.Topic}}
|
|
return term.Execute(args)
|
|
}
|