Make the fzf preview command customizable

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

@ -28,6 +28,8 @@ type NoteFinder struct {
type NoteFinderOpts struct {
// Indicates whether fzf is opened for every query, even if empty.
AlwaysFilter bool
// Preview command to run when selecting a note.
PreviewCmd opt.String
// When non nil, a "create new note from query" binding will be added to
// fzf to create a note in this directory.
NewNoteDir *zk.Dir
@ -84,10 +86,9 @@ func (f *NoteFinder) Find(opts note.FinderOpts) ([]note.Match, error) {
}
fzf, err := New(Opts{
// PreviewCmd: opt.NewString("bat -p --theme Nord --color always {1}"),
PreviewCmd: opt.NewString(zkBin + " list -f {{raw-content}} {1}"),
PreviewCmd: f.opts.PreviewCmd.OrString("cat {1}").NonEmpty(),
Padding: 2,
Bindings: bindings,
Bindings: bindings,
})
if err != nil {
return selectedMatches, err

@ -45,6 +45,7 @@ func (cmd *Edit) Run(container *Container) error {
err = db.WithTransaction(func(tx sqlite.Transaction) error {
finder := container.NoteFinder(tx, fzf.NoteFinderOpts{
AlwaysFilter: true,
PreviewCmd: zk.Config.Fzf.Preview,
NewNoteDir: cmd.newNoteDir(zk),
BasePath: zk.Path,
CurrentPath: wd,

@ -61,6 +61,7 @@ func (cmd *List) Run(container *Container) error {
err = db.WithTransaction(func(tx sqlite.Transaction) error {
finder := container.NoteFinder(tx, fzf.NoteFinderOpts{
AlwaysFilter: false,
PreviewCmd: zk.Config.Fzf.Preview,
BasePath: zk.Path,
CurrentPath: wd,
})

@ -100,7 +100,7 @@ func create(
deps createDeps,
) (*createdNote, error) {
context := renderContext{
Title: opts.Title.OrDefault(opts.Dir.Config.DefaultTitle),
Title: opts.Title.OrString(opts.Dir.Config.DefaultTitle).Unwrap(),
Content: opts.Content.Unwrap(),
Dir: opts.Dir.Name,
Extra: opts.Dir.Config.Extra,

@ -46,7 +46,7 @@ func NewFormatter(basePath string, currentPath string, format opt.String, templa
}
func resolveFormatTemplate(format opt.String) string {
templ, ok := formatTemplates[format.OrDefault("short")]
templ, ok := formatTemplates[format.OrString("short").Unwrap()]
if !ok {
templ = format.String()
// Replace raw \n and \t by actual newlines and tabs in user format.

@ -14,6 +14,7 @@ type Config struct {
Dirs map[string]DirConfig
Editor opt.String
Pager opt.String
Fzf FzfConfig
Aliases map[string]string
}
@ -28,6 +29,11 @@ type DirConfig struct {
Extra map[string]string
}
// FzfConfig holds the user configuration for running fzf.
type FzfConfig struct {
Preview opt.String
}
// ConfigOverrides holds user configuration overriden values, for example fed
// from CLI flags.
type ConfigOverrides struct {
@ -128,7 +134,10 @@ func ParseConfig(content []byte, templatesDir string) (*Config, error) {
Dirs: dirs,
Editor: opt.NewNotEmptyString(tomlConf.Editor),
Pager: opt.NewStringWithPtr(tomlConf.Pager),
Aliases: aliases,
Fzf: FzfConfig{
Preview: opt.NewStringWithPtr(tomlConf.Fzf.Preview),
},
Aliases: aliases,
}, nil
}
@ -190,6 +199,7 @@ type tomlConfig struct {
Dirs map[string]tomlDirConfig `toml:"dir"`
Editor string
Pager *string
Fzf tomlFzfConfig
Aliases map[string]string `toml:"alias"`
}
@ -209,6 +219,10 @@ type tomlIDConfig struct {
Case string
}
type tomlFzfConfig struct {
Preview *string
}
func charsetFromString(charset string) Charset {
switch charset {
case "alphanum":

@ -14,8 +14,6 @@ func TestParseDefaultConfig(t *testing.T) {
assert.Nil(t, err)
assert.Equal(t, conf, &Config{
Editor: opt.NullString,
Pager: opt.NullString,
DirConfig: DirConfig{
FilenameTemplate: "{{id}}",
Extension: "md",
@ -29,7 +27,12 @@ func TestParseDefaultConfig(t *testing.T) {
Lang: "en",
Extra: make(map[string]string),
},
Dirs: make(map[string]DirConfig),
Dirs: make(map[string]DirConfig),
Editor: opt.NullString,
Pager: opt.NullString,
Fzf: FzfConfig{
Preview: opt.NullString,
},
Aliases: make(map[string]string),
})
}
@ -57,6 +60,9 @@ func TestParseComplete(t *testing.T) {
length = 4
case = "lower"
[fzf]
preview = "bat {1}"
[extra]
hello = "world"
salut = "le monde"
@ -139,6 +145,9 @@ func TestParseComplete(t *testing.T) {
},
Editor: opt.NewString("vim"),
Pager: opt.NewString("less"),
Fzf: FzfConfig{
Preview: opt.NewString("bat {1}"),
},
Aliases: map[string]string{
"ls": "zk list $@",
"ed": "zk edit $@",
@ -236,12 +245,20 @@ func TestParseMergesDirConfig(t *testing.T) {
})
}
func TestParsePreserveEmptyPager(t *testing.T) {
conf, err := ParseConfig([]byte(`pager = ""`), "")
// Some properties like `pager` and `fzf.preview` differentiate between not
// being set and an empty string.
func TestParsePreservePropertiesAllowingEmptyValues(t *testing.T) {
conf, err := ParseConfig([]byte(`
pager = ""
[fzf]
preview = ""
`), "")
assert.Nil(t, err)
assert.Equal(t, conf.Pager.IsNull(), false)
assert.Equal(t, conf.Pager, opt.NewString(""))
assert.Equal(t, conf.Fzf.Preview.IsNull(), false)
assert.Equal(t, conf.Fzf.Preview, opt.NewString(""))
}
func TestParseIDCharset(t *testing.T) {

@ -41,6 +41,15 @@ func (s String) IsEmpty() bool {
return !s.IsNull() && *s.value == ""
}
// NonEmpty returns a null String if the String is empty.
func (s String) NonEmpty() String {
if s.IsEmpty() {
return NullString
} else {
return s
}
}
// Or returns the receiver if it is not null, otherwise the given optional
// String.
func (s String) Or(other String) String {
@ -51,19 +60,23 @@ func (s String) Or(other String) String {
}
}
// OrDefault returns the optional String value or the given default string if
// OrString returns the optional String value or the given default string if
// it is null.
func (s String) OrDefault(def string) string {
func (s String) OrString(alt string) String {
if s.IsNull() {
return def
return NewString(alt)
} else {
return *s.value
return s
}
}
// Unwrap returns the optional String value or an empty String if none is set.
func (s String) Unwrap() string {
return s.OrDefault("")
if s.IsNull() {
return ""
} else {
return *s.value
}
}
func (s String) Equal(other String) bool {
@ -72,7 +85,7 @@ func (s String) Equal(other String) bool {
}
func (s String) String() string {
return s.OrDefault("")
return s.Unwrap()
}
func (s String) MarshalJSON() ([]byte, error) {

Loading…
Cancel
Save