Skip to content

Commit

Permalink
Use RFC 3986-compliant URIs for file paths (#226)
Browse files Browse the repository at this point in the history
Fixes #218

The Java URIs uses a different standard (RFC 2396) for encoding than the
library vscode-uri used by Cody agent (RFC 3986).
Due to the fact that I was unable to find a reasonable library, this
patch merely imitates the encoding and normalization of such addresses.

Additional change: Remove unused CodyAgentDocuments.

## Test Plan

1. Verify basic features on Windows
2. Verify basic features on Linux
  • Loading branch information
exigow authored Dec 22, 2023
1 parent 014311d commit 16d2c40
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 70 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public void focusGained(@NotNull Editor editor) {
if (client.server == null) {
return;
}
client.server.textDocumentDidFocus(new TextDocument(file.getPath()));
client.server.textDocumentDidFocus(TextDocument.fromPath(file.getPath()));

if (client.codebase == null) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public void fileOpened(@NotNull FileEditorManager source, @NotNull VirtualFile f
}

server.textDocumentDidOpen(
new TextDocument(file.getPath(), document.getText()));
TextDocument.fromPath(file.getPath(), document.getText()));

CodyAgentClient client = CodyAgent.getClient(source.getProject());
if (client.codebase == null) {
Expand All @@ -63,6 +63,6 @@ public void fileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile f
if (server == null) {
return;
}
server.textDocumentDidClose(new TextDocument(file.getPath()));
server.textDocumentDidClose(TextDocument.fromPath(file.getPath()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ public class CodyAgentClient {

private static final Logger logger = Logger.getInstance(CodyAgentClient.class);
@Nullable public CodyAgentServer server;
@Nullable public CodyAgentDocuments documents;
@Nullable public CodyAgentCodebase codebase;
// Callback that is invoked when the agent sends a "chat/updateMessageInProgress" notification.
@Nullable public Consumer<ChatMessage> onChatUpdateMessageInProgress;
Expand Down
49 changes: 0 additions & 49 deletions src/main/java/com/sourcegraph/cody/agent/CodyAgentDocuments.java

This file was deleted.

1 change: 0 additions & 1 deletion src/main/kotlin/com/sourcegraph/cody/agent/CodyAgent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,6 @@ class CodyAgent(private val project: Project) : Disposable {
.create()
val server = launcher.remoteProxy
client.server = server
client.documents = CodyAgentDocuments(server)
client.codebase = CodyAgentCodebase(server, project)
listeningToJsonRpc = launcher.startListening()
}
Expand Down
32 changes: 17 additions & 15 deletions src/main/kotlin/com/sourcegraph/cody/agent/protocol/TextDocument.kt
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
package com.sourcegraph.cody.agent.protocol

import java.net.URI
import com.sourcegraph.cody.agent.protocol.util.Rfc3986UriEncoder
import java.nio.file.Paths

data class TextDocument
// JvmOverloads needed until CodyAgentFocusListener
// and CodyFileEditorListener are converted to Kotlin.
@JvmOverloads
constructor(
var uri: URI,
var content: String? = null,
var selection: Range? = null,
class TextDocument
private constructor(
var uri: String,
var content: String?,
var selection: Range?,
) {
@JvmOverloads
constructor(
filePath: String,
content: String? = null,
selection: Range? = null,
) : this(Paths.get(filePath).toUri(), content, selection)

companion object {

@JvmStatic
@JvmOverloads
fun fromPath(path: String, content: String? = null, selection: Range? = null): TextDocument {
val uri = Paths.get(path).toUri().toString()
val rfc3986Uri = Rfc3986UriEncoder.encode(uri)
return TextDocument(rfc3986Uri, content, selection)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.sourcegraph.cody.agent.protocol.util

object Rfc3986UriEncoder {

// todo solve this with library
fun encode(uri: String): String {
val isWindowsPath = uri.matches("^file:///[A-Za-z]:.*".toRegex())
if (isWindowsPath) {
val found = "file:///([A-Za-z]):".toRegex().find(uri)!!
val partition = found.groups[1]!!.value
return uri.replace("file:///$partition:", "file:///${partition.lowercase()}%3A")
}
return uri
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ class CodyEditorFactoryListener : EditorFactoryListener {
return
}
val file = FileDocumentManager.getInstance().getFile(editor.document) ?: return
val document = TextDocument(file.path, editor.document.text, getSelection(editor))
val document = TextDocument.fromPath(file.path, editor.document.text, getSelection(editor))
client.server!!.textDocumentDidChange(document)
if (client.codebase == null || skipCodebaseOnFileOpened) {
return
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.sourcegraph.cody.agent.protocol.util

import junit.framework.TestCase

class Rfc3986UriEncoderTest : TestCase() {

fun `test encode Windows path`() {
val fixedUri = Rfc3986UriEncoder.encode("file:///C:/Users/user/Test.java")
assertEquals("file:///c%3A/Users/user/Test.java", fixedUri)
}

fun `test encode Windows path with lowercase partition`() {
val fixedUri = Rfc3986UriEncoder.encode("file:///c:/Users/user/Test.java")
assertEquals("file:///c%3A/Users/user/Test.java", fixedUri)
}

fun `test encode Linux path`() {
val uri = Rfc3986UriEncoder.encode("file:///home/user/Test.java")
assertEquals("file:///home/user/Test.java", uri)
}
}

0 comments on commit 16d2c40

Please sign in to comment.