Skip to content

Commit 6f1a37c

Browse files
committed
Merge branch dev into published
2 parents 59e01bb + cbbd454 commit 6f1a37c

File tree

6 files changed

+83
-34
lines changed

6 files changed

+83
-34
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ Changes to Calva.
44

55
## [Unreleased]
66

7+
## [2.0.540] - 2025-11-06
8+
9+
- Fix: [Interrupting evaluations looks like it succeeds even when it is not supported by the host platform](https://github.com/BetterThanTomorrow/calva/issues/2961)
10+
711
## [2.0.539] - 2025-10-28
812

913
- [Use latest version of libs for Jack-in, if no specific version was set by the user](https://github.com/BetterThanTomorrow/calva/issues/2959)

package-lock.json

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"displayName": "Calva: Clojure & ClojureScript Interactive Programming",
44
"description": "Integrated REPL, formatter, Paredit, and more. Powered by cider-nrepl and clojure-lsp.",
55
"icon": "assets/calva.png",
6-
"version": "2.0.539",
6+
"version": "2.0.540",
77
"publisher": "betterthantomorrow",
88
"author": {
99
"name": "Better Than Tomorrow",

src/evaluate.ts

Lines changed: 68 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -28,32 +28,76 @@ function initInspectorDataProvider() {
2828
return inspectorDataProvider;
2929
}
3030

31-
function interruptAllEvaluations() {
32-
if (util.getConnectedState()) {
33-
const msgs: string[] = [];
34-
const nums = NReplEvaluation.interruptAll((msg) => {
35-
msgs.push(msg);
36-
});
37-
if (msgs.length) {
38-
output.appendLineOtherOut(msgs.join('\n'));
39-
}
40-
try {
41-
NReplSession.getInstances().forEach((session, _index) => {
42-
session.interruptAll();
43-
});
44-
} catch (error) {
45-
// TODO: Figure out why we never get here.
46-
console.error(error);
47-
}
48-
if (nums > 0) {
49-
void vscode.window.showInformationMessage(`Interrupted ${nums} running evaluation(s).`);
50-
} else {
51-
void vscode.window.showInformationMessage('Interruption command finished (unknown results)');
52-
}
53-
outputWindow.discardPendingPrints();
31+
async function getJavaVersion(session: NReplSession): Promise<number | null> {
32+
try {
33+
const result = await session.eval('(System/getProperty "java.version")', 'user').value;
34+
// Parse version like "21.0.1", "17.0.2", "1.8.0_292"
35+
const match = result.match(/^"(\d+)/);
36+
return match ? parseInt(match[1], 10) : null;
37+
} catch (error) {
38+
console.error('Failed to get Java version:', error);
39+
return null;
40+
}
41+
}
42+
43+
async function checkJvmAttachSelfSupport(session: NReplSession): Promise<boolean> {
44+
try {
45+
const result = await session.eval('(System/getProperty "jdk.attach.allowAttachSelf")', 'user')
46+
.value;
47+
// 'nil' means not set, any other value means enabled
48+
return result !== 'nil';
49+
} catch (error) {
50+
console.error('Failed to check jdk.attach.allowAttachSelf:', error);
51+
return false;
52+
}
53+
}
54+
55+
async function interruptAllEvaluations() {
56+
if (!util.getConnectedState()) {
57+
void vscode.window.showInformationMessage('Not connected to a REPL server');
58+
return;
59+
}
60+
61+
const firstSession = NReplSession.getInstances()?.[0];
62+
if (!firstSession?.supports('interrupt')) {
63+
void vscode.window.showInformationMessage(
64+
'The nREPL server does not support interruption of evaluations.'
65+
);
5466
return;
5567
}
56-
void vscode.window.showInformationMessage('Not connected to a REPL server');
68+
69+
const javaVersion = await getJavaVersion(firstSession);
70+
if (javaVersion !== null && javaVersion >= 21) {
71+
const attachSelfEnabled = await checkJvmAttachSelfSupport(firstSession);
72+
if (!attachSelfEnabled) {
73+
void vscode.window.showWarningMessage(
74+
'Interrupt may not work: JVM property jdk.attach.allowAttachSelf is not set. ' +
75+
'Add `-Djdk.attach.allowAttachSelf` to your JVM options.'
76+
);
77+
}
78+
}
79+
80+
const msgs: string[] = [];
81+
const nums = NReplEvaluation.interruptAll((msg) => {
82+
msgs.push(msg);
83+
});
84+
if (msgs.length) {
85+
output.appendLineOtherOut(msgs.join('\n'));
86+
}
87+
try {
88+
NReplSession.getInstances().forEach((session, _index) => {
89+
session.interruptAll();
90+
});
91+
} catch (error) {
92+
// TODO: Figure out why we never get here.
93+
console.error(error);
94+
}
95+
if (nums > 0) {
96+
void vscode.window.showInformationMessage(`Interrupted ${nums} running evaluation(s).`);
97+
} else {
98+
void vscode.window.showInformationMessage('Interruption command finished (unknown results)');
99+
}
100+
outputWindow.discardPendingPrints();
57101
}
58102

59103
async function addAsComment(

test-data/.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@
8888
// "autoSelectForConnect": true,
8989
"cljsType": "none",
9090
"menuSelections": {
91-
"cljAliases": ["dev", "test"]
91+
"cljAliases": ["dev", "test", "allow-attach-self"]
9292
}
9393
},
9494
{

test-data/projects/pirate-lang/deps.edn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
:test {:extra-paths ["test"]
66
:extra-deps {org.clojure/test.check {:mvn/version "0.10.0"}}}
77
:dev {:extra-paths ["env/dev"]}
8+
:allow-attach-self {:jvm-opts ["-Djdk.attach.allowAttachSelf"]}
89
:runner
910
{:extra-deps {com.cognitect/test-runner
1011
{:git/url "https://github.com/cognitect-labs/test-runner"

0 commit comments

Comments
 (0)