Skip to content

Commit

Permalink
Refactor links
Browse files Browse the repository at this point in the history
  • Loading branch information
mickael-menu committed Apr 3, 2021
1 parent 5ef825b commit ce41efd
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 44 deletions.
44 changes: 9 additions & 35 deletions adapter/lsp/document.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
package lsp

import (
"path/filepath"
"regexp"
"strings"

"github.com/mickael-menu/zk/core/note"
strutil "github.com/mickael-menu/zk/util/strings"
protocol "github.com/tliron/glsp/protocol_3_16"
"github.com/tliron/kutil/logging"
)
Expand Down Expand Up @@ -92,8 +89,8 @@ var markdownLinkRegex = regexp.MustCompile(`\[([^\]]+?[^\\])\]\((.+?[^\\])\)`)

// DocumentLinkAt returns the internal or external link found in the document
// at the given position.
func (d *document) DocumentLinkAt(pos protocol.Position, basePath string, finder note.Finder) (*protocol.DocumentLink, error) {
links, err := d.DocumentLinks(basePath, finder)
func (d *document) DocumentLinkAt(pos protocol.Position) (*documentLink, error) {
links, err := d.DocumentLinks()
if err != nil {
return nil, err
}
Expand All @@ -109,19 +106,18 @@ func (d *document) DocumentLinkAt(pos protocol.Position, basePath string, finder

// DocumentLinks returns all the internal and external links found in the
// document.
func (d *document) DocumentLinks(basePath string, finder note.Finder) ([]protocol.DocumentLink, error) {
links := []protocol.DocumentLink{}
func (d *document) DocumentLinks() ([]documentLink, error) {
links := []documentLink{}

lines := d.GetLines()
for lineIndex, line := range lines {

matches := []linkMatch{}
appendMatch := func(href string, start, end int) {
appendLink := func(href string, start, end int) {
if href == "" {
return
}

matches = append(matches, linkMatch{
links = append(links, documentLink{
Href: href,
Range: protocol.Range{
Start: protocol.Position{
Expand All @@ -138,41 +134,19 @@ func (d *document) DocumentLinks(basePath string, finder note.Finder) ([]protoco

for _, match := range markdownLinkRegex.FindAllStringSubmatchIndex(line, -1) {
href := line[match[4]:match[5]]
appendMatch(href, match[0], match[1])
appendLink(href, match[0], match[1])
}

for _, match := range wikiLinkRegex.FindAllStringSubmatchIndex(line, -1) {
href := line[match[2]:match[3]]
appendMatch(href, match[0], match[1])
}

for _, match := range matches {
link := protocol.DocumentLink{
Range: match.Range,
}

if strutil.IsURL(match.Href) {
link.Target = &match.Href
} else {
note, err := finder.FindByHref(match.Href)
if err != nil {
d.Log.Errorf("findByHref(%s): %s", match.Href, err.Error())
}
if note == nil {
continue
}
link.Target = stringPtr("file://" + filepath.Join(basePath, note.Path))
link.Tooltip = &note.Title
}

links = append(links, link)
appendLink(href, match[0], match[1])
}
}

return links, nil
}

type linkMatch struct {
type documentLink struct {
Href string
Range protocol.Range
}
57 changes: 48 additions & 9 deletions adapter/lsp/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,13 +205,30 @@ func NewServer(opts ServerOpts) *Server {
return nil, err
}

var links []protocol.DocumentLink
var documentLinks []protocol.DocumentLink
err = db.WithTransaction(func(tx sqlite.Transaction) error {
finder := sqlite.NewNoteDAO(tx, server.container.Logger)
links, err = doc.DocumentLinks(zk.Path, finder)
return err
links, err := doc.DocumentLinks()
if err != nil {
return err
}

for _, link := range links {
target, err := server.targetForHref(link.Href, zk.Path, finder)
if target == "" || err != nil {
continue
}

documentLinks = append(documentLinks, protocol.DocumentLink{
Range: link.Range,
Target: &target,
})
}

return nil
})
return links, err

return documentLinks, err
}

handler.TextDocumentDefinition = func(context *glsp.Context, params *protocol.DefinitionParams) (interface{}, error) {
Expand All @@ -230,31 +247,53 @@ func NewServer(opts ServerOpts) *Server {
return nil, err
}

var link *protocol.DocumentLink
var link *documentLink
var target string
err = db.WithTransaction(func(tx sqlite.Transaction) error {
finder := sqlite.NewNoteDAO(tx, server.container.Logger)
link, err = doc.DocumentLinkAt(params.Position, zk.Path, finder)
link, err = doc.DocumentLinkAt(params.Position)
if link == nil || err != nil {
return err
}
target, err = server.targetForHref(link.Href, zk.Path, finder)
return err
})
if link == nil || err != nil {
if link == nil || target == "" || err != nil {
return nil, err
}

if isTrue(clientCapabilities.TextDocument.Definition.LinkSupport) {
return protocol.LocationLink{
OriginSelectionRange: &link.Range,
TargetURI: *link.Target,
TargetURI: target,
}, nil
} else {
return protocol.Location{
URI: *link.Target,
URI: target,
}, nil
}
}

return server
}

// targetForHref returns the LSP documentUri for the note at the given HREF.
func (s *Server) targetForHref(href string, basePath string, finder note.Finder) (string, error) {
if strutil.IsURL(href) {
return href, nil
} else {
note, err := finder.FindByHref(href)
if err != nil {
s.server.Log.Errorf("findByHref(%s): %s", href, err.Error())
return "", err
}
if note == nil {
return "", nil
}
return "file://" + filepath.Join(basePath, note.Path), nil
}
}

// Run starts the Language Server in stdio mode.
func (s *Server) Run() error {
return errors.Wrap(s.server.RunStdio(), "lsp")
Expand Down

0 comments on commit ce41efd

Please sign in to comment.