Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement CSS triggerPropertyValueCompletion setting #149

Merged
merged 4 commits into from
Mar 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/cssLanguageService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ export interface LanguageService {

function createFacade(parser: Parser, completion: CSSCompletion, hover: CSSHover, navigation: CSSNavigation, codeActions: CSSCodeActions, validation: CSSValidation) {
return {
configure: validation.configure.bind(validation),
configure: (settings) => {
validation.configure(settings);
completion.configure(settings);
},
doValidation: validation.doValidation.bind(validation),
parseStylesheet: parser.parseStylesheet.bind(parser),
doComplete: completion.doComplete.bind(completion),
Expand Down
5 changes: 5 additions & 0 deletions src/cssLanguageTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,14 @@ export interface SelectionRange {

export type LintSettings = { [key: string]: any };

export interface CompletionSettings {
triggerPropertyValueCompletion: boolean;
}

export interface LanguageSettings {
validate?: boolean;
lint?: LintSettings;
completion?: CompletionSettings;
}

export interface PropertyCompletionContext {
Expand Down
22 changes: 20 additions & 2 deletions src/services/cssCompletion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ import { Symbols, Symbol } from '../parser/cssSymbolScope';
import * as languageFacts from '../languageFacts/facts';
import * as strings from '../utils/strings';
import { TextDocument, Position, CompletionList, CompletionItem, CompletionItemKind, Range, TextEdit, InsertTextFormat } from 'vscode-languageserver-types';
import { ICompletionParticipant } from '../cssLanguageTypes';
import { ICompletionParticipant, LanguageSettings } from '../cssLanguageTypes';

import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
const SnippetFormat = InsertTextFormat.Snippet;

export class CSSCompletion {

private settings: LanguageSettings;

variablePrefix: string;
position: Position;
offset: number;
Expand All @@ -32,6 +34,10 @@ export class CSSCompletion {
this.variablePrefix = variablePrefix;
}

public configure(settings: LanguageSettings) {
this.settings = settings;
}

protected getSymbolContext(): Symbols {
if (!this.symbolContext) {
this.symbolContext = new Symbols(this.styleSheet);
Expand Down Expand Up @@ -156,6 +162,7 @@ export class CSSCompletion {
}

private getPropertyProposals(declaration: nodes.Declaration, result: CompletionList): CompletionList {
const triggerPropertyValueCompletion = this.isTriggerPropertyValueCompletionEnabled;
const properties = languageFacts.cssDataManager.getProperties();

properties.forEach(entry => {
Expand Down Expand Up @@ -183,7 +190,7 @@ export class CSSCompletion {
if (!entry.restrictions) {
retrigger = false;
}
if (retrigger) {
if (triggerPropertyValueCompletion && retrigger) {
item.command = {
title: 'Suggest',
command: 'editor.action.triggerSuggest'
Expand All @@ -206,6 +213,17 @@ export class CSSCompletion {
return result;
}

private get isTriggerPropertyValueCompletionEnabled(): boolean {
if (
!this.settings ||
!this.settings.completion ||
this.settings.completion.triggerPropertyValueCompletion === undefined
) {
return true;
}
return this.settings.completion.triggerPropertyValueCompletion;
}

private valueTypes = [
nodes.NodeType.Identifier, nodes.NodeType.Value, nodes.NodeType.StringLiteral, nodes.NodeType.URILiteral, nodes.NodeType.NumericValue,
nodes.NodeType.HexColorValue, nodes.NodeType.VariableName, nodes.NodeType.Prio
Expand Down
36 changes: 34 additions & 2 deletions src/test/css/completion.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
import * as assert from 'assert';
import * as cssLanguageService from '../../cssLanguageService';

import { CompletionList, TextDocument, Position, CompletionItemKind, InsertTextFormat, Range } from 'vscode-languageserver-types';
import { CompletionList, TextDocument, Position, CompletionItemKind, InsertTextFormat, Range, Command } from 'vscode-languageserver-types';
import { LanguageSettings } from '../../cssLanguageTypes';

export interface ItemDescription {
label: string;
Expand All @@ -17,6 +18,7 @@ export interface ItemDescription {
insertTextFormat?: InsertTextFormat;
resultText?: string;
notAvailable?: boolean;
command?: Command;
}

function asPromise<T>(result: T): Promise<T> {
Expand Down Expand Up @@ -49,11 +51,14 @@ export let assertCompletion = function (completions: CompletionList, expected: I
if (expected.insertTextFormat) {
assert.equal(match.insertTextFormat, expected.insertTextFormat);
}
if (expected.command) {
assert.deepEqual(match.command, expected.command);
}
};

suite('CSS - Completion', () => {

let testCompletionFor = function (value: string, expected: { count?: number, items?: ItemDescription[], participant?: { onProperty?, onPropertValue?, onURILiteralValue?, onImportPath? } }) {
let testCompletionFor = function (value: string, expected: { count?: number, items?: ItemDescription[], participant?: { onProperty?, onPropertValue?, onURILiteralValue?, onImportPath? } }, settings?: LanguageSettings) {
let offset = value.indexOf('|');
value = value.substr(0, offset) + value.substr(offset + 1);

Expand All @@ -63,6 +68,8 @@ suite('CSS - Completion', () => {
let actualImportPathContexts: { pathValue: string; position: Position; range: Range; }[] = [];

let ls = cssLanguageService.getCSSLanguageService();
ls.configure(settings);

if (expected.participant) {
ls.setCompletionParticipants([{
onCssProperty: context => actualPropertyContexts.push(context),
Expand Down Expand Up @@ -505,6 +512,31 @@ suite('CSS - Completion', () => {
{ label: 'none' }
]
});
testCompletionFor('body { disp| ', {
items: [
{ label: 'display', resultText: 'body { display: ', command: { title: 'Suggest', command: 'editor.action.triggerSuggest' } }
]
});
testCompletionFor('body { disp| ', {
items: [
{ label: 'display', resultText: 'body { display: ', command: { title: 'Suggest', command: 'editor.action.triggerSuggest' } }
]
}, {});
testCompletionFor('body { disp| ', {
items: [
{ label: 'display', resultText: 'body { display: ', command: { title: 'Suggest', command: 'editor.action.triggerSuggest' } }
]
}, { completion: undefined });
testCompletionFor('body { disp| ', {
items: [
{ label: 'display', resultText: 'body { display: ', command: { title: 'Suggest', command: 'editor.action.triggerSuggest' } }
]
}, { completion: { triggerPropertyValueCompletion: true } });
testCompletionFor('body { disp| ', {
items: [
{ label: 'display', resultText: 'body { display: ', command: undefined }
]
}, { completion: { triggerPropertyValueCompletion: false } });
});

test('Completion description should include status and browser compat', () => {
Expand Down