From 8902a30b1274623e317b772447f7017884301fe6 Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Mon, 19 Jun 2017 17:34:51 -0700 Subject: [PATCH] Consolidate emmet expand action and emmet completion --- extensions/emmet/src/abbreviationActions.ts | 100 ++++++++++++++++-- .../emmet/src/emmetCompletionProvider.ts | 78 +++----------- extensions/emmet/src/util.ts | 14 +-- 3 files changed, 113 insertions(+), 79 deletions(-) diff --git a/extensions/emmet/src/abbreviationActions.ts b/extensions/emmet/src/abbreviationActions.ts index 6f9bbe78f50..767e8497d97 100644 --- a/extensions/emmet/src/abbreviationActions.ts +++ b/extensions/emmet/src/abbreviationActions.ts @@ -5,7 +5,13 @@ import * as vscode from 'vscode'; import { expand } from '@emmetio/expand-abbreviation'; -import { getSyntax, getProfile, extractAbbreviation } from './util'; +import * as extract from '@emmetio/extract-abbreviation'; +import parseStylesheet from '@emmetio/css-parser'; +import parse from '@emmetio/html-matcher'; +import Node from '@emmetio/node'; + +import { getSyntax, getProfile, isStyleSheet, getNode, getInnerRange } from './util'; +import { DocumentStreamReader } from './bufferStream'; const field = (index, placeholder) => `\${${index}${placeholder ? ':' + placeholder : ''}}`; @@ -42,19 +48,97 @@ export function expandAbbreviation() { vscode.window.showInformationMessage('No editor is active'); return; } - let rangeToReplace: vscode.Range = editor.selection; - let abbr = editor.document.getText(rangeToReplace); + let syntax = getSyntax(editor.document); + let output = expandAbbreviationHelper(syntax, editor.document, editor.selection); + if (output) { + editor.insertSnippet(new vscode.SnippetString(output.expandedText), output.rangeToReplace); + } +} + +export interface ExpandAbbreviationHelperOutput { + expandedText: string; + rangeToReplace: vscode.Range; + abbreviation: string; + syntax: string; +} + +/** + * Expands abbreviation at given range in the given document + * @param syntax + * @param document + * @param rangeToReplace + */ +export function expandAbbreviationHelper(syntax: string, document: vscode.TextDocument, rangeToReplace: vscode.Range): ExpandAbbreviationHelperOutput { + let parseContent = isStyleSheet(syntax) ? parseStylesheet : parse; + let rootNode: Node = parseContent(new DocumentStreamReader(document)); + let currentNode = getNode(rootNode, rangeToReplace.end); + + if (forceCssSyntax(syntax, currentNode, rangeToReplace.end)) { + syntax = 'css'; + } else if (!isValidLocationForEmmetAbbreviation(currentNode, syntax, rangeToReplace.end)) { + return; + } + + let abbreviation = document.getText(rangeToReplace); if (rangeToReplace.isEmpty) { - [rangeToReplace, abbr] = extractAbbreviation(rangeToReplace.start); + [rangeToReplace, abbreviation] = extractAbbreviation(document, rangeToReplace.start); } - let syntax = getSyntax(editor.document); + let options = { field: field, syntax: syntax, - profile: getProfile(getSyntax(editor.document)), + profile: getProfile(syntax), addons: syntax === 'jsx' ? { 'jsx': true } : null }; - let expandedText = expand(abbr, options); - editor.insertSnippet(new vscode.SnippetString(expandedText), rangeToReplace); + let expandedText = expand(abbreviation, options); + return { expandedText, rangeToReplace, abbreviation, syntax }; +} + +/** + * Extracts abbreviation from the given position in the given document + */ +function extractAbbreviation(document: vscode.TextDocument, position: vscode.Position): [vscode.Range, string] { + let currentLine = document.lineAt(position.line).text; + let result = extract(currentLine, position.character, true); + if (!result) { + return [null, '']; + } + + let rangeToReplace = new vscode.Range(position.line, result.location, position.line, result.location + result.abbreviation.length); + return [rangeToReplace, result.abbreviation]; +} + +/** + * Inside