Skip to content

Commit b329d9f

Browse files
abogoyavlenskyavli
authored andcommitted
Add optional ability to show evaluation result inline
1 parent 94237b5 commit b329d9f

File tree

4 files changed

+115
-8
lines changed

4 files changed

+115
-8
lines changed

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ option in your VSCode settings globally or per-project and connect manually to w
6161

6262
```clojure
6363
{:user {:plugins [[cider/cider-nrepl "0.22.1"]]
64-
:dependencies [[cljfmt "0.5.7"]]}}
64+
:dependencies [[cljfmt "0.5.7"]]}}
6565
```
6666

6767
Alternatively, you can put the code above to your project `project.clj` file.
@@ -75,6 +75,7 @@ The extension contributes the configuration parameters listed in the table below
7575
|`clojureVSCode.autoStartNRepl` | Whether to start an nREPL when opening a file or project. |
7676
|`clojureVSCode.formatOnSave` | Format files with [cljfmt](https://github.com/weavejester/cljfmt) on save. |
7777
|`clojureVSCode.cljfmtParameters`| Formatting parameters passed to `cljfmt` each time it runs, e.g. `:indentation? true :remove-surrounding-whitespace? false` |
78+
|`clojureVSCode.showResultInline` | Show evaluation result inline. |
7879

7980
## ClojureScript Project Setup
8081

package.json

+27-2
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,36 @@
121121
},
122122
"clojureVSCode.cljfmtParameters": {
123123
"type": "string",
124-
"description": "Parameters which will be passed to cljfmt",
124+
"description": "Parameters which will be passed to cljfmt.",
125125
"default": ""
126+
},
127+
"clojureVSCode.showResultInline": {
128+
"type": "boolean",
129+
"default": false,
130+
"description": "Show evaluation result inline."
126131
}
127132
}
128-
}
133+
},
134+
"colors": [
135+
{
136+
"id": "clojureVSCode.inlineResultBackground",
137+
"description": "Background color of the inline result.",
138+
"defaults": {
139+
"dark": "#00000000",
140+
"light": "#00000000",
141+
"highContrast": "#00000000"
142+
}
143+
},
144+
{
145+
"id": "clojureVSCode.inlineResultForeground",
146+
"description": "Foreground color of the inline result.",
147+
"defaults": {
148+
"dark": "#99999999",
149+
"light": "#99999999",
150+
"highContrast": "#99999999"
151+
}
152+
}
153+
]
129154
},
130155
"scripts": {
131156
"vscode:prepublish": "webpack --mode production",

src/clojureEval.ts

+77-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as vscode from 'vscode';
22

33
import { cljConnection } from './cljConnection';
4+
import { LANGUAGE } from './clojureMode';
45
import { cljParser } from './cljParser';
56
import { nreplClient } from './nreplClient';
67
import { TestListener } from './testRunner';
@@ -10,6 +11,17 @@ const BLOCK_DECORATION_TYPE = vscode.window.createTextEditorDecorationType({
1011
backgroundColor: { id: 'editor.findMatchHighlightBackground' }
1112
});
1213

14+
const INLINE_RESULT_LENGTH = 150;
15+
const INLINE_RESULT_DECORATION_TYPE = vscode.window.createTextEditorDecorationType({
16+
before: {
17+
margin: '0 0 0 2em',
18+
textDecoration: 'none',
19+
fontWeight: 'normal',
20+
fontStyle: 'normal',
21+
},
22+
rangeBehavior: vscode.DecorationRangeBehavior.ClosedOpen
23+
});
24+
1325
export function clojureEval(outputChannel: vscode.OutputChannel): void {
1426
evaluate(outputChannel, false);
1527
}
@@ -174,10 +186,15 @@ function evaluate(outputChannel: vscode.OutputChannel, showResults: boolean): vo
174186
}
175187

176188
const selection = blockSelection || editor.selection;
177-
let text = editor.document.getText();
189+
let text = editor.document.getText(),
190+
selectionEndLine: number;
191+
178192
if (!selection.isEmpty) {
193+
selectionEndLine = selection.end.line;
179194
const ns: string = cljParser.getNamespace(text);
180195
text = `(ns ${ns})\n${editor.document.getText(selection)}`;
196+
} else {
197+
selectionEndLine = editor.document.lineCount - 1;
181198
}
182199

183200
cljConnection.sessionForFilename(editor.document.fileName).then(session => {
@@ -195,7 +212,7 @@ function evaluate(outputChannel: vscode.OutputChannel, showResults: boolean): vo
195212
if (!!respObjs[0].ex)
196213
return handleError(outputChannel, selection, showResults, respObjs[0].session);
197214

198-
return handleSuccess(outputChannel, showResults, respObjs);
215+
return handleSuccess(outputChannel, showResults, respObjs, selectionEndLine);
199216
})
200217
});
201218
}
@@ -235,19 +252,75 @@ function handleError(outputChannel: vscode.OutputChannel, selection: vscode.Sele
235252
});
236253
}
237254

