Find notes with a partial href

pull/71/head
Mickaël Menu 3 years ago
parent 41c451b2ca
commit f0e4dc1f80
No known key found for this signature in database
GPG Key ID: 53D73664CD359895

@ -603,10 +603,19 @@ func (s *Server) notebookOf(doc *document) (*core.Notebook, error) {
}
// noteForLink returns the LSP documentUri for the note targeted by the given link.
//
// Match by order of precedence:
// 1. Prefix of relative path
// 2. Find any occurrence of the href in a note path (substring)
// 3. Match the href as a term in the note titles
func (s *Server) noteForLink(link documentLink, doc *document, notebook *core.Notebook) (*Note, error) {
note, err := s.noteForHref(link.Href, doc, notebook)
if note == nil && err == nil && link.IsWikiLink {
note, err = s.noteMatching(link.Href, notebook)
// Try to find a partial href match.
note, err = notebook.FindByHref(link.Href, true)
if note == nil && err == nil {
note, err = s.noteMatchingTitle(link.Href, notebook)
}
}
if note == nil || err != nil {
return nil, err
@ -627,26 +636,20 @@ func (s *Server) noteForHref(href string, doc *document, notebook *core.Notebook
if err != nil {
return nil, errors.Wrapf(err, "failed to resolve href: %s", href)
}
note, err := notebook.FindByHref(path)
note, err := notebook.FindByHref(path, false)
if err != nil {
s.logger.Printf("findByHref(%s): %s", href, err.Error())
}
return note, err
}
// noteMatching returns the LSP documentUri for the note matching the given search terms.
func (s *Server) noteMatching(terms string, notebook *core.Notebook) (*core.MinimalNote, error) {
// noteMatchingTitle returns the LSP documentUri for the note matching the given search terms.
func (s *Server) noteMatchingTitle(terms string, notebook *core.Notebook) (*core.MinimalNote, error) {
if terms == "" {
return nil, nil
}
note, err := notebook.FindMatching("path:(" + terms + ")")
if err != nil {
s.logger.Printf("findMatching(path: %s): %s", terms, err.Error())
}
if note == nil {
note, err = notebook.FindMatching("title:(" + terms + ")")
}
note, err := notebook.FindMatching("title:(" + terms + ")")
if err != nil {
s.logger.Printf("findMatching(title: %s): %s", terms, err.Error())
}

@ -598,7 +598,10 @@ func (d *NoteDAO) findRows(opts core.NoteFindOpts, minimal bool) (*sql.Rows, err
regexes := make([]string, 0)
for _, path := range opts.IncludePaths {
regexes = append(regexes, "n.path REGEXP ?")
args = append(args, pathRegex(path))
if !opts.EnablePathRegexes {
path = pathRegex(path)
}
args = append(args, path)
}
whereExprs = append(whereExprs, strings.Join(regexes, " OR "))
}
@ -607,7 +610,10 @@ func (d *NoteDAO) findRows(opts core.NoteFindOpts, minimal bool) (*sql.Rows, err
regexes := make([]string, 0)
for _, path := range opts.ExcludePaths {
regexes = append(regexes, "n.path NOT REGEXP ?")
args = append(args, pathRegex(path))
if !opts.EnablePathRegexes {
path = pathRegex(path)
}
args = append(args, path)
}
whereExprs = append(whereExprs, strings.Join(regexes, " AND "))
}

@ -19,6 +19,8 @@ type NoteFindOpts struct {
IncludePaths []string
// Filter excluding notes at the given paths.
ExcludePaths []string
// Indicates whether IncludePaths and ExcludePaths are using regexes.
EnablePathRegexes bool
// Filter excluding notes with the given IDs.
ExcludeIDs []NoteID
// Filter by tags found in the notes.

@ -9,6 +9,7 @@ import (
"github.com/mickael-menu/zk/internal/util"
"github.com/mickael-menu/zk/internal/util/errors"
"github.com/mickael-menu/zk/internal/util/icu"
"github.com/mickael-menu/zk/internal/util/opt"
"github.com/mickael-menu/zk/internal/util/paths"
"github.com/schollz/progressbar/v3"
@ -174,14 +175,20 @@ func (n *Notebook) FindMinimalNotes(opts NoteFindOpts) ([]MinimalNote, error) {
}
// FindByHref retrieves the first note matching the given link href.
func (n *Notebook) FindByHref(href string) (*MinimalNote, error) {
// If allowPartialMatch is true, the href can match any unique sub portion of a note path.
func (n *Notebook) FindByHref(href string, allowPartialMatch bool) (*MinimalNote, error) {
// Remove any anchor at the end of the HREF, since it's most likely
// matching a sub-section in the note.
href = strings.SplitN(href, "#", 2)[0]
if allowPartialMatch {
href = "(.*)" + icu.EscapePattern(href) + "(.*)"
}
notes, err := n.FindMinimalNotes(NoteFindOpts{
IncludePaths: []string{href},
Limit: 1,
IncludePaths: []string{href},
EnablePathRegexes: allowPartialMatch,
Limit: 1,
// To find the best match possible, we sort by path length.
// See https://github.com/mickael-menu/zk/issues/23
Sorters: []NoteSorter{{Field: NoteSortPathLength, Ascending: true}},

Loading…
Cancel
Save