@import completion for css/scss/less. Fix #51331

This commit is contained in:
Pine Wu
2018-08-07 16:01:21 -07:00
parent 37199daa9f
commit a40bfc947c
8 changed files with 152 additions and 19 deletions

View File

@@ -12,7 +12,7 @@ import { TextDocument, CompletionList, CompletionItemKind, CompletionItem, TextE
import { WorkspaceFolder } from 'vscode-languageserver';
import { ICompletionParticipant } from 'vscode-css-languageservice';
import { startsWith } from './utils/strings';
import { startsWith, endsWith } from './utils/strings';
export function getPathCompletionParticipant(
document: TextDocument,
@@ -21,32 +21,73 @@ export function getPathCompletionParticipant(
): ICompletionParticipant {
return {
onCssURILiteralValue: ({ position, range, uriValue }) => {
const isValueQuoted = startsWith(uriValue, `'`) || startsWith(uriValue, `"`);
const fullValue = stripQuotes(uriValue);
const valueBeforeCursor = isValueQuoted
? fullValue.slice(0, position.character - (range.start.character + 1))
: fullValue.slice(0, position.character - range.start.character);
if (fullValue === '.' || fullValue === '..') {
result.isIncomplete = true;
if (!shouldDoPathCompletion(uriValue, workspaceFolders)) {
if (fullValue === '.' || fullValue === '..') {
result.isIncomplete = true;
}
return;
}
if (!workspaceFolders || workspaceFolders.length === 0) {
let suggestions = providePathSuggestions(uriValue, position, range, document, workspaceFolders);
result.items = [...suggestions, ...result.items];
},
onCssImportPath: ({ position, range, pathValue }) => {
const fullValue = stripQuotes(pathValue);
if (!shouldDoPathCompletion(pathValue, workspaceFolders)) {
if (fullValue === '.' || fullValue === '..') {
result.isIncomplete = true;
}
return;
}
const workspaceRoot = resolveWorkspaceRoot(document, workspaceFolders);
const paths = providePaths(valueBeforeCursor, URI.parse(document.uri).fsPath, workspaceRoot);
const fullValueRange = isValueQuoted ? shiftRange(range, 1, -1) : range;
const replaceRange = pathToReplaceRange(valueBeforeCursor, fullValue, fullValueRange);
const suggestions = paths.map(p => pathToSuggestion(p, replaceRange));
let suggestions = providePathSuggestions(pathValue, position, range, document, workspaceFolders);
if (document.languageId === 'scss') {
suggestions.forEach(s => {
if (startsWith(s.label, '_') && endsWith(s.label, '.scss')) {
if (s.textEdit) {
s.textEdit.newText = s.label.slice(1, -5);
} else {
s.label = s.label.slice(1, -5);
}
}
});
}
result.items = [...suggestions, ...result.items];
}
};
}
function providePathSuggestions(pathValue: string, position: Position, range: Range, document: TextDocument, workspaceFolders: WorkspaceFolder[]) {
const fullValue = stripQuotes(pathValue);
const isValueQuoted = startsWith(pathValue, `'`) || startsWith(pathValue, `"`);
const valueBeforeCursor = isValueQuoted
? fullValue.slice(0, position.character - (range.start.character + 1))
: fullValue.slice(0, position.character - range.start.character);
const workspaceRoot = resolveWorkspaceRoot(document, workspaceFolders);
const paths = providePaths(valueBeforeCursor, URI.parse(document.uri).fsPath, workspaceRoot);
const fullValueRange = isValueQuoted ? shiftRange(range, 1, -1) : range;
const replaceRange = pathToReplaceRange(valueBeforeCursor, fullValue, fullValueRange);
const suggestions = paths.map(p => pathToSuggestion(p, replaceRange));
return suggestions;
}
function shouldDoPathCompletion(pathValue: string, workspaceFolders: WorkspaceFolder[]): boolean {
const fullValue = stripQuotes(pathValue);
if (fullValue === '.' || fullValue === '..') {
return false;
}
if (!workspaceFolders || workspaceFolders.length === 0) {
return false;
}
return true;
}
function stripQuotes(fullValue: string) {
if (startsWith(fullValue, `'`) || startsWith(fullValue, `"`)) {
return fullValue.slice(1, -1);