238-
function handleSuccess(outputChannel: vscode.OutputChannel, showResults: boolean, respObjs: any[]): void {
255+
function truncateLine(value: string): string {
256+
if (value.length > INLINE_RESULT_LENGTH) {
257+
return value.substring(0, INLINE_RESULT_LENGTH) + '...'
258+
}
259+
return value;
260+
}
261+
262+
function showInlineResult(respObj: any, line: number): void {
263+
const isError = Boolean(respObj.err),
264+
editor = vscode.window.activeTextEditor;
265+
let result: string,
266+
foregroundColor: vscode.ThemeColor;
267+
268+
if (isError) {
269+
// show more error description at once
270+
result = respObj.err.replace(/\n/g, ' ');
271+
foregroundColor = new vscode.ThemeColor('editorError.foreground');
272+
} else {
273+
result = respObj.value;
274+
foregroundColor = new vscode.ThemeColor('clojureVSCode.inlineResultForeground');
275+
}
276+
277+
if (result && editor) {
278+
const decoration: vscode.DecorationOptions = {
279+
renderOptions: {
280+
before: {
281+
backgroundColor: new vscode.ThemeColor('clojureVSCode.inlineResultBackground'),
282+
color: foregroundColor,
283+
contentText: truncateLine(result),
284+
},
285+
},
286+
range: editor.document.validateRange(
287+
new vscode.Range(line, Number.MAX_SAFE_INTEGER, line, Number.MAX_SAFE_INTEGER)
288+
)
289+
};
290+
editor.setDecorations(INLINE_RESULT_DECORATION_TYPE, [decoration]);
291+
}
292+
}
293+
294+
function handleSuccess(outputChannel: vscode.OutputChannel, showResults: boolean, respObjs: any[], selectionEndLine: number): void {
239295
if (!showResults) {
240296
vscode.window.showInformationMessage('Successfully compiled');
241297
} else {
298+
const config = vscode.workspace.getConfiguration('clojureVSCode');
299+
242300
respObjs.forEach(respObj => {
243301
if (respObj.out)
244302
outputChannel.append(respObj.out);
245303
if (respObj.err)
246304
outputChannel.append(respObj.err);
247305
if (respObj.value)
248306
outputChannel.appendLine(`=> ${respObj.value}`);
249-
outputChannel.show(true);
307+
308+
if (config.showResultInline) {
309+
showInlineResult(respObj, selectionEndLine);
310+
} else {
311+
outputChannel.show(true);
312+
};
250313
});
251314
}
252315
nreplClient.close(respObjs[0].session);
316+
};
317+
318+
export function clearInlineResultDecorationOnMove(event: vscode.TextEditorSelectionChangeEvent) {
319+
const config = vscode.workspace.getConfiguration('clojureVSCode');
320+
if (config.showResultInline
321+
&& event.textEditor.document.languageId === LANGUAGE
322+
&& event.textEditor === vscode.window.activeTextEditor) {
323+
324+
event.textEditor.setDecorations(INLINE_RESULT_DECORATION_TYPE, []);
325+
}
253326
}

src/clojureMain.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ import * as vscode from 'vscode';
22

33
import { CLOJURE_MODE, LANGUAGE } from './clojureMode';
44
import { ClojureCompletionItemProvider } from './clojureSuggest';
5-
import { clojureEval, clojureEvalAndShowResult, testNamespace, runAllTests } from './clojureEval';
5+
import {
6+
clojureEval, clojureEvalAndShowResult, testNamespace, runAllTests,
7+
clearInlineResultDecorationOnMove
8+
} from './clojureEval';
69
import { ClojureDefinitionProvider } from './clojureDefinition';
710
import { ClojureLanguageConfiguration } from './clojureConfiguration';
811
import { ClojureHoverProvider } from './clojureHover';
@@ -48,6 +51,11 @@ export function activate(context: vscode.ExtensionContext) {
4851

4952
vscode.workspace.registerTextDocumentContentProvider('jar', new JarContentProvider());
5053
vscode.languages.setLanguageConfiguration(LANGUAGE, ClojureLanguageConfiguration);
54+
55+
// events
56+
vscode.window.onDidChangeTextEditorSelection(event => {
57+
clearInlineResultDecorationOnMove(event);
58+
}, null, context.subscriptions);
5159
}
5260

5361
export function deactivate() { }

0 commit comments

Comments
 (0)