mirror of https://github.com/perkeep/perkeep.git
attribute search
Change-Id: I9638ca9ef325076122721c601aade05ce99c0c24
This commit is contained in:
parent
bfa8efc1b9
commit
b326c2db11
|
@ -32,8 +32,9 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
tagExpr = regexp.MustCompile(`^tag:(\w+)$`)
|
||||
titleExpr = regexp.MustCompile(`^title:(\S+)$`) // TODO: proper expr parser supporting quoting
|
||||
tagExpr = regexp.MustCompile(`^tag:(.+)$`)
|
||||
titleExpr = regexp.MustCompile(`^title:(.+)$`) // TODO: proper expr parser supporting quoting
|
||||
attrExpr = regexp.MustCompile(`^attr:(\w+):(.+)$`)
|
||||
|
||||
// used for width/height ranges. 10 is max length of 32-bit
|
||||
// int (strconv.Atoi on 32-bit platforms), even though a max
|
||||
|
@ -259,6 +260,16 @@ func parseExpression(ctx *context.Context, exp string) (*SearchQuery, error) {
|
|||
and(locConstraint)
|
||||
continue
|
||||
}
|
||||
if m := attrExpr.FindStringSubmatch(word); m != nil {
|
||||
and(&Constraint{
|
||||
Permanode: &PermanodeConstraint{
|
||||
Attr: m[1],
|
||||
SkipHidden: true,
|
||||
Value: m[2],
|
||||
},
|
||||
})
|
||||
continue
|
||||
}
|
||||
log.Printf("Unknown search expression word %q", word)
|
||||
// TODO: finish. better tokenization. non-operator tokens
|
||||
// are text searches, etc.
|
||||
|
|
|
@ -103,6 +103,78 @@ var parseExprTests = []struct {
|
|||
},
|
||||
},
|
||||
|
||||
{
|
||||
name: "tag with spaces",
|
||||
in: `tag:"Foo Bar"`,
|
||||
want: &SearchQuery{
|
||||
Constraint: &Constraint{
|
||||
Logical: &LogicalConstraint{
|
||||
Op: "and",
|
||||
A: &Constraint{
|
||||
Permanode: &PermanodeConstraint{
|
||||
SkipHidden: true,
|
||||
},
|
||||
},
|
||||
B: &Constraint{
|
||||
Permanode: &PermanodeConstraint{
|
||||
Attr: "tag",
|
||||
Value: "Foo Bar",
|
||||
SkipHidden: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
name: "attribute search",
|
||||
in: "attr:foo:bar",
|
||||
want: &SearchQuery{
|
||||
Constraint: &Constraint{
|
||||
Logical: &LogicalConstraint{
|
||||
Op: "and",
|
||||
A: &Constraint{
|
||||
Permanode: &PermanodeConstraint{
|
||||
SkipHidden: true,
|
||||
},
|
||||
},
|
||||
B: &Constraint{
|
||||
Permanode: &PermanodeConstraint{
|
||||
Attr: "foo",
|
||||
Value: "bar",
|
||||
SkipHidden: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
name: "attribute search with space in value",
|
||||
in: `attr:foo:"fun bar"`,
|
||||
want: &SearchQuery{
|
||||
Constraint: &Constraint{
|
||||
Logical: &LogicalConstraint{
|
||||
Op: "and",
|
||||
A: &Constraint{
|
||||
Permanode: &PermanodeConstraint{
|
||||
SkipHidden: true,
|
||||
},
|
||||
},
|
||||
B: &Constraint{
|
||||
Permanode: &PermanodeConstraint{
|
||||
Attr: "foo",
|
||||
Value: "fun bar",
|
||||
SkipHidden: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
in: "tag:funny",
|
||||
want: &SearchQuery{
|
||||
|
@ -204,6 +276,7 @@ func TestSplitExpr(t *testing.T) {
|
|||
{"foo bar", []string{"foo", "bar"}},
|
||||
{" foo bar ", []string{"foo", "bar"}},
|
||||
{`foo:"quoted string" bar`, []string{`foo:quoted string`, "bar"}},
|
||||
{`foo:"quoted \"-containing"`, []string{`foo:quoted "-containing`}},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
got := splitExpr(tt.in)
|
||||
|
@ -225,6 +298,7 @@ func TestTokenizeExpr(t *testing.T) {
|
|||
{" -foo bar", []string{" ", "-", "foo", " ", "bar"}},
|
||||
{`-"quote"foo`, []string{"-", `"quote"`, "foo"}},
|
||||
{`foo:"quoted string" bar`, []string{"foo:", `"quoted string"`, " ", "bar"}},
|
||||
{`"quoted \"-containing"`, []string{`"quoted \"-containing"`}},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
got := tokenizeExpr(tt.in)
|
||||
|
|
Loading…
Reference in New Issue