Skip to content

Commit

Permalink
feat: add multi-root workspaces support Closes #33
Browse files Browse the repository at this point in the history
other changes:
- remove server code & switch to gql-language-server
  • Loading branch information
Mayank1791989 committed Jul 4, 2019
1 parent 7ad1202 commit af8fe1d
Show file tree
Hide file tree
Showing 13 changed files with 1,048 additions and 4,171 deletions.
4 changes: 3 additions & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
{
"bracketSpacing": true,
"jsxBracketSameLine": false,
"printWidth": 80,
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "all",
"useTabs": false
"useTabs": false,
"parser": "typescript"
}
81 changes: 59 additions & 22 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"url": "https://github.com/kumarharsh"
},
"keywords": [
"multi-root ready",
"graphql",
"linter",
"ide",
Expand Down Expand Up @@ -44,7 +45,7 @@
"activationEvents": [
"workspaceContains:.gqlconfig"
],
"main": "./out/client/extension",
"main": "./out/extension",
"badges": [
{
"url": "https://img.shields.io/badge/%20%20%F0%9F%9A%80-semantic--release-e10079.svg",
Expand All @@ -58,20 +59,60 @@
"title": "Graphql Configuration",
"properties": {
"graphqlForVSCode.nodePath": {
"type": [
"string",
"null"
"scope": "resource",
"type": "string",
"description": "A path used for resolving the @playlyfe/gql module. (default: workspaceFolder)",
"default": "."
},
"graphqlForVSCode.loglevel": {
"scope": "resource",
"type": "string",
"default": "info",
"enum": [
"debug",
"info",
"error",
"off"
],
"default": null,
"description": "A path added to NODE_PATH when resolving the @playlyfe/gql module."
"description": "log level."
},
"graphqlForVSCode.debug": {
"type": [
"boolean",
"null"
"graphqlForVSCode.trace.server": {
"scope": "window",
"anyOf": [
{
"type": "string",
"enum": [
"off",
"messages",
"verbose"
],
"default": "off"
},
{
"type": "object",
"properties": {
"verbosity": {
"type": "string",
"enum": [
"off",
"messages",
"verbose"
],
"default": "off"
},
"format": {
"type": "string",
"enum": [
"text",
"json"
],
"default": "text"
}
}
}
],
"default": false,
"description": "enable debug logs."
"default": "off",
"description": "Traces the communication between VSCode and the gql language server."
}
}
},
Expand Down Expand Up @@ -165,14 +206,12 @@
]
},
"scripts": {
"vscode:prepublish": "yarn install && yarn clean && yarn compile-server && yarn compile",
"vscode:prepublish": "yarn install && yarn clean && yarn compile",
"postinstall": "node ./node_modules/vscode/bin/install",
"clean": "rimraf out",
"compile-server": "yarn install && tsc -p src/server",
"compile": "yarn install && tsc -p src/client",
"watch-server": "tsc -watch -p src/server",
"watch": "tsc -watch -p src/client",
"dev": "yarn clean && yarn compile-server && yarn watch",
"compile": "yarn install && tsc -p src",
"watch": "tsc -watch -p src",
"dev": "yarn clean && yarn watch",
"package": "yarn install && vsce package"
},
"devDependencies": {
Expand All @@ -196,10 +235,8 @@
"vscode": "^1.1.34"
},
"dependencies": {
"semver": "^6.0.0",
"vscode-languageclient": "^5.2.1",
"vscode-languageserver": "^5.2.1",
"vscode-uri": "^2.0.1"
"@playlyfe/gql-language-server": "0.1.0",
"vscode-languageclient": "^5.2.1"
},
"galleryBanner": {
"color": "#2e2348",
Expand Down
152 changes: 152 additions & 0 deletions src/ClientStatusBarItem.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
'use strict';

import {
commands,
languages,
StatusBarAlignment,
StatusBarItem,
TextDocument,
TextEditor,
ThemeColor,
window,
workspace,
} from 'vscode';

import { LanguageClient, State } from 'vscode-languageclient';

enum Status {
init = 1,
ok = 2,
error = 3,
}

interface IStatusBarItemConfig {
icon: string;
tooltip: string;
color: string;
}

const STATUS_BAR_ITEM_NAME = 'GQL';
const STATUS_BAR_UI = {
[Status.init]: {
icon: 'sync',
color: 'progressBar.background',
tooltip: 'Graphql language server is initializing.',
},
[Status.ok]: {
icon: 'plug',
color: 'statusBar.foreground',
tooltip: 'Graphql language server is running.',
},
[Status.error]: {
icon: 'stop',
color: 'editorError.foreground',
tooltip: 'Graphql language server is not running.',
},
};
export default class ClientStatusBarItem {
private _item: StatusBarItem;
private _client: LanguageClient;
private _disposables: Array<{ dispose: () => any }> = [];

constructor(client: LanguageClient) {
this._item = window.createStatusBarItem(StatusBarAlignment.Right, 0);
this._client = client;

this._disposables.push(this._item);
this._disposables.push(this._addOnClickToShowOutputChannel());

// update status bar depending on client state
this._setStatus(Status.init);
this._registerStatusChangeListeners();

// update visibility of statusBarItem depending on current activeTextEditor
this._updateVisibility(window.activeTextEditor);
window.onDidChangeActiveTextEditor(this._updateVisibility);
}

public dispose() {
this._disposables.forEach(item => {
item.dispose();
});
this._item = null;
this._client = null;
}

private _registerStatusChangeListeners() {
this._client.onDidChangeState(({ oldState, newState }) => {
if (newState === State.Running) {
this._setStatus(Status.ok);
} else if (newState === State.Stopped) {
this._setStatus(Status.error);
}
});

this._client.onReady().then(
() => {
this._setStatus(Status.ok);
},
() => {
this._setStatus(Status.error);
},
);
}

private _addOnClickToShowOutputChannel() {
const commandName = `showOutputChannel-${this._client.outputChannel.name}`;
const disposable = commands.registerCommand(commandName, () => {
this._client.outputChannel.show();
});
this._item.command = commandName;
return disposable;
}

private _updateVisibility = (textEditor: TextEditor) => {
let hide = true;

if (textEditor && this._checkDocumentInsideWorkspace(textEditor.document)) {
if (this._client.initializeResult) {
// if client is initialized then show only for file extensions
// defined in .gqlconfig
// @TODO: if possible, match against patterns defined in .gqlconfig
// instead of extensions.
const extensions = this._client.initializeResult.fileExtensions;
const score = languages.match(
{ scheme: 'file', pattern: `**/*.{${extensions.join(',')}}` },
textEditor.document,
);
hide = score === 0;
} else {
// while server is initializing show status bar item
// for all files inside worspace
hide = false;
}
}

hide ? this._hide() : this._show();
};

private _checkDocumentInsideWorkspace(document: TextDocument): boolean {
const folder = workspace.getWorkspaceFolder(document.uri);
return folder && folder.uri.toString() === this._getWorkspace();
}

private _getWorkspace(): string {
return this._client.clientOptions.workspaceFolder.uri.toString();
}

private _show() {
this._item.show();
}

private _hide() {
this._item.hide();
}

private _setStatus(status: Status) {
const ui: IStatusBarItemConfig = STATUS_BAR_UI[status];
this._item.text = `$(${ui.icon}) ${STATUS_BAR_ITEM_NAME}`;
this._item.tooltip = ui.tooltip;
this._item.color = new ThemeColor(ui.color);
}
}
Loading

0 comments on commit af8fe1d

Please sign in to comment.