From 4582265de0c0472755880652dc7b390b342cf3e0 Mon Sep 17 00:00:00 2001 From: JP Appel Date: Mon, 30 Jun 2025 19:23:20 -0400 Subject: Add filepath to searchable categories --- cmd/query.go | 5 ++++- pkg/query/compiler.go | 2 ++ pkg/query/lexer.go | 13 +++++++++---- pkg/query/parser.go | 7 ++++++- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/cmd/query.go b/cmd/query.go index 40c9e58..32a89e1 100644 --- a/cmd/query.go +++ b/cmd/query.go @@ -18,7 +18,7 @@ type QueryFlags struct { func setupQueryFlags(args []string, fs *flag.FlagSet, flags *QueryFlags) { // NOTE: providing `-outFormat` before `-outCustomFormat` might ignore user specified format - fs.Func("outFormat", "output `format` for queries (default, json, custom)", + fs.Func("outFormat", "output `format` for queries (default, json, pathonly, custom)", func(arg string) error { switch arg { case "default": @@ -27,6 +27,9 @@ func setupQueryFlags(args []string, fs *flag.FlagSet, flags *QueryFlags) { case "json": flags.Outputer = query.JsonOutput{} return nil + case "pathonly": + flags.Outputer, _ = query.NewCustomOutput("%p", dateFormat) + return nil case "custom": var err error flags.Outputer, err = query.NewCustomOutput(flags.CustomFormat, dateFormat) diff --git a/pkg/query/compiler.go b/pkg/query/compiler.go index c2f6701..9edfeb5 100644 --- a/pkg/query/compiler.go +++ b/pkg/query/compiler.go @@ -41,6 +41,8 @@ func (s Statements) buildCompile(b *strings.Builder, delim string) ([]any, error } var catStr string switch cat { + case CAT_PATH: + catStr = "path " case CAT_AUTHOR: catStr = "author " case CAT_DATE: diff --git a/pkg/query/lexer.go b/pkg/query/lexer.go index 9e64b82..a421fbc 100644 --- a/pkg/query/lexer.go +++ b/pkg/query/lexer.go @@ -33,6 +33,7 @@ const ( TOK_OP_PIPE // external pipe TOK_OP_ARG // external arg // categories + TOK_CAT_PATH TOK_CAT_TITLE TOK_CAT_AUTHOR TOK_CAT_DATE @@ -82,6 +83,8 @@ func (tokType queryTokenType) String() string { return "Pipe External Command" case TOK_OP_ARG: return "Argument External Command" + case TOK_CAT_PATH: + return "Filepath Category" case TOK_CAT_TITLE: return "Title Category" case TOK_CAT_AUTHOR: @@ -126,7 +129,7 @@ func (t queryTokenType) isClause() bool { } func (t queryTokenType) isCategory() bool { - return t.Any(TOK_CAT_TITLE, TOK_CAT_AUTHOR, TOK_CAT_DATE, TOK_CAT_FILETIME, TOK_CAT_TAGS, TOK_CAT_LINKS, TOK_CAT_META) + return t.Any(TOK_CAT_PATH, TOK_CAT_TITLE, TOK_CAT_AUTHOR, TOK_CAT_DATE, TOK_CAT_FILETIME, TOK_CAT_TAGS, TOK_CAT_LINKS, TOK_CAT_META) } func (t queryTokenType) isOperation() bool { return t.Any(TOK_OP_EQ, TOK_OP_AP, TOK_OP_NE, TOK_OP_LT, TOK_OP_LE, TOK_OP_GE, TOK_OP_GT, TOK_OP_PIPE, TOK_OP_ARG) @@ -248,6 +251,8 @@ func tokenizeOperation(s string) Token { func tokenizeCategory(s string) Token { t := Token{Value: s} switch s { + case "p", "path": + t.Type = TOK_CAT_PATH case "T", "title": t.Type = TOK_CAT_TITLE case "a", "author": @@ -276,7 +281,7 @@ func tokenizeValue(s string, catType queryTokenType) Token { switch catType { case TOK_CAT_DATE, TOK_CAT_FILETIME: t.Type = TOK_VAL_DATETIME - case TOK_CAT_TITLE, TOK_CAT_AUTHOR, TOK_CAT_TAGS, TOK_CAT_LINKS, TOK_CAT_META: + case TOK_CAT_PATH, TOK_CAT_TITLE, TOK_CAT_AUTHOR, TOK_CAT_TAGS, TOK_CAT_LINKS, TOK_CAT_META: t.Type = TOK_VAL_STR } return t @@ -307,7 +312,7 @@ func TokensStringify(tokens []Token) string { case TOK_CLAUSE_AND: b.WriteString("and\n") indentLvl += 1 - case TOK_CAT_TITLE, TOK_CAT_AUTHOR, TOK_CAT_DATE, TOK_CAT_FILETIME, TOK_CAT_TAGS, TOK_CAT_LINKS, TOK_CAT_META, TOK_OP_NEG: + case TOK_CAT_PATH, TOK_CAT_TITLE, TOK_CAT_AUTHOR, TOK_CAT_DATE, TOK_CAT_FILETIME, TOK_CAT_TAGS, TOK_CAT_LINKS, TOK_CAT_META, TOK_OP_NEG: if i == 0 || tokens[i-1].Type != TOK_OP_NEG { writeIndent(&b, indentLvl) } @@ -325,7 +330,7 @@ func TokensStringify(tokens []Token) string { func init() { negPattern := `(?-?)` - categoryPattern := `(?T|a(?:uthor)?|d(?:ate)?|f(?:iletime)?|t(?:ags|itle)?|l(?:inks)?|m(?:eta)?)` + categoryPattern := `(?T|p(?:ath)?|a(?:uthor)?|d(?:ate)?|f(?:iletime)?|t(?:ags|itle)?|l(?:inks)?|m(?:eta)?)` opPattern := `(?!=|!+|<=|>=|=|:|~|<|>|!)` valPattern := `(?".*?"|\S*[^\s\)])` statementPattern := `(?` + negPattern + categoryPattern + opPattern + valPattern + `)` diff --git a/pkg/query/parser.go b/pkg/query/parser.go index 73738fb..e22b4c3 100644 --- a/pkg/query/parser.go +++ b/pkg/query/parser.go @@ -15,6 +15,7 @@ type catType int const ( CAT_UNKNOWN catType = iota + CAT_PATH CAT_TITLE CAT_AUTHOR CAT_DATE @@ -144,6 +145,8 @@ func (t catType) IsOrdered() bool { func (t catType) String() string { switch t { + case CAT_PATH: + return "path" case CAT_TITLE: return "title" case CAT_AUTHOR: @@ -199,6 +202,8 @@ func (t opType) String() string { // convert a token to a category func tokToCat(t queryTokenType) catType { switch t { + case TOK_CAT_PATH: + return CAT_PATH case TOK_CAT_TITLE: return CAT_TITLE case TOK_CAT_AUTHOR: @@ -497,7 +502,7 @@ func Parse(tokens []Token) (*Clause, error) { stmt := Statement{Negated: true} clause.Statements = append(clause.Statements, stmt) - case TOK_CAT_TITLE, TOK_CAT_AUTHOR, TOK_CAT_DATE, TOK_CAT_FILETIME, TOK_CAT_TAGS, TOK_CAT_LINKS, TOK_CAT_META: + case TOK_CAT_PATH, TOK_CAT_TITLE, TOK_CAT_AUTHOR, TOK_CAT_DATE, TOK_CAT_FILETIME, TOK_CAT_TAGS, TOK_CAT_LINKS, TOK_CAT_META: if !prevToken.Type.Any(TOK_CLAUSE_OR, TOK_CLAUSE_AND, TOK_VAL_STR, TOK_VAL_DATETIME, TOK_OP_NEG, TOK_CLAUSE_END) { return nil, &TokenError{ got: token, -- cgit v1.2.3