Skip to content

Commit

Permalink
Handles modification of autoCloseTags from the server side.
Browse files Browse the repository at this point in the history
Signed-off-by: Nikolas Komonen <[email protected]>
  • Loading branch information
NikolasKomonen authored and fbricon committed Mar 13, 2019
1 parent 7aaa9b0 commit e1f7438
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 17 deletions.
15 changes: 8 additions & 7 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,20 @@
*/

import { prepareExecutable } from './javaServerStarter';
import { LanguageClientOptions, RevealOutputChannelOn, LanguageClient, DidChangeConfigurationNotification, RequestType, TextDocumentPositionParams } from 'vscode-languageclient';
import { LanguageClientOptions, RevealOutputChannelOn, LanguageClient, DidChangeConfigurationNotification, RequestType, TextDocumentPositionParams, RequestType0 } from 'vscode-languageclient';
import * as requirements from './requirements';
import { languages, IndentAction, workspace, window, commands, ExtensionContext, TextDocument, Position, LanguageConfiguration } from "vscode";
import * as path from 'path';
import * as os from 'os';
import { activateTagClosing } from './tagClosing';
import { activateTagClosing, AutoCloseResult } from './tagClosing';

export interface ScopeInfo {
scope : "default" | "global" | "workspace" | "folder";
configurationTarget: boolean;
}

namespace TagCloseRequest {
export const type: RequestType<TextDocumentPositionParams, string, any, any> = new RequestType('xml/closeTag');
export const type: RequestType<TextDocumentPositionParams, AutoCloseResult, any, any> = new RequestType('xml/closeTag');
}

let ignoreAutoCloseTags = false;
Expand Down Expand Up @@ -81,13 +81,14 @@ export function activate(context: ExtensionContext) {
let disposable = languageClient.start();
toDispose.push(disposable);
languageClient.onReady().then(() => {
//init
let tagRequestor = (document: TextDocument, position: Position) => {
//Setup autoCloseTags
let tagProvider = (document: TextDocument, position: Position) => {
let param = languageClient.code2ProtocolConverter.asTextDocumentPositionParams(document, position);
return languageClient.sendRequest(TagCloseRequest.type, param);
let text = languageClient.sendRequest(TagCloseRequest.type, param);
return text;
};

disposable = activateTagClosing(tagRequestor, { xml: true, xsl: true }, 'xml.completion.autoCloseTags');
disposable = activateTagClosing(tagProvider, { xml: true, xsl: true }, 'xml.completion.autoCloseTags');
toDispose.push(disposable);
});
languages.setLanguageConfiguration('xml', getIndentationRules());
Expand Down
37 changes: 27 additions & 10 deletions src/tagClosing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,15 @@
*--------------------------------------------------------------------------------------------*/
'use strict';

import { window, workspace, Disposable, TextDocumentContentChangeEvent, TextDocument, Position, SnippetString } from 'vscode';
import { window, workspace, Disposable, TextDocumentContentChangeEvent, TextDocument, Position, SnippetString, Range } from 'vscode';

export function activateTagClosing(tagProvider: (document: TextDocument, position: Position) => Thenable<string>, supportedLanguages: { [id: string]: boolean }, configName: string): Disposable {
export interface AutoCloseResult {
snippet: string,
range?: Range
}

export function activateTagClosing(tagProvider: (document: TextDocument, position: Position) => Thenable<AutoCloseResult>, supportedLanguages: { [id: string]: boolean }, configName: string): Disposable {
const TRIGGER_CHARACTERS = ['>', '/'];
let disposables: Disposable[] = [];
workspace.onDidChangeTextDocument(event => onDidChangeTextDocument(event.document, event.contentChanges), null, disposables);

Expand Down Expand Up @@ -50,25 +55,37 @@ export function activateTagClosing(tagProvider: (document: TextDocument, positio
}
let lastChange = changes[changes.length - 1];
let lastCharacter = lastChange.text[lastChange.text.length - 1];
if (lastChange.rangeLength > 0 || lastCharacter !== '>' && lastCharacter !== '/') {
if (lastChange.rangeLength > 0 || lastChange.text.length > 1 || lastCharacter in TRIGGER_CHARACTERS) {
return;
}
let rangeStart = lastChange.range.start;
let version = document.version;
timeout = setTimeout(() => {
let position = new Position(rangeStart.line, rangeStart.character + lastChange.text.length);
tagProvider(document, position).then(text => {
tagProvider(document, position).then(result => {
let text = result.snippet;
let replaceLocation : Position | Range;
let range : Range = result.range;
if(range != null) {
// re-create Range
let line = range.start.line;
let character = range.start.character;
let startPosition = new Position(line, character);
line = range.end.line;
character = range.end.character;
let endPosition = new Position(line, character);
replaceLocation = new Range(startPosition, endPosition);
}
else {
replaceLocation = position;
}
if (text && isEnabled) {
let activeEditor = window.activeTextEditor;
if (activeEditor) {
let activeDocument = activeEditor.document;
if (document === activeDocument && activeDocument.version === version) {
let selections = activeEditor.selections;
if (selections.length && selections.some(s => s.active.isEqual(position))) {
activeEditor.insertSnippet(new SnippetString(text), selections.map(s => s.active));
} else {
activeEditor.insertSnippet(new SnippetString(text), position);
}
activeEditor.insertSnippet(new SnippetString(text), replaceLocation);

}
}
}
Expand Down

0 comments on commit e1f7438

Please sign in to comment.