Skip to content

Commit dd17b56

Browse files
authored
Merge pull request #2347 from continuedev/nate/jetbrains-updates
JetBrains Updates
2 parents 9a550ef + 89a02e2 commit dd17b56

31 files changed

+395
-476
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
## 0.0.69 - 2024-09-22
2+
### Added
3+
* Support for the "search" context provider
4+
### Fixed
5+
* Fixed bug where only first module would be recognized
6+
* Improved concurrency handling to avoid freezes
7+
* Made compatible with latest JetBrains versions

.changes/unreleased/Added-20240915-163755.yaml

Lines changed: 0 additions & 4 deletions
This file was deleted.

.changes/unreleased/Fixed-20240915-163641.yaml

Lines changed: 0 additions & 4 deletions
This file was deleted.

.github/workflows/jetbrains-release.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ jobs:
203203
ls
204204
echo "---"
205205
FILENAME=`ls continue-intellij-extension-*.zip`
206+
echo "Filename=${FILENAME}"
206207
unzip "$FILENAME" -d content
207208
208209
echo "filename=${FILENAME%.????}" >> $GITHUB_OUTPUT
@@ -330,10 +331,10 @@ jobs:
330331
331332
- name: Upload logs
332333
if: ${{ always() }}
333-
uses: actions/upload-artifact@v2
334+
uses: actions/upload-artifact@v4
334335
with:
335336
name: core-logs-${{ matrix.platform }}-${{ matrix.arch }}
336-
path: binary/.continue/logs/core.log
337+
path: ~/.continue/logs/core.log
337338

338339
# Run tests and upload a code coverage report
339340
test:

binary/test/binary.test.ts

