From a0cfc1c7829befc034e100bdf9f000c88a2e395c Mon Sep 17 00:00:00 2001 From: Peter Munch-Ellingsen Date: Thu, 26 Nov 2020 11:13:43 +0100 Subject: [PATCH 1/2] Improve handling of paths as URIs --- src/nimlsp.nim | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/src/nimlsp.nim b/src/nimlsp.nim index 4fecb34..4caa2fe 100644 --- a/src/nimlsp.nim +++ b/src/nimlsp.nim @@ -24,6 +24,10 @@ const # This is used to explicitly set the default source path explicitSourcePath {.strdefine.} = getCurrentCompilerExe().parentDir.parentDir +type + UriParseError* = object of Defect + uri: string + var nimpath = explicitSourcePath discard existsOrCreateDir(storage) @@ -105,8 +109,22 @@ proc pathToUri(path: string): string = proc uriToPath(uri: string): string = ## Convert an RFC 8089 file URI to a native, platform-specific, absolute path. - let startIdx = when defined(windows): 8 else: 7 - normalizedPath(uri[startIdx..^1]) + #let startIdx = when defined(windows): 8 else: 7 + #normalizedPath(uri[startIdx..^1]) + let parsed = uri.decodeUrl.parseUri + if parsed.scheme != "file": + var e = newException(UriParseError, "Invalid scheme: " & parsed.scheme & ", only \"file\" is supported") + e.uri = uri + raise e + if parsed.hostname != "": + var e = newException(UriParseError, "Invalid hostname: " & parsed.hostname & ", only empty hostname is supported") + e.uri = uri + raise e + return normalizedPath( + when defined(windows): + parsed.path[1..^1] + else: + parsed.path) proc parseId(node: JsonNode): int = if node.kind == JString: @@ -324,7 +342,7 @@ while true: for suggestion in suggestions: if suggestion.section == ideUse or referenceRequest["context"]["includeDeclaration"].getBool: response.add create(Location, - "file://" & suggestion.filepath, + "file://" & pathToUri(suggestion.filepath), create(Range, create(Position, suggestion.line-1, suggestion.column), create(Position, suggestion.line-1, suggestion.column + suggestion.qualifiedPath[^1].len) @@ -351,9 +369,9 @@ while true: else: var textEdits = newJObject() for suggestion in suggestions: - if not textEdits.hasKey("file://" & suggestion.filepath): - textEdits["file://" & suggestion.filepath] = newJArray() - textEdits["file://" & suggestion.filepath].add create(TextEdit, + if not textEdits.hasKey("file://" & pathToUri(suggestion.filepath)): + textEdits["file://" & pathToUri(suggestion.filepath)] = newJArray() + textEdits["file://" & pathToUri(suggestion.filepath)].add create(TextEdit, create(Range, create(Position, suggestion.line-1, suggestion.column), create(Position, suggestion.line-1, suggestion.column + suggestion.qualifiedPath[^1].len) @@ -540,6 +558,9 @@ while true: else: debugEcho "Got unknown notification message" continue + except UriParseError as e: + debugEcho "Got exception parsing URI: ", e.msg + continue except IOError: break except CatchableError as e: From 46cb1cf0382b68b055baf7befc875383595285af Mon Sep 17 00:00:00 2001 From: Peter Munch-Ellingsen Date: Thu, 26 Nov 2020 14:58:07 +0100 Subject: [PATCH 2/2] Better fix --- src/nimlsp.nim | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/nimlsp.nim b/src/nimlsp.nim index 4caa2fe..7d1f7f7 100644 --- a/src/nimlsp.nim +++ b/src/nimlsp.nim @@ -111,7 +111,7 @@ proc uriToPath(uri: string): string = ## Convert an RFC 8089 file URI to a native, platform-specific, absolute path. #let startIdx = when defined(windows): 8 else: 7 #normalizedPath(uri[startIdx..^1]) - let parsed = uri.decodeUrl.parseUri + let parsed = uri.parseUri if parsed.scheme != "file": var e = newException(UriParseError, "Invalid scheme: " & parsed.scheme & ", only \"file\" is supported") e.uri = uri @@ -124,7 +124,7 @@ proc uriToPath(uri: string): string = when defined(windows): parsed.path[1..^1] else: - parsed.path) + parsed.path).decodeUrl proc parseId(node: JsonNode): int = if node.kind == JString: @@ -561,7 +561,8 @@ while true: except UriParseError as e: debugEcho "Got exception parsing URI: ", e.msg continue - except IOError: + except IOError as e: + debugEcho "Got IOError: ", e.msg break except CatchableError as e: debugEcho "Got exception: ", e.msg