mirror of
https://github.com/mickael-menu/zk
synced 2024-11-07 15:20:21 +00:00
Exclude a tag with the --tag filtering option
This commit is contained in:
parent
f1391b5a63
commit
bae1fab567
@ -7,7 +7,9 @@ All notable changes to this project will be documented in this file.
|
||||
### Added
|
||||
|
||||
* Support for tags.
|
||||
* Filter notes by their tags using `--tag "history, europe"`. To match notes associated with either tags, use a pipe `|` or `OR` (all caps), e.g. `--tag "inbox OR todo"`.
|
||||
* Filter notes by their tags using `--tag "history, europe"`.
|
||||
* To match notes associated with either tags, use a pipe `|` or `OR` (all caps), e.g. `--tag "inbox OR todo"`.
|
||||
* If you want to exclude notes having a particular tag, prefix it with `-` or `NOT` (all caps), e.g. `--tag "NOT done"`
|
||||
* Many tag flavors are supported: `#hashtags`, `:colon:separated:tags:` and even Bear's [`#multi-word tags#`](https://blog.bear.app/2017/11/bear-tips-how-to-create-multi-word-tags/). If you prefer to use a YAML frontmatter, list your tags with the key `tags` or `keywords`.
|
||||
|
||||
### Changed
|
||||
|
@ -442,11 +442,22 @@ func (d *NoteDAO) findRows(opts note.FinderOpts) (*sql.Rows, error) {
|
||||
break
|
||||
}
|
||||
separatorRegex := regexp.MustCompile(`(\ OR\ )|\|`)
|
||||
for _, tags := range filter {
|
||||
tags := separatorRegex.Split(tags, -1)
|
||||
for _, tagsArg := range filter {
|
||||
tags := separatorRegex.Split(tagsArg, -1)
|
||||
|
||||
negate := false
|
||||
globs := make([]string, 0)
|
||||
for _, tag := range tags {
|
||||
tag = strings.TrimSpace(tag)
|
||||
|
||||
if strings.HasPrefix(tag, "-") {
|
||||
negate = true
|
||||
tag = strings.TrimPrefix(tag, "-")
|
||||
} else if strings.HasPrefix(tag, "NOT") {
|
||||
negate = true
|
||||
tag = strings.TrimPrefix(tag, "NOT")
|
||||
}
|
||||
|
||||
tag = strings.TrimSpace(tag)
|
||||
if len(tag) == 0 {
|
||||
continue
|
||||
@ -455,13 +466,25 @@ func (d *NoteDAO) findRows(opts note.FinderOpts) (*sql.Rows, error) {
|
||||
args = append(args, tag)
|
||||
}
|
||||
|
||||
whereExprs = append(whereExprs, fmt.Sprintf(`n.id IN (
|
||||
if len(globs) == 0 {
|
||||
continue
|
||||
}
|
||||
if negate && len(globs) > 1 {
|
||||
return nil, fmt.Errorf("cannot negate a tag in a OR group: %s", tagsArg)
|
||||
}
|
||||
|
||||
expr := "n.id"
|
||||
if negate {
|
||||
expr += " NOT"
|
||||
}
|
||||
expr += fmt.Sprintf(` IN (
|
||||
SELECT note_id FROM notes_collections
|
||||
WHERE collection_id IN (SELECT id FROM collections t WHERE kind = '%s' AND (%s))
|
||||
)`,
|
||||
note.CollectionKindTag,
|
||||
strings.Join(globs, " OR "),
|
||||
))
|
||||
)
|
||||
whereExprs = append(whereExprs, expr)
|
||||
}
|
||||
|
||||
case note.ExcludePathFilter:
|
||||
|
@ -418,6 +418,9 @@ func TestNoteDAOFindTag(t *testing.T) {
|
||||
test([]string{"fiction | adventure | fantasy"}, []string{"ref/test/b.md", "f39c8.md", "log/2021-01-03.md"})
|
||||
test([]string{"fiction | history", "adventure"}, []string{"ref/test/b.md", "log/2021-01-03.md"})
|
||||
test([]string{"fiction", "unknown"}, []string{})
|
||||
test([]string{"-fiction"}, []string{"ref/test/b.md", "f39c8.md", "ref/test/a.md", "log/2021-02-04.md", "index.md", "log/2021-01-04.md"})
|
||||
test([]string{"NOT fiction"}, []string{"ref/test/b.md", "f39c8.md", "ref/test/a.md", "log/2021-02-04.md", "index.md", "log/2021-01-04.md"})
|
||||
test([]string{"NOTfiction"}, []string{"ref/test/b.md", "f39c8.md", "ref/test/a.md", "log/2021-02-04.md", "index.md", "log/2021-01-04.md"})
|
||||
}
|
||||
|
||||
func TestNoteDAOFindMatch(t *testing.T) {
|
||||
|
Loading…
Reference in New Issue
Block a user