Lines changed: 68 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ import FileSystemIde from "core/util/filesystem";
55
import { IMessenger } from "core/util/messenger";
66
import { ReverseMessageIde } from "core/util/reverseMessageIde";
77
import fs from "fs";
8-
import { ChildProcessWithoutNullStreams, spawn } from "node:child_process";
8+
import {
9+
ChildProcessWithoutNullStreams,
10+
execSync,
11+
spawn,
12+
} from "node:child_process";
913
import path from "path";
1014
import {
1115
CoreBinaryMessenger,
@@ -59,21 +63,66 @@ describe("Test Suite", () => {
5963

6064
beforeAll(async () => {
6165
const [platform, arch] = autodetectPlatformAndArch();
62-
const binaryPath = path.join(
63-
__dirname,
64-
"..",
65-
"bin",
66-
`${platform}-${arch}`,
67-
`continue-binary${platform === "win32" ? ".exe" : ""}`,
68-
);
69-
expect(fs.existsSync(binaryPath)).toBe(true);
66+
const binaryDir = path.join(__dirname, "..", "bin", `${platform}-${arch}`);
67+
const exe = platform === "win32" ? ".exe" : "";
68+
const binaryPath = path.join(binaryDir, `continue-binary${exe}`);
69+
const expectedItems = [
70+
`continue-binary${exe}`,
71+
`esbuild${exe}`,
72+
"index.node",
73+
"package.json",
74+
"build/Release/node_sqlite3.node",
75+
];
76+
expectedItems.forEach((item) => {
77+
expect(fs.existsSync(path.join(binaryDir, item))).toBe(true);
78+
});
79+
80+
// Set execute permissions and remove quarantine attribute if on macOS
81+
if (platform !== "win32") {
82+
try {
83+
fs.chmodSync(binaryPath, 0o755);
84+
console.log("Execute permissions set for the binary");
85+
86+
if (platform === "darwin") {
87+
const indexNodePath = path.join(binaryDir, "index.node");
88+
const filesToUnquarantine = [binaryPath, indexNodePath];
89+
90+
for (const file of filesToUnquarantine) {
91+
try {
92+
execSync(`xattr -d com.apple.quarantine "${file}"`, {
93+
stdio: "ignore",
94+
});
95+
console.log(
96+
`Quarantine attribute removed from ${path.basename(file)}`,
97+
);
98+
} catch (error) {
99+
console.warn(
100+
`Failed to remove quarantine attribute from ${path.basename(file)}:`,
101+
error,
102+
);
103+
}
104+
}
105+
}
106+
} catch (error) {
107+
console.error(
108+
"Error setting permissions or removing quarantine:",
109+
error,
110+
);
111+
}
112+
}
70113

71114
if (USE_TCP) {
72115
messenger = new CoreBinaryTcpMessenger<ToIdeProtocol, FromIdeProtocol>();
73116
} else {
74-
subprocess = spawn(binaryPath, {
75-
env: { ...process.env, CONTINUE_GLOBAL_DIR },
76-
});
117+
try {
118+
subprocess = spawn(binaryPath, {
119+
env: { ...process.env, CONTINUE_GLOBAL_DIR },
120+
});
121+
console.log("Successfully spawned subprocess");
122+
} catch (error) {
123+
console.error("Error spawning subprocess:", error);
124+
throw error;
125+
}
77126
messenger = new CoreBinaryMessenger<ToIdeProtocol, FromIdeProtocol>(
78127
subprocess,
79128
);
@@ -123,13 +172,17 @@ describe("Test Suite", () => {
123172
"package.json",
124173
"logs/core.log",
125174
"index/autocompleteCache.sqlite",
126-
"out/config.js",
127175
"types/core/index.d.ts",
128176
];
129177

130-
for (const file of expectedFiles) {
178+
const missingFiles = expectedFiles.filter((file) => {
131179
const filePath = path.join(CONTINUE_GLOBAL_DIR, file);
132-
expect(fs.existsSync(filePath)).toBe(true);
180+
return !fs.existsSync(filePath);
181+
});
182+
183+
expect(missingFiles).toEqual([]);
184+
if (missingFiles.length > 0) {
185+
console.log("Missing files:", missingFiles);
133186
}
134187
});
135188

extensions/intellij/.run/Run Verifications.run.xml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<log_file alias="idea.log" path="$PROJECT_DIR$/build/idea-sandbox/system/log/idea.log" />
44
<ExternalSystemSettings>
55
<option name="executionName" />
6-
<option name="externalProjectPath" value="$PROJECT_DIR$" />
6+
<option name="externalProjectPath" value="$PROJECT_DIR$/extensions/intellij" />
77
<option name="externalSystemIdString" value="GRADLE" />
88
<option name="scriptParameters" value="" />
99
<option name="taskDescriptions">
@@ -19,8 +19,7 @@
1919
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
2020
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
2121
<DebugAllEnabled>false</DebugAllEnabled>
22-
<method v="2">
23-
<option name="Gradle.BeforeRunTask" enabled="true" tasks="clean" externalProjectPath="$PROJECT_DIR$" vmOptions="" scriptParameters="" />
24-
</method>
22+
<RunAsTest>false</RunAsTest>
23+
<method v="2" />
2524
</configuration>
2625
</component>

extensions/intellij/CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html),
55
and is generated by [Changie](https://github.com/miniscruff/changie).
66

77

8-
Pre-release Changes
8+
## 0.0.69 - 2024-09-22
99
### Added
1010
* Support for the "search" context provider
1111
### Fixed
1212
* Fixed bug where only first module would be recognized
13+
* Improved concurrency handling to avoid freezes
14+
* Made compatible with latest JetBrains versions
1315

1416
## 0.0.54 - 2024-07-13
1517
### Added

extensions/intellij/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ dependencies {
4040
}
4141
implementation("com.posthog.java:posthog:1.+")
4242
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0")
43+
// implementation("com.jetbrains.jsonSchema")
4344
}
4445

4546

extensions/intellij/gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ pluginGroup = com.github.continuedev.continueintellijextension
44
pluginName = continue-intellij-extension
55
pluginRepositoryUrl = https://github.com/continuedev/continue
66
# SemVer format -> https://semver.org
7-
pluginVersion = 0.0.68
7+
pluginVersion = 0.0.69
88

99
# Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
1010
pluginSinceBuild = 223

extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/activities/ContinuePluginStartupActivity.kt

Lines changed: 21 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@ import com.github.continuedev.continueintellijextension.listeners.ContinuePlugin
99
import com.github.continuedev.continueintellijextension.services.ContinueExtensionSettings
1010
import com.github.continuedev.continueintellijextension.services.ContinuePluginService
1111
import com.github.continuedev.continueintellijextension.services.SettingsListener
12-
import com.github.continuedev.continueintellijextension.services.TelemetryService
13-
import com.github.continuedev.continueintellijextension.services.TerminalActivityTrackingService
14-
import com.github.continuedev.continueintellijextension.utils.isNotAvailable
1512
import com.intellij.openapi.Disposable
1613
import com.intellij.openapi.actionSystem.KeyboardShortcut
1714
import com.intellij.openapi.application.ApplicationManager
@@ -27,18 +24,11 @@ import com.intellij.openapi.vfs.LocalFileSystem
2724
import kotlinx.coroutines.*
2825
import java.io.*
2926
import java.nio.charset.StandardCharsets
30-
import java.nio.file.Files
3127
import java.nio.file.Paths
3228
import javax.swing.*
33-
import com.intellij.ide.plugins.PluginManager
3429
import com.intellij.openapi.components.service
35-
import com.intellij.openapi.extensions.PluginId
3630
import com.intellij.openapi.module.ModuleManager
3731
import com.intellij.openapi.roots.ModuleRootManager
38-
import com.intellij.openapi.wm.ToolWindowManager
39-
import com.intellij.openapi.wm.ex.ToolWindowManagerListener
40-
import org.jetbrains.plugins.terminal.TerminalToolWindowFactory
41-
import org.jetbrains.plugins.terminal.TerminalView
4232

4333
fun showTutorial(project: Project) {
4434
ContinuePluginStartupActivity::class.java.getClassLoader().getResourceAsStream("continue_tutorial.py").use { `is` ->
@@ -85,9 +75,7 @@ class ContinuePluginStartupActivity : StartupActivity, Disposable, DumbAware {
8575
// }
8676
// )
8777

88-
ApplicationManager.getApplication().executeOnPooledThread {
89-
initializePlugin(project)
90-
}
78+
initializePlugin(project)
9179
}
9280

9381
private fun getPlatformSpecificKeyStroke(key: String): String {
@@ -182,33 +170,31 @@ class ContinuePluginStartupActivity : StartupActivity, Disposable, DumbAware {
182170
}
183171
})
184172

185-
GlobalScope.async(Dispatchers.IO) {
186-
val listener =
187-
ContinuePluginSelectionListener(
188-
ideProtocolClient,
189-
coroutineScope
190-
)
191-
192-
// Reload the WebView
193-
continuePluginService?.let { pluginService ->
194-
val allModulePaths = ModuleManager.getInstance(project).modules
195-
.flatMap { module -> ModuleRootManager.getInstance(module).contentRoots.map { it.path } }
196-
.map { Paths.get(it).normalize() }
173+
val listener =
174+
ContinuePluginSelectionListener(
175+
ideProtocolClient,
176+
coroutineScope
177+
)
197178

198-
val topLevelModulePaths = allModulePaths
199-
.filter { modulePath -> allModulePaths.none { it != modulePath && modulePath.startsWith(it) } }
200-
.map { it.toString() }
179+
// Reload the WebView
180+
continuePluginService?.let { pluginService ->
181+
val allModulePaths = ModuleManager.getInstance(project).modules
182+
.flatMap { module -> ModuleRootManager.getInstance(module).contentRoots.map { it.path } }
183+
.map { Paths.get(it).normalize() }
201184

202-
pluginService.workspacePaths = topLevelModulePaths.toTypedArray()
203-
}
185+
val topLevelModulePaths = allModulePaths
186+
.filter { modulePath -> allModulePaths.none { it != modulePath && modulePath.startsWith(it) } }
187+
.map { it.toString() }
204188

205-
EditorFactory.getInstance().eventMulticaster.addSelectionListener(
206-
listener,
207-
this@ContinuePluginStartupActivity
208-
)
189+
pluginService.workspacePaths = topLevelModulePaths.toTypedArray()
209190
}
210191

211-
val coreMessengerManager = CoreMessengerManager(project, ideProtocolClient)
192+
EditorFactory.getInstance().eventMulticaster.addSelectionListener(
193+
listener,
194+
this@ContinuePluginStartupActivity
195+
)
196+
197+
val coreMessengerManager = CoreMessengerManager(project, ideProtocolClient, coroutineScope)
212198
continuePluginService.coreMessengerManager = coreMessengerManager
213199
}
214200
}

extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/auth/ContinueAuthService.kt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import com.intellij.openapi.components.Service
1010
import com.intellij.openapi.components.service
1111
import com.intellij.openapi.project.Project
1212
import com.intellij.remoteServer.util.CloudConfigurationUtil.createCredentialAttributes
13+
import kotlinx.coroutines.CoroutineScope
1314
import java.awt.Desktop
1415
import kotlinx.coroutines.Dispatchers
1516
import kotlinx.coroutines.launch
@@ -22,6 +23,8 @@ import java.net.URL
2223

2324
@Service
2425
class ContinueAuthService {
26+
private val coroutineScope = CoroutineScope(Dispatchers.IO)
27+
2528
companion object {
2629
fun getInstance(): ContinueAuthService = service<ContinueAuthService>()
2730
private const val CREDENTIALS_USER = "ContinueAuthUser"
@@ -61,7 +64,7 @@ class ContinueAuthService {
6164

6265
private fun updateRefreshToken(token: String) {
6366
// Launch a coroutine to call the suspend function
64-
kotlinx.coroutines.GlobalScope.launch {
67+
coroutineScope.launch {
6568
try {
6669
val response = refreshToken(token)
6770
val accessToken = response["accessToken"] as? String
@@ -89,7 +92,7 @@ class ContinueAuthService {
8992

9093
private fun setupRefreshTokenInterval() {
9194
// Launch a coroutine to refresh the token every 30 minutes
92-
kotlinx.coroutines.GlobalScope.launch {
95+
coroutineScope.launch {
9396
while (true) {
9497
val refreshToken = getRefreshToken()
9598
if (refreshToken != null) {

extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/autocomplete/AutocompleteEditorListener.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class AutocompleteDocumentListener(private val editorManager: FileEditorManager,
4242

4343
// Invoke later is important, otherwise the completion will be triggered before the document is updated
4444
// causing the old caret offset to be used
45+
// TODO: concurrency
4546
invokeLater {
4647
service.triggerCompletion(editor)
4748
}

extensions/intellij/src/main/kotlin/com/github/continuedev/continueintellijextension/autocomplete/AutocompleteSpinnerWidgetFactory.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class AutocompleteSpinnerWidget(project: Project): EditorBasedWidget(project), S
3434
)
3535

3636
init {
37+
Disposer.register(project, this)
3738
updateIcon()
3839
}
3940

@@ -49,7 +50,7 @@ class AutocompleteSpinnerWidget(project: Project): EditorBasedWidget(project), S
4950

5051
override fun getTooltipText(): String? {
5152
val enabled = service<ContinueExtensionSettings>().state.enableTabAutocomplete
52-
return if (enabled) "Continue Autocomplete Enabled" else "Continue Autocomplete Disabled"
53+
return if (enabled) "Continue autocomplete enabled" else "Continue autocomplete disabled"
5354
}
5455

5556
override fun getClickConsumer(): Consumer<MouseEvent>? {
@@ -70,7 +71,7 @@ class AutocompleteSpinnerWidget(project: Project): EditorBasedWidget(project), S
7071

7172
// Update the widget
7273
val statusBar = WindowManager.getInstance().getStatusBar(project)
73-
statusBar.updateWidget(ID())
74+
statusBar?.updateWidget(ID())
7475
}
7576

7677
override fun install(statusBar: StatusBar) {

0 commit comments

Comments
 (0)