Skip to content

Commit 173fcf8

Browse files
authored
Merge pull request #117 from deankevorkian/commands-custom-callback
2 parents 2557ebb + d569a46 commit 173fcf8

File tree

4 files changed

+112
-4
lines changed

4 files changed

+112
-4
lines changed

lib/adapters/code-action-adapter.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
Range,
1616
TextEditor,
1717
} from 'atom';
18+
import CommandExecutionAdapter from './command-execution-adapter';
1819

1920
export default class CodeActionAdapter {
2021
/**
@@ -88,10 +89,7 @@ export default class CodeActionAdapter {
8889
connection: LanguageClientConnection,
8990
): Promise<void> {
9091
if (Command.is(command)) {
91-
await connection.executeCommand({
92-
command: command.command,
93-
arguments: command.arguments,
94-
});
92+
await CommandExecutionAdapter.executeCommand(connection, command.command, command.arguments);
9593
}
9694
}
9795

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { ExecuteCommandParams, ServerCapabilities } from "../languageclient";
2+
import { LanguageClientConnection } from "../main";
3+
4+
export type CommandCustomCallbackFunction = (command: ExecuteCommandParams) => Promise<any | void>;
5+
6+
export default class CommandExecutionAdapter {
7+
private static commandsCustomCallbacks = new Map<string, CommandCustomCallbackFunction>();
8+
9+
public static canAdapt(serverCapabilities: ServerCapabilities): boolean {
10+
return serverCapabilities.executeCommandProvider != null;
11+
}
12+
13+
public static registerCustomCallbackForCommand(command: string, callback: CommandCustomCallbackFunction): void {
14+
this.commandsCustomCallbacks.set(command, callback);
15+
}
16+
17+
public static async executeCommand(connection: LanguageClientConnection, command: string, commandArgs?: any[]): Promise<any | void> {
18+
const executeCommandParams = CommandExecutionAdapter.createExecuteCommandParams(command, commandArgs);
19+
const commandCustomCallback = this.commandsCustomCallbacks.get(command);
20+
21+
return commandCustomCallback !== undefined ? await commandCustomCallback(executeCommandParams) : await connection.executeCommand(executeCommandParams);
22+
}
23+
24+
private static createExecuteCommandParams(command: string, commandArgs?: any[]): ExecuteCommandParams {
25+
return {
26+
command: command,
27+
arguments: commandArgs
28+
};
29+
}
30+
}

lib/main.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import Convert from './convert';
88
import { Logger, ConsoleLogger, FilteredLogger } from './logger';
99
import DownloadFile from './download-file';
1010
import LinterPushV2Adapter from './adapters/linter-push-v2-adapter';
11+
import CommandExecutionAdapter from './adapters/command-execution-adapter';
1112

1213
export * from './auto-languageclient';
1314
export {
@@ -18,4 +19,5 @@ export {
1819
FilteredLogger,
1920
DownloadFile,
2021
LinterPushV2Adapter,
22+
CommandExecutionAdapter
2123
};
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { expect } from 'chai';
2+
import * as sinon from 'sinon';
3+
import * as ls from '../../lib/languageclient';
4+
import CommandExecutionAdapter, { CommandCustomCallbackFunction } from '../../lib/adapters/command-execution-adapter';
5+
import { createSpyConnection } from '../helpers.js';
6+
import { ExecuteCommandParams } from '../../lib/languageclient';
7+
8+
describe('CommandExecutionAdapter', () => {
9+
describe('canAdapt', () => {
10+
it('returns true if command execution is supported', () => {
11+
const result = CommandExecutionAdapter.canAdapt({
12+
executeCommandProvider: {commands: []},
13+
});
14+
expect(result).to.be.true;
15+
});
16+
17+
it('returns false it no formatting supported', () => {
18+
const result = CommandExecutionAdapter.canAdapt({});
19+
expect(result).to.be.false;
20+
});
21+
});
22+
23+
describe('executeCommand', () => {
24+
it('invokes an executeCommand object from given inputs', async () => {
25+
const connection = createSpyConnection();
26+
const languageClient = new ls.LanguageClientConnection(connection);
27+
const testCommand = {
28+
command: 'testCommand',
29+
arguments: ['a', 'b'],
30+
};
31+
sinon.stub(languageClient, 'executeCommand').returns(Promise.resolve(testCommand));
32+
33+
const result = await CommandExecutionAdapter.executeCommand(
34+
languageClient,
35+
testCommand.command,
36+
testCommand.arguments
37+
);
38+
39+
expect(result.command).to.equal(testCommand.command);
40+
expect(result.arguments).to.equal(testCommand.arguments);
41+
42+
expect((languageClient as any).executeCommand.called).to.be.true;
43+
expect((languageClient as any).executeCommand.getCalls()[0].args).to.deep.equal([{
44+
command: testCommand.command,
45+
arguments: testCommand.arguments
46+
} as ExecuteCommandParams]);
47+
});
48+
});
49+
50+
describe('registerCustomCallbackForCommand', () => {
51+
it('registers a custom callback for a command, to be executed on executeCommand', async () => {
52+
const connection = createSpyConnection();
53+
const languageClient = new ls.LanguageClientConnection(connection);
54+
const testCallback: CommandCustomCallbackFunction = (command: ExecuteCommandParams) => Promise.resolve(command.command);
55+
const testCommand = {
56+
command: 'testCommand',
57+
arguments: ['a', 'b'],
58+
};
59+
60+
const spiedCallback = sinon.spy(testCallback);
61+
sinon.spy(languageClient, 'executeCommand');
62+
63+
CommandExecutionAdapter.registerCustomCallbackForCommand(testCommand.command, spiedCallback);
64+
65+
const result = await CommandExecutionAdapter.executeCommand(
66+
languageClient,
67+
testCommand.command,
68+
testCommand.arguments
69+
);
70+
71+
expect(spiedCallback.called).to.be.true;
72+
73+
expect((languageClient as any).executeCommand.called).to.be.false;
74+
75+
expect(result).to.equal(testCommand.command);
76+
});
77+
});
78+
});

0 commit comments

Comments
 (0)