Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a text field for entering multiple remote repositories at once #1308

Merged
merged 48 commits into from
Apr 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
3602d38
WIP
dominiccooney Mar 27, 2024
adf458b
Autocomplete roughly working.
dominiccooney Mar 27, 2024
2094114
Remove the legacy Thinger.
dominiccooney Mar 28, 2024
afad06f
Edit button on the toolbar, pop up a textbox.
dominiccooney Mar 29, 2024
918671f
Toolbar is vertical although the toolbar button width is really narro…
dominiccooney Mar 29, 2024
58dff43
Insert autocompletes over the whole line.
dominiccooney Mar 29, 2024
124f950
Add callbacks for remote repo state updates.
dominiccooney Mar 29, 2024
08dfb7c
Multiline, etc.
dominiccooney Apr 3, 2024
9277a47
Show icons next to repos
dominiccooney Apr 3, 2024
c0493d2
Add a language, lexer and parser for "repo lists" to enable annotatin…
dominiccooney Apr 5, 2024
4e1a4e0
Annotations appearing (once indexing is finished) and stub completion…
dominiccooney Apr 5, 2024
b333541
Add icons for all code hosts
dominiccooney Apr 6, 2024
f38f4cc
Suppress autocomplete in repo text box. Add tool tip placeholder text.
dominiccooney Apr 7, 2024
c5b27e2
Make completion contributor BASIC so it shows completions with ctrl-s…
dominiccooney Apr 8, 2024
78d769f
Use completion contributor and Psi.
dominiccooney Apr 8, 2024
facd5ec
WIP scree for hanging
dominiccooney Apr 9, 2024
2ee4b41
Overwrought cancellation burns two threads.
dominiccooney Apr 9, 2024
1ef9e3c
Simpler threading with `runBlockingCancelable`.
dominiccooney Apr 9, 2024
7603ba2
Remove the text-based completions.
dominiccooney Apr 9, 2024
3056140
Some actual annotations, but autocompletes pile up.
dominiccooney Apr 9, 2024
08663fa
Clean up unused text highlighting.
dominiccooney Apr 9, 2024
29d6494
More cancellation checks.
dominiccooney Apr 9, 2024
5237d1c
Highlight unknown repositories.
dominiccooney Apr 9, 2024
90a5a27
Cheesy accept callback.
dominiccooney Apr 9, 2024
8b04355
Specialize the chat panel for consumer/enterprise
dominiccooney Apr 9, 2024
05d2e5e
Add an empty tree view.
dominiccooney Apr 9, 2024
1df27c5
Encapsulate the mutable isEnhancedContextEnabled to the consumer cont…
dominiccooney Apr 9, 2024
9ace485
Add the help button to the enterprise toolbar.
dominiccooney Apr 9, 2024
f2e477f
Fun and games with treeviews and checkboxes.
dominiccooney Apr 10, 2024
fc7942f
Push the result back to the model. Problem with collapsing.
dominiccooney Apr 10, 2024
312cc33
Path remains expanded/collapsed when editing repos.
dominiccooney Apr 10, 2024
f8b7a6e
No horizontal scrollbars.
dominiccooney Apr 10, 2024
b9f663d
Wire up enhanced context enabled button.
dominiccooney Apr 10, 2024
fcc947b
Move insights into a separate file.
dominiccooney Apr 11, 2024
d943af0
Make annotator and completion contributor DumbAware.
dominiccooney Apr 11, 2024
aa01048
Display root element checked/unchecked reliably.
dominiccooney Apr 11, 2024
0a6ae09
Move UI strings to CodyBundle.
dominiccooney Apr 11, 2024
eb03c4b
Move complex tree node labels into CodyBundle.
dominiccooney Apr 11, 2024
9cda9c1
Notification bubble when fetching fails.
dominiccooney Apr 11, 2024
d7aba39
Update repo state as checkboxes are checked, unchecked.
dominiccooney Apr 11, 2024
ac675c3
Make the minimum size include a couple of toolbar buttons.
dominiccooney Apr 15, 2024
1a93290
Minimize imports. Add some RequiresEdt annotations.
dominiccooney Apr 15, 2024
abaa153
Spotless.
dominiccooney Apr 15, 2024
b2839c4
Fix syntax for setting up other platform versions for :runIDE
dominiccooney Apr 15, 2024
fac6d69
Clarify tokenization is breaking on whitespace.
dominiccooney Apr 15, 2024
a95f6d5
Rename confusing nextChar -> peekChar
dominiccooney Apr 15, 2024
27c0ff0
Some thread assertions, set the initial cursor position.
dominiccooney Apr 15, 2024
735346f
spotless
dominiccooney Apr 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ Few tips and tricks regarding versioning of the tooling:
- Use `node` version `18` (newer versions causes hard to diagnose errors with `ERR_INVALID_THIS`).
- If you changed `pnpm` or `node` version after running gradle you need to kill gradle daemon with `./gradlew --stop`.
Otherwise you won't see effects of your changes.
- Running `:runIde PplatformRuntimeVersion=X.Y` for the first time might fail due to missing IntelliJ installation. You
can fix it by running `:runIde PplatformVersion=X.Y` once - even if compilation fails it fixes your caches.
- Running `./gradlew -PplatformRuntimeVersion=X.Y :runIde` for the first time might fail due to missing IntelliJ installation. You
can fix it by running `./gradlew -PplatformVersion=X.Y :runIde` once - even if compilation fails it fixes your caches.

