2021-01-14 21:10:35 +00:00
|
|
|
package note
|
|
|
|
|
|
|
|
import (
|
2021-02-07 16:48:23 +00:00
|
|
|
"errors"
|
2021-01-14 21:45:05 +00:00
|
|
|
"fmt"
|
|
|
|
"strings"
|
2021-01-14 21:10:35 +00:00
|
|
|
"time"
|
2021-01-14 21:45:05 +00:00
|
|
|
"unicode/utf8"
|
2021-03-13 14:31:05 +00:00
|
|
|
|
|
|
|
"github.com/mickael-menu/zk/core"
|
|
|
|
"github.com/mickael-menu/zk/util/opt"
|
2021-01-14 21:10:35 +00:00
|
|
|
)
|
|
|
|
|
2021-02-07 16:48:23 +00:00
|
|
|
// ErrCanceled is returned when the user cancelled an operation.
|
|
|
|
var ErrCanceled = errors.New("canceled")
|
|
|
|
|
2021-01-14 21:10:35 +00:00
|
|
|
// Finder retrieves notes matching the given options.
|
|
|
|
//
|
|
|
|
// Returns the number of matches found.
|
|
|
|
type Finder interface {
|
2021-01-23 12:29:14 +00:00
|
|
|
Find(opts FinderOpts) ([]Match, error)
|
2021-01-14 21:10:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// FinderOpts holds the option used to filter and order a list of notes.
|
|
|
|
type FinderOpts struct {
|
2021-03-13 14:31:05 +00:00
|
|
|
// Filter used to match the notes with FTS predicates.
|
|
|
|
Match opt.String
|
|
|
|
// Filter by note paths.
|
|
|
|
IncludePaths []string
|
|
|
|
// Filter excluding notes at the given paths.
|
|
|
|
ExcludePaths []string
|
|
|
|
// Filter excluding notes with the given IDs.
|
|
|
|
ExcludeIds []core.NoteId
|
|
|
|
// Filter by tags found in the notes.
|
|
|
|
Tags []string
|
|
|
|
// Filter the notes mentioning the given notes.
|
|
|
|
Mention []string
|
|
|
|
// Filter to select notes being linked by another one.
|
|
|
|
LinkedBy *LinkedByFilter
|
|
|
|
// Filter to select notes linking to another one.
|
|
|
|
LinkTo *LinkToFilter
|
|
|
|
// Filter to select notes which could might be related to the given notes paths.
|
|
|
|
Related []string
|
|
|
|
// Filter to select notes having no other notes linking to them.
|
|
|
|
Orphan bool
|
|
|
|
// Filter notes created after the given date.
|
|
|
|
CreatedStart *time.Time
|
|
|
|
// Filter notes created before the given date.
|
|
|
|
CreatedEnd *time.Time
|
|
|
|
// Filter notes modified after the given date.
|
|
|
|
ModifiedStart *time.Time
|
|
|
|
// Filter notes modified before the given date.
|
|
|
|
ModifiedEnd *time.Time
|
|
|
|
// Indicates that the user should select manually the notes.
|
|
|
|
Interactive bool
|
|
|
|
// Limits the number of results
|
|
|
|
Limit int
|
|
|
|
// Sorting criteria
|
2021-01-14 21:10:35 +00:00
|
|
|
Sorters []Sorter
|
|
|
|
}
|
|
|
|
|
|
|
|
// Match holds information about a note matching the find options.
|
|
|
|
type Match struct {
|
|
|
|
Metadata
|
2021-01-30 17:08:02 +00:00
|
|
|
// Snippets are relevant excerpts in the note.
|
|
|
|
Snippets []string
|
2021-01-14 21:10:35 +00:00
|
|
|
}
|
|
|
|
|
2021-01-25 21:57:12 +00:00
|
|
|
// LinkedByFilter is a note filter used to select notes being linked by another one.
|
2021-01-27 20:25:33 +00:00
|
|
|
type LinkedByFilter struct {
|
2021-01-31 16:07:28 +00:00
|
|
|
Paths []string
|
|
|
|
Negate bool
|
|
|
|
Recursive bool
|
|
|
|
MaxDistance int
|
2021-01-27 20:25:33 +00:00
|
|
|
}
|
2021-01-25 21:57:12 +00:00
|
|
|
|
2021-03-13 14:31:05 +00:00
|
|
|
// LinkToFilter is a note filter used to select notes linking to another one.
|
2021-03-07 16:14:07 +00:00
|
|
|
type LinkToFilter struct {
|
2021-01-31 16:07:28 +00:00
|
|
|
Paths []string
|
|
|
|
Negate bool
|
|
|
|
Recursive bool
|
|
|
|
MaxDistance int
|
2021-01-27 20:25:33 +00:00
|
|
|
}
|
2021-01-27 19:20:26 +00:00
|
|
|
|
2021-01-14 21:10:35 +00:00
|
|
|
// Sorter represents an order term used to sort a list of notes.
|
|
|
|
type Sorter struct {
|
|
|
|
Field SortField
|
|
|
|
Ascending bool
|
|
|
|
}
|
|
|
|
|
|
|
|
// SortField represents a note field used to sort a list of notes.
|
|
|
|
type SortField int
|
|
|
|
|
|
|
|
const (
|
|
|
|
// Sort by creation date.
|
|
|
|
SortCreated SortField = iota + 1
|
|
|
|
// Sort by modification date.
|
|
|
|
SortModified
|
|
|
|
// Sort by the file paths.
|
|
|
|
SortPath
|
|
|
|
// Sort randomly.
|
|
|
|
SortRandom
|
|
|
|
// Sort by the note titles.
|
|
|
|
SortTitle
|
|
|
|
// Sort by the number of words in the note bodies.
|
|
|
|
SortWordCount
|
|
|
|
)
|
2021-01-14 21:45:05 +00:00
|
|
|
|
|
|
|
// 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:
|
2021-02-10 19:27:34 +00:00
|
|
|
return sorter, fmt.Errorf("%s: unknown sorting term\ntry created, modified, path, title, random or word-count", str)
|
2021-01-14 21:45:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
2021-02-27 19:24:12 +00:00
|
|
|
|
|
|
|
// Iterates in reverse order to be able to override sort criteria set in a
|
|
|
|
// config alias with a `--sort` flag.
|
|
|
|
for i := len(strs) - 1; i >= 0; i-- {
|
|
|
|
sorter, err := SorterFromString(strs[i])
|
2021-01-14 21:45:05 +00:00
|
|
|
if err != nil {
|
|
|
|
return sorters, err
|
|
|
|
}
|
|
|
|
sorters = append(sorters, sorter)
|
|
|
|
}
|
|
|
|
return sorters, nil
|
|
|
|
}
|