Add support for user aliases

pull/6/head
Mickaël Menu 3 years ago
parent 1b905dacfd
commit 225b0c2603
No known key found for this signature in database
GPG Key ID: 53D73664CD359895

@ -2,6 +2,7 @@ package cmd
import (
"io"
"sync"
"github.com/mickael-menu/zk/adapter/fzf"
"github.com/mickael-menu/zk/adapter/handlebars"
@ -20,6 +21,10 @@ type Container struct {
Logger util.Logger
Terminal *term.Terminal
templateLoader *handlebars.Loader
zkOnce sync.Once
zk *zk.Zk
zkErr error
}
func NewContainer() *Container {
@ -34,6 +39,13 @@ func NewContainer() *Container {
}
}
func (c *Container) OpenZk() (*zk.Zk, error) {
c.zkOnce.Do(func() {
c.zk, c.zkErr = zk.Open(".")
})
return c.zk, c.zkErr
}
func (c *Container) TemplateLoader(lang string) *handlebars.Loader {
if c.templateLoader == nil {
handlebars.Init(lang, c.Logger, c.Terminal)

@ -6,7 +6,6 @@ import (
"github.com/mickael-menu/zk/adapter/sqlite"
"github.com/mickael-menu/zk/core/note"
"github.com/mickael-menu/zk/core/zk"
"github.com/mickael-menu/zk/util/errors"
)
@ -18,7 +17,7 @@ type Edit struct {
}
func (cmd *Edit) Run(container *Container) error {
zk, err := zk.Open(".")
zk, err := container.OpenZk()
if err != nil {
return err
}
@ -61,6 +60,8 @@ func (cmd *Edit) Run(container *Container) error {
}
note.Edit(zk, paths...)
} else {
fmt.Println("Found 0 note")
}
return err

@ -7,7 +7,6 @@ import (
"github.com/mickael-menu/zk/adapter/sqlite"
"github.com/mickael-menu/zk/core/note"
"github.com/mickael-menu/zk/core/zk"
"github.com/mickael-menu/zk/util/paths"
"github.com/schollz/progressbar/v3"
)
@ -20,7 +19,7 @@ type Index struct {
}
func (cmd *Index) Run(container *Container) error {
zk, err := zk.Open(".")
zk, err := container.OpenZk()
if err != nil {
return err
}

@ -7,7 +7,6 @@ import (
"github.com/mickael-menu/zk/adapter/sqlite"
"github.com/mickael-menu/zk/core/note"
"github.com/mickael-menu/zk/core/zk"
"github.com/mickael-menu/zk/util/errors"
"github.com/mickael-menu/zk/util/opt"
"github.com/mickael-menu/zk/util/strings"
@ -22,7 +21,7 @@ type List struct {
}
func (cmd *List) Run(container *Container) error {
zk, err := zk.Open(".")
zk, err := container.OpenZk()
if err != nil {
return err
}

@ -12,7 +12,7 @@ import (
// New adds a new note to the slip box.
type New struct {
Directory string `arg optional type:"path" default:"." help:"Directory in which to create the note"`
PrintPath bool `help:"Prints the path of the created note to stdin instead of editing it"`
PrintPath bool `help:"Prints the path of the created note to stdin instead of editing it" short:"p"`
Title string `short:"t" help:"Title of the new note" placeholder:"<title>"`
Template string `type:"path" help:"Custom template to use to render the note" placeholder:"<path>"`
Extra map[string]string `help:"Extra variables passed to the templates"`
@ -26,7 +26,7 @@ func (cmd *New) ConfigOverrides() zk.ConfigOverrides {
}
func (cmd *New) Run(container *Container) error {
zk, err := zk.Open(".")
zk, err := container.OpenZk()
if err != nil {
return err
}

@ -15,6 +15,7 @@ type Config struct {
Editor opt.String
Pager opt.String
NoPager bool
Aliases map[string]string
}
// DirConfig holds the user configuration for a given directory.
@ -113,19 +114,26 @@ func ParseConfig(content []byte, templatesDir string) (*Config, error) {
}
}
config := Config{
DirConfig: root,
Dirs: make(map[string]DirConfig),
Editor: opt.NewNotEmptyString(hcl.Editor),
Pager: opt.NewNotEmptyString(hcl.Pager),
NoPager: hcl.NoPager,
dirs := make(map[string]DirConfig)
for _, dirHCL := range hcl.Dirs {
dirs[dirHCL.Dir] = root.merge(dirHCL, templatesDir)
}
for _, dirHCL := range hcl.Dirs {
config.Dirs[dirHCL.Dir] = root.merge(dirHCL, templatesDir)
aliases := make(map[string]string)
if hcl.Aliases != nil {
for k, v := range hcl.Aliases {
aliases[k] = v
}
}
return &config, nil
return &Config{
DirConfig: root,
Dirs: dirs,
Editor: opt.NewNotEmptyString(hcl.Editor),
Pager: opt.NewNotEmptyString(hcl.Pager),
NoPager: hcl.NoPager,
Aliases: aliases,
}, nil
}
func (c DirConfig) merge(hcl hclDirConfig, templatesDir string) DirConfig {
@ -189,6 +197,7 @@ type hclConfig struct {
Editor string `hcl:"editor,optional"`
Pager string `hcl:"pager,optional"`
NoPager bool `hcl:"no-pager,optional"`
Aliases map[string]string `hcl:"aliases,optional"`
}
type hclDirConfig struct {

@ -28,7 +28,8 @@ func TestParseDefaultConfig(t *testing.T) {
Lang: "en",
Extra: make(map[string]string),
},
Dirs: make(map[string]DirConfig),
Dirs: make(map[string]DirConfig),
Aliases: make(map[string]string),
})
}
@ -45,6 +46,11 @@ func TestParseComplete(t *testing.T) {
editor = "vim"
pager = "less"
no-pager = true
aliases = {
ls = "zk list $@"
ed = "zk edit $@"
}
filename = "{{id}}.note"
extension = "txt"
template = "default.note"
@ -135,6 +141,10 @@ func TestParseComplete(t *testing.T) {
Editor: opt.NewString("vim"),
Pager: opt.NewString("less"),
NoPager: true,
Aliases: map[string]string{
"ls": "zk list $@",
"ed": "zk edit $@",
},
})
}
@ -223,6 +233,7 @@ func TestParseMergesDirConfig(t *testing.T) {
},
},
},
Aliases: make(map[string]string),
})
}

@ -1,8 +1,13 @@
package main
import (
"fmt"
"os"
"os/exec"
"github.com/alecthomas/kong"
"github.com/mickael-menu/zk/cmd"
executil "github.com/mickael-menu/zk/util/exec"
)
var Version = "dev"
@ -18,25 +23,73 @@ var cli struct {
Version kong.VersionFlag `help:"Print zk version"`
}
// NoInput is a flag preventing any user prompt when enabled.
type NoInput bool
func (f NoInput) BeforeApply(container *cmd.Container) error {
container.Terminal.NoInput = true
return nil
}
func main() {
// Create the dependency graph.
container := cmd.NewContainer()
ctx := kong.Parse(&cli,
kong.Bind(container),
kong.Name("zk"),
kong.Vars{
"version": Version,
},
)
err := ctx.Run(container)
ctx.FatalIfErrorf(err)
indexZk(container)
if isAlias, err := runAlias(container, os.Args[1:]); isAlias {
fatalIfError(err)
} else {
ctx := kong.Parse(&cli,
kong.Bind(container),
kong.Name("zk"),
kong.Vars{
"version": Version,
},
)
err := ctx.Run(container)
ctx.FatalIfErrorf(err)
}
}
// NoInput is a flag preventing any user prompt when enabled.
type NoInput bool
func fatalIfError(err error) {
if err != nil {
fmt.Fprintf(os.Stderr, "zk: error: %v\n", err)
os.Exit(1)
}
}
func (f NoInput) BeforeApply(container *cmd.Container) error {
container.Terminal.NoInput = true
return nil
// indexZk will index any slip box in the working directory.
func indexZk(container *cmd.Container) {
(&cmd.Index{Quiet: true}).Run(container)
}
// runAlias will execute a user alias if the command is one of them.
func runAlias(container *cmd.Container, args []string) (bool, error) {
if zk, err := container.OpenZk(); err == nil && len(args) >= 1 {
for alias, cmdStr := range zk.Config.Aliases {
if alias != args[0] {
continue
}
cmd := executil.CommandFromString(cmdStr, args...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Run()
if err != nil {
if err, ok := err.(*exec.ExitError); ok {
os.Exit(err.ExitCode())
return true, nil
} else {
return true, err
}
}
return true, nil
}
}
return false, nil
}

@ -8,10 +8,11 @@ import (
)
// CommandFromString returns a Cmd running the given command with $SHELL.
func CommandFromString(command string) *exec.Cmd {
func CommandFromString(command string, args ...string) *exec.Cmd {
shell := os.Getenv("SHELL")
if len(shell) == 0 {
shell = "sh"
}
return exec.Command(shell, "-c", command)
args = append([]string{"-c", command}, args...)
return exec.Command(shell, args...)
}

Loading…
Cancel
Save