## Using Nightly channel releases

Expand Down
4 changes: 4 additions & 0 deletions src/main/java/com/sourcegraph/Icons.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,8 @@ public interface Icons {
Icon SourcegraphLogo = IconLoader.getIcon("/icons/sourcegraphLogo.svg", Icons.class);
Icon CodyLogo = IconLoader.getIcon("/icons/codyLogo.svg", Icons.class);
Icon GearPlain = IconLoader.getIcon("/icons/gearPlain.svg", Icons.class);
Icon RepoHostBitbucket = IconLoader.getIcon("/icons/repo-host-bitbucket.svg", Icons.class);
Icon RepoHostGeneric = IconLoader.getIcon("/icons/repo-host-generic.svg", Icons.class);
Icon RepoHostGitHub = IconLoader.getIcon("/icons/repo-host-github.svg", Icons.class);
Icon RepoHostGitlab = IconLoader.getIcon("/icons/repo-host-gitlab.svg", Icons.class);
}
23 changes: 19 additions & 4 deletions src/main/java/com/sourcegraph/cody/agent/CodyAgentClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@

import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.sourcegraph.cody.agent.protocol.DebugMessage;
import com.sourcegraph.cody.agent.protocol.EditTask;
import com.sourcegraph.cody.agent.protocol.TextDocumentEditParams;
import com.sourcegraph.cody.agent.protocol.WorkspaceEditParams;
import com.sourcegraph.cody.agent.protocol.*;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
import org.eclipse.lsp4j.jsonrpc.services.JsonNotification;
Expand Down Expand Up @@ -54,6 +51,24 @@ public CompletableFuture<Void> editTaskDidDelete(EditTask params) {
return acceptOnEventThread("editTask/didDelete", onEditTaskDidDelete, params);
}

@Nullable Consumer<Void> onRemoteRepoDidChange;

@JsonNotification("remoteRepo/didChange")
public void remoteRepoDidChange() {
if (onRemoteRepoDidChange != null) {
onRemoteRepoDidChange.accept(null);
}
}

@Nullable Consumer<RemoteRepoFetchState> onRemoteRepoDidChangeState;

@JsonNotification("remoteRepo/didChangeState")
public void remoteRepoDidChangeState(RemoteRepoFetchState state) {
if (onRemoteRepoDidChangeState != null) {
onRemoteRepoDidChangeState.accept(state);
}
}

