|
import os |
|
import re |
|
from pathlib import Path |
|
from typing import Union |
|
from urllib.parse import unquote, urlparse |
|
|
|
RE_PATH_ANCHOR = r"^file://([^/]+|/[A-Z]:)" |
|
|
|
|
|
def normalized_uri(root_dir): |
|
"""Attempt to make an LSP rootUri from a ContentsManager root_dir |
|
|
|
Special care must be taken around windows paths: the canonical form of |
|
windows drives and UNC paths is lower case |
|
""" |
|
root_uri = Path(root_dir).expanduser().resolve().as_uri() |
|
root_uri = re.sub( |
|
RE_PATH_ANCHOR, lambda m: "file://{}".format(m.group(1).lower()), root_uri |
|
) |
|
return root_uri |
|
|
|
|
|
def file_uri_to_path(file_uri): |
|
"""Return a path string for give file:/// URI. |
|
|
|
Respect the different path convention on Windows. |
|
Based on https://stackoverflow.com/a/57463161/6646912, BSD 0 |
|
""" |
|
windows_path = os.name == "nt" |
|
file_uri_parsed = urlparse(file_uri) |
|
file_uri_path_unquoted = unquote(file_uri_parsed.path) |
|
if windows_path and file_uri_path_unquoted.startswith("/"): |
|
result = file_uri_path_unquoted[1:] |
|
else: |
|
result = file_uri_path_unquoted |
|
return result |
|
|
|
|
|
def is_relative(root: Union[str, Path], path: Union[str, Path]) -> bool: |
|
"""Return if path is relative to root""" |
|
try: |
|
Path(path).resolve().relative_to(Path(root).resolve()) |
|
return True |
|
except ValueError: |
|
return False |
|
|