turbo-editors/turbo-corepublic Fork 0
main
Commits
Clone
git clone https://git.rickub.com/turbo-editors/turbo-core.git
git clone ssh://git@rickub.com/turbo-editors/turbo-core.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

uri.go · 79 lines · 2.8 KBGo Blame HistoryRaw
🛟 Updated. 28d5985 k33g 18h ago1package lsp
2
3import (
4 "net/url"
5 "path/filepath"
6 "strings"
7)
8
9// PathToURI turns a file path into the file:// URI the protocol names
10// documents by.
11//
📦 Turbo Core — canonical paths: symbolic links resolved in URIs and document keys (moon-lsp on macOS) b91316e k33g 9h ago12// The path is made canonical first — absolute, with symbolic links resolved —
13// since a language server has no idea what the editor's working directory is,
14// and some resolve links themselves: see CanonicalPath.
🛟 Updated. 28d5985 k33g 18h ago15//
16// lsp.PathToURI("main.go") // file:///home/you/project/main.go
17func PathToURI(path string) string {
📦 Turbo Core — canonical paths: symbolic links resolved in URIs and document keys (moon-lsp on macOS) b91316e k33g 9h ago18 absolute := filepath.ToSlash(CanonicalPath(path))
🛟 Updated. 28d5985 k33g 18h ago19
20 if !strings.HasPrefix(absolute, "/") {
21 // A Windows path such as C:/x becomes /C:/x, which is what the URI
22 // form of a drive letter looks like.
23 absolute = "/" + absolute
24 }
25
26 uri := url.URL{Scheme: "file", Path: absolute}
27 return uri.String()
28}
29
📦 Turbo Core — canonical paths: symbolic links resolved in URIs and document keys (moon-lsp on macOS) b91316e k33g 9h ago30// CanonicalPath is the one spelling of a file this package names it by:
31// absolute, with every symbolic link resolved.
32//
33// Resolving the links is not tidiness. moon-lsp works a package's files out
34// from disk and canonicalises what it finds, so a document announced under
35// another spelling of the same path is, to it, a file that belongs to no
36// package: it answers no completion about the buffer's types, and it publishes
37// the file's diagnostics under the spelling it knows — which the editor then
38// cannot match to any open buffer. On macOS every temporary directory is such
39// a spelling: /var is a link to /private/var, and the Turbo MoonBit suite,
40// green on Linux, failed both of those ways the first time it ran on a Mac.
41//
42// A file that is not on disk yet — a buffer being saved under a new name — has
43// nothing to resolve, so its deepest existing directory is resolved instead and
44// the rest of the path put back on. A path that cannot be made absolute is
45// returned as it is, which degrades to the behaviour there was before.
46func CanonicalPath(path string) string {
47 absolute, err := filepath.Abs(path)
48 if err != nil {
49 return path
50 }
51 if resolved, err := filepath.EvalSymlinks(absolute); err == nil {
52 return resolved
53 }
54
55 dir, rest := filepath.Dir(absolute), filepath.Base(absolute)
56 for dir != filepath.Dir(dir) {
57 if resolved, err := filepath.EvalSymlinks(dir); err == nil {
58 return filepath.Join(resolved, rest)
59 }
60 dir, rest = filepath.Dir(dir), filepath.Join(filepath.Base(dir), rest)
61 }
62 return absolute
63}
64
🛟 Updated. 28d5985 k33g 18h ago65// URIToPath turns a file:// URI back into a path. Anything that is not a file
66// URI comes back unchanged, since there is nothing better to do with it.
67func URIToPath(uri string) string {
68 parsed, err := url.Parse(uri)
69 if err != nil || parsed.Scheme != "file" {
70 return uri
71 }
72
73 path := parsed.Path
74 // Undo the leading slash added in front of a Windows drive letter.
75 if len(path) > 2 && path[0] == '/' && path[2] == ':' {
76 path = path[1:]
77 }
78 return filepath.FromSlash(path)
79}