Move parsing of sorting terms to core

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

@ -2,9 +2,7 @@ package cmd
import (
"fmt"
"strings"
"time"
"unicode/utf8"
"github.com/mickael-menu/zk/adapter/sqlite"
"github.com/mickael-menu/zk/core/note"
@ -16,18 +14,18 @@ import (
// List displays notes matching a set of criteria.
type List struct {
Path []string `arg optional placeholder:"GLOB"`
Format string `help:"Pretty prints the list using the given format" short:"f" placeholder:"TEMPLATE"`
Match string `help:"Terms to search for in the notes" short:"m" placeholder:"TERMS"`
Limit int `help:"Limit the number of results" short:"n" placeholder:"MAX"`
Created string `help:"Show only the notes created on the given date" placeholder:"DATE"`
CreatedBefore string `help:"Show only the notes created before the given date" placeholder:"DATE"`
CreatedAfter string `help:"Show only the notes created after the given date" placeholder:"DATE"`
Modified string `help:"Show only the notes modified on the given date" placeholder:"DATE"`
ModifiedBefore string `help:"Show only the notes modified before the given date" placeholder:"DATE"`
ModifiedAfter string `help:"Show only the notes modified after the given date" placeholder:"DATE"`
Exclude []string `help:"Excludes notes matching the given file path pattern from the list" short:"x" placeholder:"GLOB"`
Sort []string `help:"Sort the notes by the given criterion" short:"s" placeholder:"CRITERION"`
Path []string `arg optional placeholder:"<glob>"`
Format string `help:"Pretty prints the list using the given format" short:"f" placeholder:"<template>"`
Match string `help:"Terms to search for in the notes" short:"m" placeholder:"<query>"`
Limit int `help:"Limit the number of results" short:"n" placeholder:"<count>"`
Created string `help:"Show only the notes created on the given date" placeholder:"<date>"`
CreatedBefore string `help:"Show only the notes created before the given date" placeholder:"<date>"`
CreatedAfter string `help:"Show only the notes created after the given date" placeholder:"<date>"`
Modified string `help:"Show only the notes modified on the given date" placeholder:"<date>"`
ModifiedBefore string `help:"Show only the notes modified before the given date" placeholder:"<date>"`
ModifiedAfter string `help:"Show only the notes modified after the given date" placeholder:"<date>"`
Exclude []string `help:"Excludes notes matching the given file path pattern from the list" short:"x" placeholder:"<glob>"`
Sort []string `help:"Sort the notes by the given criterion" short:"s" placeholder:"<term>"`
}
func (cmd *List) Run(container *Container) error {
@ -153,7 +151,7 @@ func (cmd *List) ListOpts(zk *zk.Zk) (*note.ListOpts, error) {
})
}
sorters, err := sorters(cmd.Sort)
sorters, err := note.SortersFromStrings(cmd.Sort)
if err != nil {
return nil, err
}
@ -188,65 +186,3 @@ func parseDate(date string) (time.Time, error) {
// FIXME: support years
return naturaldate.Parse(date, time.Now().UTC(), naturaldate.WithDirection(naturaldate.Past))
}
func sorters(terms []string) ([]note.Sorter, error) {
sorters := make([]note.Sorter, 0)
for _, term := range terms {
orderSymbol, _ := utf8.DecodeLastRuneInString(term)
term = strings.TrimRight(term, "+-")
sorter, err := sorter(term)
if err != nil {
return sorters, err
}
switch orderSymbol {
case '+':
sorter.Ascending = true
case '-':
sorter.Ascending = false
}
sorters = append(sorters, sorter)
}
return sorters, nil
}
func sorter(term string) (sorter note.Sorter, err error) {
switch {
case strings.HasPrefix("created", term):
sorter = note.Sorter{Field: note.SortCreated, Ascending: false}
case strings.HasPrefix("modified", term):
sorter = note.Sorter{Field: note.SortModified, Ascending: false}
case strings.HasPrefix("path", term):
sorter = note.Sorter{Field: note.SortPath, Ascending: true}
case strings.HasPrefix("title", term):
sorter = note.Sorter{Field: note.SortTitle, Ascending: true}
case strings.HasPrefix("random", term):
sorter = note.Sorter{Field: note.SortRandom, Ascending: true}
case strings.HasPrefix("word-count", term) || term == "wc":
sorter = note.Sorter{Field: note.SortWordCount, Ascending: true}
default:
err = fmt.Errorf("%s: unknown sorting term", term)
}
return
}
func sortAscending(symbol rune, term string) bool {
switch term {
case "created":
return false
case "modified":
return false
case "path":
return true
case "title":
return true
case "random":
return true
case "word-count":
return true
}
return true
}

@ -13,8 +13,8 @@ import (
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"`
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"`
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"`
}

@ -1,7 +1,10 @@
package note
import (
"fmt"
"strings"
"time"
"unicode/utf8"
)
// Finder retrieves notes matching the given options.
@ -87,3 +90,53 @@ const (
// Sort by the number of words in the note bodies.
SortWordCount
)
// SorterFromString returns a Sorter from its string representation.
//
// If the input str has for suffix `+`, then the order will be ascending, while
// descending for `-`. If no suffix is given, then the default order for the
// sorting field will be used.
func SorterFromString(str string) (Sorter, error) {
orderSymbol, _ := utf8.DecodeLastRuneInString(str)
str = strings.TrimRight(str, "+-")
var sorter Sorter
switch str {
case "created", "c":
sorter = Sorter{Field: SortCreated, Ascending: false}
case "modified", "m":
sorter = Sorter{Field: SortModified, Ascending: false}
case "path", "p":
sorter = Sorter{Field: SortPath, Ascending: true}
case "title", "t":
sorter = Sorter{Field: SortTitle, Ascending: true}
case "random", "r":
sorter = Sorter{Field: SortRandom, Ascending: true}
case "word-count", "wc":
sorter = Sorter{Field: SortWordCount, Ascending: true}
default:
return sorter, fmt.Errorf("%s: unknown sorting term", str)
}
switch orderSymbol {
case '+':
sorter.Ascending = true
case '-':
sorter.Ascending = false
}
return sorter, nil
}
// SortersFromStrings returns a list of Sorter from their string representation.
func SortersFromStrings(strs []string) ([]Sorter, error) {
sorters := make([]Sorter, 0)
for _, str := range strs {
sorter, err := SorterFromString(str)
if err != nil {
return sorters, err
}
sorters = append(sorters, sorter)
}
return sorters, nil
}

@ -0,0 +1,66 @@
package note
import (
"testing"
"github.com/mickael-menu/zk/util/test/assert"
)
func TestSorterFromString(t *testing.T) {
test := func(str string, expectedField SortField, expectedAscending bool) {
actual, err := SorterFromString(str)
assert.Nil(t, err)
assert.Equal(t, actual, Sorter{Field: expectedField, Ascending: expectedAscending})
}
test("c", SortCreated, false)
test("c+", SortCreated, true)
test("created", SortCreated, false)
test("created-", SortCreated, false)
test("created+", SortCreated, true)
test("m", SortModified, false)
test("modified", SortModified, false)
test("modified+", SortModified, true)
test("p", SortPath, true)
test("path", SortPath, true)
test("path-", SortPath, false)
test("t", SortTitle, true)
test("title", SortTitle, true)
test("title-", SortTitle, false)
test("r", SortRandom, true)
test("random", SortRandom, true)
test("random-", SortRandom, false)
test("wc", SortWordCount, true)
test("word-count", SortWordCount, true)
test("word-count-", SortWordCount, false)
_, err := SorterFromString("foobar")
assert.Err(t, err, "foobar: unknown sorting term")
}
func TestSortersFromStrings(t *testing.T) {
test := func(strs []string, expected []Sorter) {
actual, err := SortersFromStrings(strs)
assert.Nil(t, err)
assert.Equal(t, actual, expected)
}
test([]string{}, []Sorter{})
test([]string{"created"}, []Sorter{
{Field: SortCreated, Ascending: false},
})
test([]string{"c+", "title"}, []Sorter{
{Field: SortCreated, Ascending: true},
{Field: SortTitle, Ascending: true},
})
_, err := SortersFromStrings([]string{"c", "foobar"})
assert.Err(t, err, "foobar: unknown sorting term")
}
Loading…
Cancel
Save