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

refactor: Optimize widget initialization and loading state #4417

Merged
merged 1 commit into from
Mar 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 7 additions & 8 deletions core/autocomplete/CompletionProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import { DEFAULT_AUTOCOMPLETE_OPTS } from "../util/parameters.js";

import { shouldCompleteMultiline } from "./classification/shouldCompleteMultiline.js";
import { ContextRetrievalService } from "./context/ContextRetrievalService.js";

Check warning on line 8 in core/autocomplete/CompletionProvider.ts

View workflow job for this annotation

GitHub Actions / core-checks

There should be no empty line within import group

import { BracketMatchingService } from "./filtering/BracketMatchingService.js";
import { CompletionStreamer } from "./generation/CompletionStreamer.js";
Expand Down Expand Up @@ -134,6 +134,13 @@
token: AbortSignal | undefined,
): Promise<AutocompleteOutcome | undefined> {
try {
// Create abort signal if not given
if (!token) {
const controller = this.loggingService.createAbortController(
input.completionId,
);
token = controller.signal;
}
const startTime = Date.now();
const options = await this._getAutocompleteOptions();

Expand All @@ -158,14 +165,6 @@
return undefined;
}

// Create abort signal if not given
if (!token) {
const controller = this.loggingService.createAbortController(
input.completionId,
);
token = controller.signal;
}

const [snippetPayload, workspaceDirs] = await Promise.all([
getAllSnippets({
helper,
Expand Down Expand Up @@ -258,7 +257,7 @@

// Save to cache
if (!outcome.cacheHit && helper.options.useCache) {
(await this.autocompleteCache).put(outcome.prefix, outcome.completion);

Check warning on line 260 in core/autocomplete/CompletionProvider.ts

View workflow job for this annotation

GitHub Actions / core-checks

Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator
}

// When using the JetBrains extension, Mark as displayed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,15 @@ fun Editor.addInlayElement(
class AutocompleteService(private val project: Project) {
var pendingCompletion: PendingCompletion? = null
private val autocompleteLookupListener = project.service<AutocompleteLookupListener>()
private var widget: AutocompleteSpinnerWidget? = null
private val widget: AutocompleteSpinnerWidget? by lazy {
WindowManager.getInstance().getStatusBar(project)
?.getWidget(AutocompleteSpinnerWidget.ID) as? AutocompleteSpinnerWidget
}

// To avoid triggering another completion on partial acceptance,
// we need to keep track of whether the last change was a partial accept
var lastChangeWasPartialAccept = false

init {
val statusBar = WindowManager.getInstance().getStatusBar(project)
widget = statusBar.getWidget("AutocompleteSpinnerWidget") as? AutocompleteSpinnerWidget
}

fun triggerCompletion(editor: Editor) {
val settings =
ServiceManager.getService(ContinueExtensionSettings::class.java)
Expand All @@ -80,13 +78,14 @@ class AutocompleteService(private val project: Project) {
val completionId = uuid()
val offset = editor.caretModel.primaryCaret.offset
pendingCompletion = PendingCompletion(editor, offset, completionId, null)
widget?.setLoading(true)

// Request a completion from the core
val virtualFile = FileDocumentManager.getInstance().getFile(editor.document)

val uri = virtualFile?.toUriOrNull() ?: return

widget?.setLoading(true)

val line = editor.caretModel.primaryCaret.logicalPosition.line
val column = editor.caretModel.primaryCaret.logicalPosition.column
val input = mapOf(
Expand All @@ -106,7 +105,9 @@ class AutocompleteService(private val project: Project) {
input,
null,
({ response ->
widget?.setLoading(false)
if (pendingCompletion == null || pendingCompletion?.completionId == completionId) {
widget?.setLoading(false)
}

val responseObject = response as Map<*, *>
val completions = responseObject["content"] as List<*>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,7 @@ class AutocompleteSpinnerWidget(project: Project) : EditorBasedWidget(project),
private val iconLabel = JLabel()
private var isLoading = false

private val animatedIcon = AnimatedIcon(
100,
IconLoader.getIcon("/icons/AnimationLoadingIcon/AnimationLoading1(RiderLight).svg", javaClass),
IconLoader.getIcon("/icons/AnimationLoadingIcon/AnimationLoading2(RiderLight).svg", javaClass),
IconLoader.getIcon("/icons/AnimationLoadingIcon/AnimationLoading3(RiderLight).svg", javaClass),
IconLoader.getIcon("/icons/AnimationLoadingIcon/AnimationLoading4(RiderLight).svg", javaClass),
IconLoader.getIcon("/icons/AnimationLoadingIcon/AnimationLoading5(RiderLight).svg", javaClass),
IconLoader.getIcon("/icons/AnimationLoadingIcon/AnimationLoading6(RiderLight).svg", javaClass),
IconLoader.getIcon("/icons/AnimationLoadingIcon/AnimationLoading7(RiderLight).svg", javaClass),
IconLoader.getIcon("/icons/AnimationLoadingIcon/AnimationLoading8(RiderLight).svg", javaClass),
)
private val animatedIcon = AnimatedIcon.Default()

init {
Disposer.register(ContinuePluginDisposable.getInstance(project), this)
Expand All @@ -47,10 +37,10 @@ class AutocompleteSpinnerWidget(project: Project) : EditorBasedWidget(project),
override fun dispose() {}

override fun ID(): String {
return "AutocompleteSpinnerWidget"
return ID
}

override fun getTooltipText(): String? {
override fun getTooltipText(): String {
val enabled = service<ContinueExtensionSettings>().state.enableTabAutocomplete
return if (enabled) "Continue autocomplete enabled" else "Continue autocomplete disabled"
}
Expand Down Expand Up @@ -80,9 +70,13 @@ class AutocompleteSpinnerWidget(project: Project) : EditorBasedWidget(project),
updateIcon()
}

override fun getPresentation(): StatusBarWidget.WidgetPresentation? {
override fun getPresentation(): StatusBarWidget.WidgetPresentation {
return this
}

companion object {
const val ID = "AutocompleteSpinnerWidget"
}
}

class AutocompleteSpinnerWidgetFactory : StatusBarWidgetFactory {
Expand All @@ -91,7 +85,7 @@ class AutocompleteSpinnerWidgetFactory : StatusBarWidgetFactory {
}

override fun getId(): String {
return "AutocompleteSpinnerWidget"
return AutocompleteSpinnerWidget.ID
}

override fun getDisplayName(): String {
Expand All @@ -103,7 +97,7 @@ class AutocompleteSpinnerWidgetFactory : StatusBarWidgetFactory {
}

override fun createWidget(project: Project): StatusBarWidget {
return AutocompleteSpinnerWidget(project)
return create(project)
}

override fun disposeWidget(p0: StatusBarWidget) {
Expand Down
Loading