Skip to content

Commit

Permalink
A HA Language!
Browse files Browse the repository at this point in the history
  • Loading branch information
keesschollaart81 committed Apr 21, 2019
1 parent 4f982a4 commit fbbd34a
Show file tree
Hide file tree
Showing 7 changed files with 897 additions and 181 deletions.
25 changes: 19 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
"description": " Completion for entity-id's in Home Assistant Configurations",
"version": "0.3.7",
"preview": true,
"extensionDependencies": [
"redhat.vscode-yaml"
],
"engines": {
"vscode": "^1.32.0"
},
Expand Down Expand Up @@ -77,10 +74,26 @@
"path": "./snippets/homeassistant_sensor.json"
}
],
"yamlValidation": [
"languages": [
{
"fileMatch": "ui-lovelace.yaml",
"url": "./src/lovelace-schema/ui-lovelace.json"
"id": "home-assistant",
"configuration": "./yaml-language/language-configuration.json",
"filenamePatterns": [
"ui-lovelace.yml",
"ui-lovelace.yaml",
"configuration.yml",
"configuration.yaml"
],
"aliases": [
"Home Assistant"
]
}
],
"grammars": [
{
"language": "yaml",
"scopeName": "source.yaml",
"path": "./yaml-language/yaml.tmLanguage.json"
}
]
},
Expand Down
11 changes: 6 additions & 5 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import { Config } from './configuration';
import { ServiceCompletionProvider } from './service-completion-provider';

const documentSelector = [
{ language: 'yaml', scheme: 'file' },
{ language: 'yaml', scheme: 'untitled' }
{ language: 'home-assistant', scheme: 'file' },
{ language: 'home-assistant', scheme: 'untitled' }
];

export function activate(context: vscode.ExtensionContext) {
Expand Down Expand Up @@ -56,9 +56,10 @@ export function activate(context: vscode.ExtensionContext) {
};

var client = new LanguageClient('home-assistant', 'Home Assistant Language Server', serverOptions, clientOptions);
client.onReady().then(() =>{
client.onRequest('ha/openTextDocument', vscode.workspace.openTextDocument);
})

// is this really needed?
vscode.languages.setLanguageConfiguration('home-assistant', { wordPattern: /("(?:[^\\\"]*(?:\\.)?)*"?)|[^\s{}\[\],:]+/ });

context.subscriptions.push(client.start());
}

Expand Down
174 changes: 106 additions & 68 deletions src/server/server.ts
Original file line number Diff line number Diff line change
@@ -1,81 +1,119 @@
import { createConnection, TextDocuments, ProposedFeatures, TextDocumentSyncKind, RequestType} from 'vscode-languageserver';
import { getLanguageService } from './yamlLanguageService';
import * as path from 'path';
import { parse as parseYAML } from 'yaml-language-server/out/server/src/languageservice/parser/yamlParser';
// import * as vscode from 'vscode';
import { NestedYamlParser, VsCodeFileAccessor } from './yamlDiscovery';
import * as path from "path";
import { parse as parseYAML } from "yaml-language-server/out/server/src/languageservice/parser/yamlParser";
import { YAMLValidation } from "yaml-language-server/out/server/src/languageservice/services/yamlValidation";
import { JSONSchemaService } from "yaml-language-server/out/server/src/languageservice/services/jsonSchemaService";
import {
createConnection,
TextDocuments,
ProposedFeatures
} from "vscode-languageserver";

import {
NestedYamlParser,
VsCodeFileAccessor,
SchemaServiceForIncludes,
Includetype
} from "./yamlDiscovery";

let connection = createConnection(ProposedFeatures.all);
let documents = new TextDocuments();
let workspaceFolder: string | null;
let parser: NestedYamlParser | null;
let schemaServiceForIncludes: SchemaServiceForIncludes | null;
let yamlvalidation: YAMLValidation | null;

documents.listen(connection);

connection.onInitialize((params) => {
workspaceFolder = params.rootUri;
connection.console.log(`[Server(${process.pid}) ${workspaceFolder}] Started and initialize received`);
return {
capabilities: {
textDocumentSync: {
openClose: true,
change: documents.syncKind
}
}
};
});

