Skip to content

Commit 00ade72

Browse files
authored
Merge pull request #882 from puppetlabs/cat-1669-fix_hashrocket_allignment
(CAT-1669) - Fix hashrocket allignment on completion item select
2 parents 2681e30 + d505e68 commit 00ade72

File tree

2 files changed

+102
-0
lines changed

2 files changed

+102
-0
lines changed

src/extension.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,17 @@ export function activate(context: vscode.ExtensionContext) {
133133
extensionFeatures.push(new PuppetModuleHoverFeature(extContext, logger));
134134
}
135135

136+
// if formatting is enabled, add a middleware to the language client to format the document on insert
137+
if (settings.format.enable) {
138+
vscode.commands.registerCommand('editor.action.formatDocumentAndMoveCursor', async () => {
139+
vscode.commands.executeCommand('editor.action.formatDocument').then(() => {
140+
vscode.commands.executeCommand('cursorMove', { to: 'left' });
141+
});
142+
});
143+
// add middleware to Intercept the provideCompletionItem method
144+
connectionHandler.languageClient.clientOptions.middleware = provideCompletionItemMiddleware;
145+
}
146+
136147
const facts = new PuppetFactsProvider(connectionHandler);
137148
vscode.window.registerTreeDataProvider('puppetFacts', facts);
138149

@@ -359,3 +370,28 @@ function setLanguageConfiguration() {
359370
},
360371
});
361372
}
373+
374+
export const provideCompletionItemMiddleware = {
375+
provideCompletionItem: async (document, position, context, token, next) => {
376+
// Get the completion list from the language server
377+
const result = await next(document, position, context, token);
378+
let items: vscode.CompletionItem[];
379+
if (Array.isArray(result)) {
380+
items = result;
381+
} else {
382+
items = result.items;
383+
}
384+
// Add command to be executed after completion item is selected
385+
items.forEach(item => {
386+
// check completion item is a prop or param, as this dictates which command to use
387+
const isPropOrParam = item.detail === 'Property' || item.detail === 'Parameter';
388+
// additional cursor cmd on the insertion of a property/param (UX)
389+
const command = isPropOrParam ? 'editor.action.formatDocumentAndMoveCursor' : 'editor.action.formatDocument';
390+
item.command = {
391+
title: 'format document',
392+
command: command
393+
};
394+
});
395+
return items;
396+
}
397+
};

src/test/suite/extension.test.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import * as assert from 'assert';
2+
import { after, before, beforeEach, describe, it } from 'mocha';
3+
import * as sinon from 'sinon';
4+
import * as vscode from 'vscode';
5+
import { provideCompletionItemMiddleware } from '../../extension';
6+
import { PuppetStatusBarFeature } from '../../feature/PuppetStatusBarFeature';
7+
import { ISettings, settingsFromWorkspace } from '../../settings';
8+
9+
describe('Extension Tests', () => {
10+
let vscodeCommandsRegisterCommandStub: sinon.SinonStub;
11+
let puppetStatusBarFeatureStub: sinon.SinonStub;
12+
let settings: ISettings;
13+
let context: vscode.ExtensionContext;
14+
let registerDebugAdapterDescriptorFactoryStub: sinon.SinonStub;
15+
let document: vscode.TextDocument;
16+
let position: vscode.Position;
17+
let completionContext: vscode.CompletionContext;
18+
let token: vscode.CancellationToken;
19+
let next: sinon.SinonStub
20+
const sandbox = sinon.createSandbox();
21+
22+
before(() => {
23+
vscodeCommandsRegisterCommandStub = sandbox.stub(vscode.commands, 'registerCommand');
24+
settings = settingsFromWorkspace();
25+
context = {
26+
subscriptions: [],
27+
asAbsolutePath: (relativePath: string) => {
28+
return `/absolute/path/to/${relativePath}`;
29+
},
30+
globalState: {
31+
get: sandbox.stub(),
32+
}
33+
} as vscode.ExtensionContext;
34+
puppetStatusBarFeatureStub = sandbox.createStubInstance(PuppetStatusBarFeature);
35+
registerDebugAdapterDescriptorFactoryStub = sandbox.stub(vscode.debug, 'registerDebugAdapterDescriptorFactory');
36+
});
37+
38+
beforeEach(() => {
39+
document = {} as vscode.TextDocument;
40+
position = new vscode.Position(0, 0);
41+
completionContext = {} as vscode.CompletionContext;
42+
token = new vscode.CancellationTokenSource().token;
43+
next = sandbox.stub();
44+
});
45+
46+
after(() => {
47+
sandbox.restore();
48+
});
49+
50+
it('should add command to completion items', async () => {
51+
const completionItems = [
52+
new vscode.CompletionItem('item1', vscode.CompletionItemKind.Property),
53+
new vscode.CompletionItem('item2', vscode.CompletionItemKind.Text),
54+
];
55+
completionItems[0].detail = 'Property';
56+
completionItems[1].detail = 'Text';
57+
next.returns(completionItems);
58+
59+
const result = await provideCompletionItemMiddleware.provideCompletionItem(document, position, context, token, next);
60+
61+
assert.ok(Array.isArray(result));
62+
assert.strictEqual(result.length, 2);
63+
assert.strictEqual(result[0].command?.command, 'editor.action.formatDocumentAndMoveCursor');
64+
assert.strictEqual(result[1].command?.command, 'editor.action.formatDocument');
65+
});
66+
});

0 commit comments

Comments
 (0)