Skip to content

Commit

Permalink
Merge pull request #37 from lifeart/ember-cli-runner
Browse files Browse the repository at this point in the history
ability to run ember-cli command
  • Loading branch information
lifeart authored Dec 19, 2019
2 parents e5266d7 + a0aaa01 commit 22dea04
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 13 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@ All features currently only work in Ember CLI application that use the default c

* [els-a11y-addon](https://github.com/lifeart/els-a11y-addon) - Ember Language Server a11y addon.
* [els-addon-typed-templates](https://github.com/lifeart/els-addon-typed-templates) - Typed Templates for Ember.
* [els-addon-docs](https://github.com/lifeart/els-addon-docs) - Ember Language Server Addon Docs Completion Provider.
* [els-addon-docs](https://github.com/lifeart/els-addon-docs) - Ember Language Server Addon Docs Completion Provider.
* [ember-fast-cli](https://github.com/lifeart/ember-fast-cli) - Addon for Ember-cli commands execution.
18 changes: 16 additions & 2 deletions src/project-roots.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,27 @@ import { logError, logInfo } from './utils/logger';
import * as walkSync from 'walk-sync';
import { isGlimmerNativeProject, isGlimmerXProject } from './utils/layout-helpers';
import { ProjectProviders, collectProjectProviders, initBuiltinProviders } from './utils/addon-api';
import Server from './server';

export interface Executors {
[key: string]: (server: Server, command: string, args: any[]) => any;
}

export class Project {
providers!: ProjectProviders;
builtinProviders!: ProjectProviders;
executors: Executors = {};
constructor(public readonly root: string) {
this.providers = collectProjectProviders(root);
this.builtinProviders = initBuiltinProviders();
}
init(server: Server) {
this.providers.initFunctions.forEach((initFn) => initFn(server, this));
}
}

export default class ProjectRoots {
constructor(private server: Server) {}
workspaceRoot: string;

projects = new Map<string, Project>();
Expand Down Expand Up @@ -56,7 +66,9 @@ export default class ProjectRoots {
return;
}
try {
this.projects.set(path, new Project(path));
const project = new Project(path);
this.projects.set(path, project);
project.init(this.server);
logInfo(`Ember CLI project added at ${path}`);
} catch (e) {
logError(e);
Expand All @@ -67,9 +79,11 @@ export default class ProjectRoots {
let path = uriToFilePath(uri);

if (!path) return;
return this.projectForPath(path);
}

projectForPath(path: string): Project | undefined {
let root = (Array.from(this.projects.keys()) || []).filter((root) => path!.indexOf(root) === 0).reduce((a, b) => (a.length > b.length ? a : b), '');

return this.projects.get(root);
}
}
37 changes: 30 additions & 7 deletions src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ import {
Location
} from 'vscode-languageserver';

import ProjectRoots from './project-roots';
import ProjectRoots, { Executors } from './project-roots';
import DefinitionProvider from './definition-providers/entry';
import TemplateLinter from './template-linter';
import DocumentSymbolProvider from './symbols/document-symbol-provider';
import JSDocumentSymbolProvider from './symbols/js-document-symbol-provider';
import HBSDocumentSymbolProvider from './symbols/hbs-document-symbol-provider';
import { ReferenceProvider } from './reference-provider/entry';
import { log, setConsole, logError } from './utils/logger';
import { log, setConsole, logError, logInfo } from './utils/logger';
import TemplateCompletionProvider from './completion-provider/template-completion-provider';
import ScriptCompletionProvider from './completion-provider/script-completion-provider';
import { uriToFilePath } from 'vscode-languageserver/lib/files';
Expand All @@ -50,7 +50,7 @@ export default class Server {
// supports full document sync only
documents: TextDocuments = new TextDocuments();

projectRoots: ProjectRoots = new ProjectRoots();
projectRoots: ProjectRoots = new ProjectRoots(this);
addToRegistry(normalizedName: string, kind: REGISTRY_KIND, fullPath: string | string[]) {
let rawPaths = Array.isArray(fullPath) ? fullPath : [fullPath];
let purePaths = rawPaths.filter((p) => path.isAbsolute(p));
Expand Down Expand Up @@ -112,6 +112,7 @@ export default class Server {
this.connection.onExecuteCommand(this.onExecute.bind(this));
this.connection.onReferences(this.onReference.bind(this));
this.connection.telemetry.logEvent({ connected: true });

// this.displayInfoMessage('Ember Language Server [activated]');
// 'els.showStatusBarText'

Expand Down Expand Up @@ -139,9 +140,30 @@ export default class Server {
this.connection.sendNotification('$/displayError', msg);
}

onExecute(params: string[]) {
if (params[0] === 'els:registerProjectPath') {
this.projectRoots.onProjectAdd(params[1]);
async onExecute(params: string[] | any) {
if (Array.isArray(params)) {
if (params[0] === 'els:registerProjectPath') {
this.projectRoots.onProjectAdd(params[1]);
}
} else {
if (params.command in this.executors) {
return this.executors[params.command](this, params.command, params.arguments);
} else {
let [uri, ...args] = params.arguments;
logInfo(JSON.stringify(params));
try {
const project = this.projectRoots.projectForPath(uri);
let result = null;
if (project) {
if (params.command in project.executors) {
result = project.executors[params.command](this, params.command, args);
}
}
return result;
} catch (e) {
logError(e);
}
}
}
return params;
}
Expand Down Expand Up @@ -179,7 +201,7 @@ export default class Server {
textDocumentSync: this.documents.syncKind,
definitionProvider: true,
executeCommandProvider: {
commands: ['els:registerProjectPath']
commands: ['els:registerProjectPath', 'els.executeInEmberCLI']
},
documentSymbolProvider: true,
referencesProvider: true,
Expand All @@ -192,6 +214,7 @@ export default class Server {
}

linters: any[] = [];
executors: Executors = {};

private async onDidChangeContent(change: any) {
// this.setStatusText('did-change');
Expand Down
24 changes: 21 additions & 3 deletions src/utils/addon-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import { log, logInfo, logError } from './logger';
import Server from '../server';
import ASTPath from './../glimmer-utils';
import DAGMap from 'dag-map';

import CoreScriptDefinitionProvider from './../builtin-addons/core/script-definition-provider';
import CoreTemplateDefinitionProvider from './../builtin-addons/core/template-definition-provider';
import ScriptCompletionProvider from './../builtin-addons/core/script-completion-provider';
import TemplateCompletionProvider from './../builtin-addons/core/template-completion-provider';
import { Project } from '../project-roots';

const ADDON_CONFIG_KEY = 'ember-language-server';
interface BaseAPIParams {
Expand All @@ -34,16 +34,19 @@ export interface DefinitionFunctionParams extends ExtendedAPIParams {
type ReferenceResolveFunction = (root: string, params: ReferenceFunctionParams) => Promise<Location[]>;
type CompletionResolveFunction = (root: string, params: CompletionFunctionParams) => Promise<CompletionItem[]>;
type DefinitionResolveFunction = (root: string, params: DefinitionFunctionParams) => Promise<Location[]>;
type InitFunction = (server: Server, project: Project) => any;
export interface AddonAPI {
onReference: undefined | ReferenceResolveFunction;
onComplete: undefined | CompletionResolveFunction;
onDefinition: undefined | DefinitionResolveFunction;
onInit: undefined | InitFunction;
}

interface PublicAddonAPI {
onReference?: ReferenceResolveFunction;
onComplete?: CompletionResolveFunction;
onDefinition?: DefinitionResolveFunction;
onInit?: InitFunction;
}
interface HandlerObject {
handler: PublicAddonAPI;
Expand Down Expand Up @@ -79,6 +82,7 @@ export function initBuiltinProviders(): ProjectProviders {
return {
definitionProviders: [scriptDefinition.onDefinition.bind(scriptDefinition), templateDefinition.onDefinition.bind(templateDefinition)],
referencesProviders: [],
initFunctions: [],
completionProviders: [scriptCompletion.onComplete.bind(scriptCompletion), templateCompletion.onComplete.bind(templateCompletion)]
};
}
Expand Down Expand Up @@ -122,10 +126,12 @@ export function collectProjectProviders(root: string): ProjectProviders {
definitionProviders: DefinitionResolveFunction[];
referencesProviders: ReferenceResolveFunction[];
completionProviders: CompletionResolveFunction[];
initFunctions: InitFunction[];
} = {
definitionProviders: [],
referencesProviders: [],
completionProviders: []
completionProviders: [],
initFunctions: []
};

// onReference, onComplete, onDefinition
Expand Down Expand Up @@ -162,6 +168,14 @@ export function collectProjectProviders(root: string): ProjectProviders {
return params.results;
}
} as DefinitionResolveFunction);
result.initFunctions.push(function(server: Server, project: Project) {
handlerObject.updateHandler();
if (typeof handlerObject.handler.onInit === 'function') {
return handlerObject.handler.onInit(server, project);
} else {
return;
}
} as InitFunction);
} else {
if (handlerObject.capabilities.completionProvider && typeof handlerObject.handler.onComplete === 'function') {
result.completionProviders.push(handlerObject.handler.onComplete);
Expand All @@ -172,6 +186,9 @@ export function collectProjectProviders(root: string): ProjectProviders {
if (handlerObject.capabilities.definitionProvider && typeof handlerObject.handler.onDefinition === 'function') {
result.definitionProviders.push(handlerObject.handler.onDefinition);
}
if (typeof handlerObject.handler.onInit === 'function') {
result.initFunctions.push(handlerObject.handler.onInit);
}
}
});

Expand All @@ -182,6 +199,7 @@ export interface ProjectProviders {
definitionProviders: DefinitionResolveFunction[];
referencesProviders: ReferenceResolveFunction[];
completionProviders: CompletionResolveFunction[];
initFunctions: InitFunction[];
}

interface ExtensionCapabilities {
Expand Down Expand Up @@ -210,7 +228,7 @@ function normalizeCapabilities(raw: ExtensionCapabilities): NormalizedCapabiliti
}

export function extensionCapabilities(info: any): ExtensionCapabilities {
return info[ADDON_CONFIG_KEY].capabilities;
return info[ADDON_CONFIG_KEY].capabilities || {};
}
export function languageServerHandler(info: any): string {
return info[ADDON_CONFIG_KEY].entry;
Expand Down
1 change: 1 addition & 0 deletions test/__snapshots__/integration-test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2678,6 +2678,7 @@ Object {
"executeCommandProvider": Object {
"commands": Array [
"els:registerProjectPath",
"els.executeInEmberCLI",
],
},
"referencesProvider": true,
Expand Down

0 comments on commit 22dea04

Please sign in to comment.