let workspaceContext = {

connection.onInitialize(params => {
workspaceFolder = params.rootUri;

var vsCodeFileAccessor = new VsCodeFileAccessor(workspaceFolder, connection);
parser = new NestedYamlParser(vsCodeFileAccessor);

let workspaceContext = {
resolveRelativePath: (relativePath: string, resource: string) => {
return path.resolve(resource, relativePath);
return path.resolve(resource, relativePath);
}
};
};

let jsonSchemaService = new JSONSchemaService(null, workspaceContext, null);
schemaServiceForIncludes = new SchemaServiceForIncludes(jsonSchemaService);

export let languageService = getLanguageService(
workspaceContext,
{
validation: true
}
);
documents.onDidChangeContent(async (textDocumentChangeEvent) =>{
if (!textDocumentChangeEvent.document) {
return;
}
yamlvalidation = new YAMLValidation(jsonSchemaService);
yamlvalidation.configure({
validate: true
});

if (textDocumentChangeEvent.document.getText().length === 0) {
return;
connection.console.log(
`[Server(${
process.pid
}) ${workspaceFolder}] Started and initialize received`
);
return {
capabilities: {
textDocumentSync: {
openClose: true,
change: documents.syncKind
}
}


var vsCodeFileAccessor = new VsCodeFileAccessor(workspaceFolder,connection);
var parser = new NestedYamlParser(vsCodeFileAccessor);
var parseResult = await parser.parse([
path.join(workspaceFolder,"configuration.yaml"),
path.join(workspaceFolder,"ui-lovelace.yaml")
]);

let yamlDocument = parseYAML(textDocumentChangeEvent.document.getText(), []);
if (!yamlDocument) {
return;
}
languageService.doValidation(textDocumentChangeEvent.document, yamlDocument).then((diagnosticResults) => {

if (!diagnosticResults) {
return;
}
let diagnostics = [];
for (let diagnosticItem in diagnosticResults) {
diagnosticResults[diagnosticItem].severity = 1; //Convert all warnings to errors
diagnostics.push(diagnosticResults[diagnosticItem]);
}
connection.sendDiagnostics({ uri: textDocumentChangeEvent.document.uri, diagnostics: diagnostics });
}, (error) => {
connection.window.showErrorMessage(`oops: ${error}`);
});
})

documents.onDidOpen((event) => {
connection.console.log(`[Server(${process.pid}) ${workspaceFolder}] Document opened: ${event.document.uri}`);
});
};
});

documents.onDidChangeContent(async textDocumentChangeEvent => {
if (!textDocumentChangeEvent.document) {
return;
}

var parseResult = await parser.parse([
path.join(workspaceFolder, "configuration.yaml"),
path.join(workspaceFolder, "ui-lovelace.yaml")
]);

schemaServiceForIncludes.onUpdate(parseResult.filePathMappings);

if (textDocumentChangeEvent.document.getText().length === 0) {
return;
}

let yamlDocument = parseYAML(textDocumentChangeEvent.document.getText(), getValidYamlTags());
if (!yamlDocument) {
return;
}
var diagnosticResults = await yamlvalidation.doValidation(
textDocumentChangeEvent.document,
yamlDocument
);

if (!diagnosticResults) {
return;
}
let diagnostics = [];
for (let diagnosticItem in diagnosticResults) {
diagnosticResults[diagnosticItem].severity = 1; //Convert all warnings to errors
diagnostics.push(diagnosticResults[diagnosticItem]);
}
connection.sendDiagnostics({
uri: textDocumentChangeEvent.document.uri,
diagnostics: diagnostics
});
});

documents.onDidOpen(event => {
connection.console.log(
`[Server(${process.pid}) ${workspaceFolder}] Document opened: ${
event.document.uri
}`
);
});

function getValidYamlTags() : string[] {
var validTags: string[] = [];
for (let item in Includetype) {
if (isNaN(Number(item))) {
validTags.push(`!${item} scalar`);
}
}
validTags.push("!secret scalar");
return validTags;
}
connection.listen();

Loading

0 comments on commit fbbd34a

Please sign in to comment.