Skip to content

Commit

Permalink
Add optional ability to show evaluation result inline
Browse files Browse the repository at this point in the history
  • Loading branch information
abogoyavlensky authored and avli committed Mar 28, 2020
1 parent 94237b5 commit b329d9f
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 8 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ option in your VSCode settings globally or per-project and connect manually to w

```clojure
{:user {:plugins [[cider/cider-nrepl "0.22.1"]]
:dependencies [[cljfmt "0.5.7"]]}}
:dependencies [[cljfmt "0.5.7"]]}}
```

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

## ClojureScript Project Setup

Expand Down
29 changes: 27 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,36 @@
},
"clojureVSCode.cljfmtParameters": {
"type": "string",
"description": "Parameters which will be passed to cljfmt",
"description": "Parameters which will be passed to cljfmt.",
"default": ""
},
"clojureVSCode.showResultInline": {
"type": "boolean",
"default": false,
"description": "Show evaluation result inline."
}
}
}
},
"colors": [
{
"id": "clojureVSCode.inlineResultBackground",
"description": "Background color of the inline result.",
"defaults": {
"dark": "#00000000",
"light": "#00000000",
"highContrast": "#00000000"
}
},
{
"id": "clojureVSCode.inlineResultForeground",
"description": "Foreground color of the inline result.",
"defaults": {
"dark": "#99999999",
"light": "#99999999",
"highContrast": "#99999999"
}
}
]
},
"scripts": {
"vscode:prepublish": "webpack --mode production",
Expand Down
81 changes: 77 additions & 4 deletions src/clojureEval.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as vscode from 'vscode';

import { cljConnection } from './cljConnection';
import { LANGUAGE } from './clojureMode';
import { cljParser } from './cljParser';
import { nreplClient } from './nreplClient';
import { TestListener } from './testRunner';
Expand All @@ -10,6 +11,17 @@ const BLOCK_DECORATION_TYPE = vscode.window.createTextEditorDecorationType({
backgroundColor: { id: 'editor.findMatchHighlightBackground' }
});

const INLINE_RESULT_LENGTH = 150;
const INLINE_RESULT_DECORATION_TYPE = vscode.window.createTextEditorDecorationType({
before: {
margin: '0 0 0 2em',
textDecoration: 'none',
fontWeight: 'normal',
fontStyle: 'normal',
},
rangeBehavior: vscode.DecorationRangeBehavior.ClosedOpen
});

export function clojureEval(outputChannel: vscode.OutputChannel): void {
evaluate(outputChannel, false);
}
Expand Down Expand Up @@ -174,10 +186,15 @@ function evaluate(outputChannel: vscode.OutputChannel, showResults: boolean): vo
}

const selection = blockSelection || editor.selection;
let text = editor.document.getText();
let text = editor.document.getText(),
selectionEndLine: number;

if (!selection.isEmpty) {
selectionEndLine = selection.end.line;
const ns: string = cljParser.getNamespace(text);
text = `(ns ${ns})\n${editor.document.getText(selection)}`;
} else {
selectionEndLine = editor.document.lineCount - 1;
}

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

return handleSuccess(outputChannel, showResults, respObjs);
return handleSuccess(outputChannel, showResults, respObjs, selectionEndLine);
})
});
}
Expand Down Expand Up @@ -235,19 +252,75 @@ function handleError(outputChannel: vscode.OutputChannel, selection: vscode.Sele
});
}

function handleSuccess(outputChannel: vscode.OutputChannel, showResults: boolean, respObjs: any[]): void {
function truncateLine(value: string): string {
if (value.length > INLINE_RESULT_LENGTH) {
return value.substring(0, INLINE_RESULT_LENGTH) + '...'
}
return value;
}

function showInlineResult(respObj: any, line: number): void {
const isError = Boolean(respObj.err),
editor = vscode.window.activeTextEditor;
let result: string,
foregroundColor: vscode.ThemeColor;

if (isError) {
// show more error description at once
result = respObj.err.replace(/\n/g, ' ');
foregroundColor = new vscode.ThemeColor('editorError.foreground');
} else {
result = respObj.value;
foregroundColor = new vscode.ThemeColor('clojureVSCode.inlineResultForeground');
}

if (result && editor) {
const decoration: vscode.DecorationOptions = {
renderOptions: {
before: {
backgroundColor: new vscode.ThemeColor('clojureVSCode.inlineResultBackground'),
color: foregroundColor,
contentText: truncateLine(result),
},
},
range: editor.document.validateRange(
new vscode.Range(line, Number.MAX_SAFE_INTEGER, line, Number.MAX_SAFE_INTEGER)
)
};
editor.setDecorations(INLINE_RESULT_DECORATION_TYPE, [decoration]);
}
}

function handleSuccess(outputChannel: vscode.OutputChannel, showResults: boolean, respObjs: any[], selectionEndLine: number): void {
if (!showResults) {
vscode.window.showInformationMessage('Successfully compiled');
} else {
const config = vscode.workspace.getConfiguration('clojureVSCode');

respObjs.forEach(respObj => {
if (respObj.out)
outputChannel.append(respObj.out);
if (respObj.err)
outputChannel.append(respObj.err);
if (respObj.value)
outputChannel.appendLine(`=> ${respObj.value}`);
outputChannel.show(true);

if (config.showResultInline) {
showInlineResult(respObj, selectionEndLine);
} else {
outputChannel.show(true);
};
});
}
nreplClient.close(respObjs[0].session);
};

export function clearInlineResultDecorationOnMove(event: vscode.TextEditorSelectionChangeEvent) {
const config = vscode.workspace.getConfiguration('clojureVSCode');
if (config.showResultInline
&& event.textEditor.document.languageId === LANGUAGE
&& event.textEditor === vscode.window.activeTextEditor) {

event.textEditor.setDecorations(INLINE_RESULT_DECORATION_TYPE, []);
}
}
10 changes: 9 additions & 1 deletion src/clojureMain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ import * as vscode from 'vscode';

import { CLOJURE_MODE, LANGUAGE } from './clojureMode';
import { ClojureCompletionItemProvider } from './clojureSuggest';
import { clojureEval, clojureEvalAndShowResult, testNamespace, runAllTests } from './clojureEval';
import {
clojureEval, clojureEvalAndShowResult, testNamespace, runAllTests,
clearInlineResultDecorationOnMove
} from './clojureEval';
import { ClojureDefinitionProvider } from './clojureDefinition';
import { ClojureLanguageConfiguration } from './clojureConfiguration';
import { ClojureHoverProvider } from './clojureHover';
Expand Down Expand Up @@ -48,6 +51,11 @@ export function activate(context: vscode.ExtensionContext) {

vscode.workspace.registerTextDocumentContentProvider('jar', new JarContentProvider());
vscode.languages.setLanguageConfiguration(LANGUAGE, ClojureLanguageConfiguration);

// events
vscode.window.onDidChangeTextEditorSelection(event => {
clearInlineResultDecorationOnMove(event);
}, null, context.subscriptions);
}

export function deactivate() { }

0 comments on commit b329d9f

Please sign in to comment.