@JsonRequest("textDocument/edit")
public CompletableFuture<Void> textDocumentEdit(TextDocumentEditParams params) {
return acceptOnEventThread("textDocument/edit", onTextDocumentEdit, params);
Expand Down
35 changes: 12 additions & 23 deletions src/main/kotlin/com/sourcegraph/cody/agent/CodyAgentServer.kt
Original file line number Diff line number Diff line change
@@ -1,28 +1,6 @@
package com.sourcegraph.cody.agent

import com.sourcegraph.cody.agent.protocol.AttributionSearchParams
import com.sourcegraph.cody.agent.protocol.AttributionSearchResponse
import com.sourcegraph.cody.agent.protocol.AutocompleteParams
import com.sourcegraph.cody.agent.protocol.AutocompleteResult
import com.sourcegraph.cody.agent.protocol.ChatHistoryResponse
import com.sourcegraph.cody.agent.protocol.ChatModelsParams
import com.sourcegraph.cody.agent.protocol.ChatModelsResponse
import com.sourcegraph.cody.agent.protocol.ChatRestoreParams
import com.sourcegraph.cody.agent.protocol.ChatSubmitMessageParams
import com.sourcegraph.cody.agent.protocol.ClientInfo
import com.sourcegraph.cody.agent.protocol.CompletionItemParams
import com.sourcegraph.cody.agent.protocol.CurrentUserCodySubscription
import com.sourcegraph.cody.agent.protocol.EditTask
import com.sourcegraph.cody.agent.protocol.Event
import com.sourcegraph.cody.agent.protocol.GetFeatureFlag
import com.sourcegraph.cody.agent.protocol.GetFoldingRangeParams
import com.sourcegraph.cody.agent.protocol.GetFoldingRangeResult
import com.sourcegraph.cody.agent.protocol.GetRepoIdsParam
import com.sourcegraph.cody.agent.protocol.GetRepoIdsResponse
import com.sourcegraph.cody.agent.protocol.InlineEditParams
import com.sourcegraph.cody.agent.protocol.ProtocolTextDocument
import com.sourcegraph.cody.agent.protocol.ServerInfo
import com.sourcegraph.cody.agent.protocol.TaskIdParam
import com.sourcegraph.cody.agent.protocol.*
import com.sourcegraph.cody.chat.ConnectionId
import java.util.concurrent.CompletableFuture
import org.eclipse.lsp4j.jsonrpc.services.JsonNotification
Expand Down Expand Up @@ -87,6 +65,11 @@ interface CodyAgentServer {
@JsonNotification("autocomplete/completionAccepted")
fun completionAccepted(logID: CompletionItemParams)

@JsonNotification("remoteRepo/didChange") fun remoteRepoDidChange()

@JsonNotification("remoteRepo/didChangeState")
fun remoteRepoDidChangeState(state: RemoteRepoFetchState)

@JsonRequest("webview/receiveMessage")
fun webviewReceiveMessage(params: WebviewReceiveMessageParams): CompletableFuture<Any?>

Expand Down Expand Up @@ -130,4 +113,10 @@ interface CodyAgentServer {
fun attributionSearch(
params: AttributionSearchParams
): CompletableFuture<AttributionSearchResponse>

@JsonRequest("remoteRepo/has")
fun remoteRepoHas(params: RemoteRepoHasParams): CompletableFuture<RemoteRepoHasResponse>

@JsonRequest("remoteRepo/list")
fun remoteRepoList(params: RemoteRepoListParams): CompletableFuture<RemoteRepoListResponse>
}
62 changes: 49 additions & 13 deletions src/main/kotlin/com/sourcegraph/cody/agent/CodyAgentService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,20 @@ import com.intellij.openapi.components.Service
import com.intellij.openapi.components.service
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.project.Project
import com.sourcegraph.cody.CodyFileEditorListener
import com.sourcegraph.cody.chat.AgentChatSessionService
import com.sourcegraph.cody.config.CodyApplicationSettings
import com.sourcegraph.cody.context.RemoteRepoSearcher
import com.sourcegraph.cody.edit.FixupService
import com.sourcegraph.cody.statusbar.CodyStatusService
import java.util.concurrent.CompletableFuture
import java.util.concurrent.TimeUnit
import java.util.concurrent.TimeoutException
import java.util.concurrent.atomic.AtomicReference
import java.util.function.Consumer
import kotlinx.coroutines.runBlocking

@Service(Service.Level.PROJECT)
class CodyAgentService(project: Project) : Disposable {
Expand Down Expand Up @@ -61,6 +64,14 @@ class CodyAgentService(project: Project) : Disposable {
FixupService.getInstance(project).getActiveSession()?.performInlineEdits(params.edits)
}

agent.client.onRemoteRepoDidChange = Consumer {
RemoteRepoSearcher.getInstance(project).remoteRepoDidChange()
}

agent.client.onRemoteRepoDidChangeState = Consumer { state ->
RemoteRepoSearcher.getInstance(project).remoteRepoDidChangeState(state)
}

if (!project.isDisposed) {
AgentChatSessionService.getInstance(project).restoreAllSessions(agent)
val fileEditorManager = FileEditorManager.getInstance(project)
Expand Down Expand Up @@ -156,19 +167,15 @@ class CodyAgentService(project: Project) : Disposable {
) {
if (CodyApplicationSettings.instance.isCodyEnabled) {
ApplicationManager.getApplication().executeOnPooledThread {
try {
val instance = getInstance(project)
val isReadyButNotFunctional = instance.codyAgent.getNow(null)?.isConnected() == false
val agent =
if (isReadyButNotFunctional && restartIfNeeded) instance.restartAgent(project)
else instance.codyAgent

callback.accept(agent.get())
setAgentError(project, null)
} catch (e: Exception) {
logger.warn("Failed to execute call to agent", e)
onFailure.accept(e)
if (restartIfNeeded) getInstance(project).restartAgent(project)
runBlocking {
val task: suspend (CodyAgent) -> Unit = { agent ->
try {
callback.accept(agent)
} catch (e: Exception) {
onFailure.accept(e)
}
}
coWithAgent(project, restartIfNeeded, task)
}
}
}
Expand Down Expand Up @@ -201,5 +208,34 @@ class CodyAgentService(project: Project) : Disposable {
false
}
}

suspend fun <T> coWithAgent(project: Project, callback: suspend (CodyAgent) -> T) =
coWithAgent(project, false, callback)

suspend fun <T> coWithAgent(
project: Project,
restartIfNeeded: Boolean,
callback: suspend (CodyAgent) -> T
): T {
if (!CodyApplicationSettings.instance.isCodyEnabled) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That change will require testing all the features with disabled cody:

  • chat, @-files
  • commands
  • autocompletion
  • enhanced context
  • edit tasks
  • account management panel

I do not trust we properly handle exeptions everywhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It won't because the withAgent wrappers check this boolean. We might get one exception if you disable agent between the time of that check and the time this coroutine runs.

throw Exception("Cody is not enabled")
}
try {
val instance = CodyAgentService.getInstance(project)
val isReadyButNotFunctional = instance.codyAgent.getNow(null)?.isConnected() == false
val agent =
if (isReadyButNotFunctional && restartIfNeeded) instance.restartAgent(project)
else instance.codyAgent
val result = callback(agent.get())
setAgentError(project, null)
return result
} catch (e: Exception) {
logger.warn("Failed to execute call to agent", e)
if (restartIfNeeded && e !is ProcessCanceledException) {
getInstance(project).restartAgent(project)
}
throw e
}
}
}
}
29 changes: 29 additions & 0 deletions src/main/kotlin/com/sourcegraph/cody/agent/protocol/RemoteRepo.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.sourcegraph.cody.agent.protocol

import com.sourcegraph.cody.error.CodyError

data class RemoteRepoHasParams(
val repoName: String,
)

data class RemoteRepoHasResponse(
val result: Boolean,
)

data class RemoteRepoListParams(
val query: String?,
val first: Int,
val after: String?,
)

data class RemoteRepoListResponse(
val startIndex: Int,
val count: Int,
val repos: List<Repo>,
val state: RemoteRepoFetchState,
)

data class RemoteRepoFetchState(
val state: String, // one of: "paused", "fetching", "errored", "complete"
val error: CodyError?,
)
4 changes: 2 additions & 2 deletions src/main/kotlin/com/sourcegraph/cody/chat/ui/ChatPanel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class ChatPanel(
private val messagesPanel = MessagesPanel(project, chatSession)
private val chatPanel = ChatScrollPane(messagesPanel)

private val contextView: EnhancedContextPanel = EnhancedContextPanel(project, chatSession)
private val contextView: EnhancedContextPanel = EnhancedContextPanel.create(project, chatSession)

private val stopGeneratingButton =
object : JButton("Stop generating", IconUtil.desaturate(AllIcons.Actions.Suspend)) {
Expand Down Expand Up @@ -75,7 +75,7 @@ class ChatPanel(
promptPanel.focus()
}

fun isEnhancedContextEnabled(): Boolean = contextView.isEnhancedContextEnabled.get()
fun isEnhancedContextEnabled(): Boolean = contextView.isEnhancedContextEnabled

@RequiresEdt
fun addOrUpdateMessage(message: ChatMessage, index: Int) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.intellij.util.xmlb.annotations.Attribute
import com.intellij.util.xmlb.annotations.Tag
import com.sourcegraph.cody.auth.ServerPath
import com.sourcegraph.config.ConfigUtil
import java.net.URI
import java.util.regex.Pattern

@Tag("server")
Expand All @@ -22,6 +23,9 @@ data class SourcegraphServerPath(
return url + GRAPHQL_API_SUFFIX
}

val displayName: String
get() = URI.create(url).host

companion object {
const val DEFAULT_HOST = ConfigUtil.DOTCOM_URL

Expand Down
Loading
Loading