From 4813817bf910b8f9bd4877ce43c391d415447d2e Mon Sep 17 00:00:00 2001 From: Gustavo Martin Hurovich Date: Fri, 9 Mar 2018 17:06:02 -0800 Subject: [PATCH 1/3] Adding Live Preview to wrapIndividualLinesWithAbbreviation --- extensions/emmet/src/abbreviationActions.ts | 70 ++++++++++++++------- 1 file changed, 49 insertions(+), 21 deletions(-) diff --git a/extensions/emmet/src/abbreviationActions.ts b/extensions/emmet/src/abbreviationActions.ts index da56664ca2e06..41cf96e6e1256 100644 --- a/extensions/emmet/src/abbreviationActions.ts +++ b/extensions/emmet/src/abbreviationActions.ts @@ -192,8 +192,7 @@ export function wrapIndividualLinesWithAbbreviation(args: any) { vscode.window.showInformationMessage('Select more than 1 line in each selection and try again.'); return; } - let rangesToReplace: vscode.Range[] = []; - editor.selections.forEach(selection => { + let rangesToReplace: PreviewRangesWithContent[] = editor.selections.sort((a: vscode.Selection, b: vscode.Selection) => { return a.start.compareTo(b.start); }).map(selection => { let rangeToReplace: vscode.Range = selection.isReversed ? new vscode.Range(selection.active, selection.anchor) : selection; if (!rangeToReplace.isSingleLine && rangeToReplace.end.character === 0) { let previousLine = rangeToReplace.end.line - 1; @@ -202,7 +201,12 @@ export function wrapIndividualLinesWithAbbreviation(args: any) { } rangeToReplace = ignoreExtraWhitespaceSelected(rangeToReplace, editor.document); - rangesToReplace.push(rangeToReplace); + return { + originalRange: rangeToReplace, + previewRange: rangeToReplace, + originalContent: editor.document.getText(rangeToReplace), + textToWrapInPreview: editor.document.getText(rangeToReplace).split('\n').map(x => x.trim()) + }; }); const syntax = getSyntaxFromArgs({ language: editor.document.languageId }); @@ -210,32 +214,56 @@ export function wrapIndividualLinesWithAbbreviation(args: any) { return; } - const abbreviationPromise = (args && args['abbreviation']) ? Promise.resolve(args['abbreviation']) : vscode.window.showInputBox({ prompt: 'Enter Abbreviation' }); + let inPreview = false; + let currentValue = ''; + + function inputChanged(value: string): string { + if (value !== currentValue) { + currentValue = value; + makeChanges(value, inPreview, false).then((out) => { + if (typeof out === 'boolean') { + inPreview = out; + } + }); + } + return ''; + } + + const abbreviationPromise = (args && args['abbreviation']) ? Promise.resolve(args['abbreviation']) : vscode.window.showInputBox({ prompt: 'Enter Abbreviation', validateInput: inputChanged }); const helper = getEmmetHelper(); - return abbreviationPromise.then(inputAbbreviation => { - let expandAbbrInput: ExpandAbbreviationInput[] = []; - if (!inputAbbreviation || !inputAbbreviation.trim() || !helper.isAbbreviationValid(syntax, inputAbbreviation)) { return false; } + function makeChanges(inputAbbreviation: string | undefined, inPreview: boolean, definitive: boolean): Thenable { + if (!inputAbbreviation || !inputAbbreviation.trim() || !helper.isAbbreviationValid(syntax, inputAbbreviation)) { + return inPreview ? revertPreview(editor, rangesToReplace).then(() => { return false; }) : Promise.resolve(inPreview); + } let extractedResults = helper.extractAbbreviationFromText(inputAbbreviation); if (!extractedResults) { - return false; + return Promise.resolve(inPreview); + } else if (extractedResults.abbreviation !== inputAbbreviation) { + // Not clear what should we do in this case. Warn the user? How? } - rangesToReplace.forEach(rangeToReplace => { - let lines = editor.document.getText(rangeToReplace).split('\n').map(x => x.trim()); - - let { abbreviation, filter } = extractedResults; - let input: ExpandAbbreviationInput = { - syntax, - abbreviation, - rangeToReplace, - textToWrap: lines, - filter - }; - expandAbbrInput.push(input); + + let { abbreviation, filter } = extractedResults; + if (definitive) { + const revertPromise = inPreview ? revertPreview(editor, rangesToReplace) : Promise.resolve(); + return revertPromise.then(() => { + const expandAbbrList: ExpandAbbreviationInput[] = rangesToReplace.map(rangesAndContent => { + let rangeToReplace = rangesAndContent.originalRange; + let textToWrap = rangesAndContent.textToWrapInPreview; + return { syntax: syntax || '', abbreviation, rangeToReplace, textToWrap, filter }; + }); + return expandAbbreviationInRange(editor, expandAbbrList, false).then(() => { return true; }); + }); + } + const expandAbbrList: ExpandAbbreviationInput[] = rangesToReplace.map(rangesAndContent => { + return { syntax: syntax || '', abbreviation, rangeToReplace: rangesAndContent.originalRange, textToWrap: rangesAndContent.textToWrapInPreview, filter }; }); - return expandAbbreviationInRange(editor, expandAbbrInput, false); + return applyPreview(editor, expandAbbrList, rangesToReplace); + } + return abbreviationPromise.then(inputAbbreviation => { + return makeChanges(inputAbbreviation, inPreview, true); }); } From dcb775f94597a118a239e7f1836ca667955d9033 Mon Sep 17 00:00:00 2001 From: Gustavo Martin Hurovich Date: Fri, 9 Mar 2018 18:10:03 -0800 Subject: [PATCH 2/3] Refactoring --- extensions/emmet/src/abbreviationActions.ts | 159 ++++++-------------- 1 file changed, 49 insertions(+), 110 deletions(-) diff --git a/extensions/emmet/src/abbreviationActions.ts b/extensions/emmet/src/abbreviationActions.ts index 41cf96e6e1256..99156e2ceb0fb 100644 --- a/extensions/emmet/src/abbreviationActions.ts +++ b/extensions/emmet/src/abbreviationActions.ts @@ -32,103 +32,7 @@ interface PreviewRangesWithContent { } export function wrapWithAbbreviation(args: any) { - if (!validate(false) || !vscode.window.activeTextEditor) { - return; - } - - const editor = vscode.window.activeTextEditor; - let rootNode = parseDocument(editor.document, false); - - const syntax = getSyntaxFromArgs({ language: editor.document.languageId }) || ''; - if (!syntax) { - return; - } - - let inPreview = false; - - // Fetch general information for the succesive expansions. i.e. the ranges to replace and its contents - let rangesToReplace: PreviewRangesWithContent[] = []; - - editor.selections.sort((a: vscode.Selection, b: vscode.Selection) => { return a.start.line - b.start.line; }).forEach(selection => { - let rangeToReplace: vscode.Range = selection.isReversed ? new vscode.Range(selection.active, selection.anchor) : selection; - if (!rangeToReplace.isSingleLine && rangeToReplace.end.character === 0) { - let previousLine = rangeToReplace.end.line - 1; - let lastChar = editor.document.lineAt(previousLine).text.length; - rangeToReplace = new vscode.Range(rangeToReplace.start, new vscode.Position(previousLine, lastChar)); - } else if (rangeToReplace.isEmpty) { - let { active } = selection; - let currentNode = getNode(rootNode, active, true); - if (currentNode && (currentNode.start.line === active.line || currentNode.end.line === active.line)) { - rangeToReplace = new vscode.Range(currentNode.start, currentNode.end); - } else { - rangeToReplace = new vscode.Range(rangeToReplace.start.line, 0, rangeToReplace.start.line, editor.document.lineAt(rangeToReplace.start.line).text.length); - } - } - - rangeToReplace = ignoreExtraWhitespaceSelected(rangeToReplace, editor.document); - - const wholeFirstLine = editor.document.lineAt(rangeToReplace.start).text; - const otherMatches = wholeFirstLine.match(/^(\s*)/); - const preceedingWhiteSpace = otherMatches ? otherMatches[1] : ''; - let textToReplace = editor.document.getText(rangeToReplace); - let textToWrapInPreview = rangeToReplace.isSingleLine ? [textToReplace] : ['\n\t' + textToReplace.split('\n' + preceedingWhiteSpace).join('\n\t') + '\n']; - rangesToReplace.push({ previewRange: rangeToReplace, originalRange: rangeToReplace, originalContent: textToReplace, textToWrapInPreview }); - }); - - let abbreviationPromise; - let currentValue = ''; - - function inputChanged(value: string): string { - if (value !== currentValue) { - currentValue = value; - makeChanges(value, inPreview, false).then((out) => { - if (typeof out === 'boolean') { - inPreview = out; - } - }); - } - return ''; - } - - abbreviationPromise = (args && args['abbreviation']) ? Promise.resolve(args['abbreviation']) : vscode.window.showInputBox({ prompt: 'Enter Abbreviation', validateInput: inputChanged }); - const helper = getEmmetHelper(); - - function makeChanges(inputAbbreviation: string | undefined, inPreview: boolean, definitive: boolean): Thenable { - if (!inputAbbreviation || !inputAbbreviation.trim() || !helper.isAbbreviationValid(syntax, inputAbbreviation)) { - return inPreview ? revertPreview(editor, rangesToReplace).then(() => { return false; }) : Promise.resolve(inPreview); - } - - let extractedResults = helper.extractAbbreviationFromText(inputAbbreviation); - if (!extractedResults) { - return Promise.resolve(inPreview); - } else if (extractedResults.abbreviation !== inputAbbreviation) { - // Not clear what should we do in this case. Warn the user? How? - } - - let { abbreviation, filter } = extractedResults; - if (definitive) { - const revertPromise = inPreview ? revertPreview(editor, rangesToReplace) : Promise.resolve(); - return revertPromise.then(() => { - const expandAbbrList: ExpandAbbreviationInput[] = rangesToReplace.map(rangesAndContent => { - let rangeToReplace = rangesAndContent.originalRange; - let textToWrap = rangeToReplace.isSingleLine ? ['$TM_SELECTED_TEXT'] : ['\n\t$TM_SELECTED_TEXT\n']; - return { syntax, abbreviation, rangeToReplace, textToWrap, filter }; - }); - return expandAbbreviationInRange(editor, expandAbbrList, true).then(() => { return true; }); - }); - } - - const expandAbbrList: ExpandAbbreviationInput[] = rangesToReplace.map(rangesAndContent => { - return { syntax, abbreviation, rangeToReplace: rangesAndContent.originalRange, textToWrap: rangesAndContent.textToWrapInPreview, filter }; - }); - - return applyPreview(editor, expandAbbrList, rangesToReplace); - } - - // On inputBox closing - return abbreviationPromise.then(inputAbbreviation => { - return makeChanges(inputAbbreviation, inPreview, true); - }); + return doWrapping(false, args); } function revertPreview(editor: vscode.TextEditor, rangesToReplace: PreviewRangesWithContent[]): Thenable { @@ -178,34 +82,58 @@ function applyPreview(editor: vscode.TextEditor, expandAbbrList: ExpandAbbreviat }, { undoStopBefore: false, undoStopAfter: false }); } -export function wrapIndividualLinesWithAbbreviation(args: any) { +function doWrapping(individualLines: boolean, args: any) { if (!validate(false) || !vscode.window.activeTextEditor) { return; } const editor = vscode.window.activeTextEditor; - if (editor.selections.length === 1 && editor.selection.isEmpty) { - vscode.window.showInformationMessage('Select more than 1 line and try again.'); - return; - } - if (editor.selections.find(x => x.isEmpty)) { - vscode.window.showInformationMessage('Select more than 1 line in each selection and try again.'); - return; + let rootNode = parseDocument(editor.document, false); + if (individualLines) { + if (editor.selections.length === 1 && editor.selection.isEmpty) { + vscode.window.showInformationMessage('Select more than 1 line and try again.'); + return; + } + if (editor.selections.find(x => x.isEmpty)) { + vscode.window.showInformationMessage('Select more than 1 line in each selection and try again.'); + return; + } } + + // Fetch general information for the succesive expansions. i.e. the ranges to replace and its contents let rangesToReplace: PreviewRangesWithContent[] = editor.selections.sort((a: vscode.Selection, b: vscode.Selection) => { return a.start.compareTo(b.start); }).map(selection => { let rangeToReplace: vscode.Range = selection.isReversed ? new vscode.Range(selection.active, selection.anchor) : selection; if (!rangeToReplace.isSingleLine && rangeToReplace.end.character === 0) { let previousLine = rangeToReplace.end.line - 1; let lastChar = editor.document.lineAt(previousLine).text.length; rangeToReplace = new vscode.Range(rangeToReplace.start, new vscode.Position(previousLine, lastChar)); + } else if (rangeToReplace.isEmpty) { + let { active } = selection; + let currentNode = getNode(rootNode, active, true); + if (currentNode && (currentNode.start.line === active.line || currentNode.end.line === active.line)) { + rangeToReplace = new vscode.Range(currentNode.start, currentNode.end); + } else { + rangeToReplace = new vscode.Range(rangeToReplace.start.line, 0, rangeToReplace.start.line, editor.document.lineAt(rangeToReplace.start.line).text.length); + } } rangeToReplace = ignoreExtraWhitespaceSelected(rangeToReplace, editor.document); + let textToWrapInPreview: string[]; + let textToReplace = editor.document.getText(rangeToReplace); + if (individualLines) { + textToWrapInPreview = textToReplace.split('\n').map(x => x.trim()); + } else { + const wholeFirstLine = editor.document.lineAt(rangeToReplace.start).text; + const otherMatches = wholeFirstLine.match(/^(\s*)/); + const preceedingWhiteSpace = otherMatches ? otherMatches[1] : ''; + textToWrapInPreview = rangeToReplace.isSingleLine ? [textToReplace] : ['\n\t' + textToReplace.split('\n' + preceedingWhiteSpace).join('\n\t') + '\n']; + } + return { - originalRange: rangeToReplace, previewRange: rangeToReplace, - originalContent: editor.document.getText(rangeToReplace), - textToWrapInPreview: editor.document.getText(rangeToReplace).split('\n').map(x => x.trim()) + originalRange: rangeToReplace, + originalContent: textToReplace, + textToWrapInPreview }; }); @@ -250,22 +178,33 @@ export function wrapIndividualLinesWithAbbreviation(args: any) { return revertPromise.then(() => { const expandAbbrList: ExpandAbbreviationInput[] = rangesToReplace.map(rangesAndContent => { let rangeToReplace = rangesAndContent.originalRange; - let textToWrap = rangesAndContent.textToWrapInPreview; + let textToWrap: string[]; + if (individualLines) { + textToWrap = rangesAndContent.textToWrapInPreview; + } else { + textToWrap = rangeToReplace.isSingleLine ? ['$TM_SELECTED_TEXT'] : ['\n\t$TM_SELECTED_TEXT\n']; + } return { syntax: syntax || '', abbreviation, rangeToReplace, textToWrap, filter }; }); - return expandAbbreviationInRange(editor, expandAbbrList, false).then(() => { return true; }); + return expandAbbreviationInRange(editor, expandAbbrList, !individualLines).then(() => { return true; }); }); } + const expandAbbrList: ExpandAbbreviationInput[] = rangesToReplace.map(rangesAndContent => { return { syntax: syntax || '', abbreviation, rangeToReplace: rangesAndContent.originalRange, textToWrap: rangesAndContent.textToWrapInPreview, filter }; }); return applyPreview(editor, expandAbbrList, rangesToReplace); } + + // On inputBox closing return abbreviationPromise.then(inputAbbreviation => { return makeChanges(inputAbbreviation, inPreview, true); }); +} +export function wrapIndividualLinesWithAbbreviation(args: any) { + return doWrapping(true, args); } function ignoreExtraWhitespaceSelected(range: vscode.Range, document: vscode.TextDocument): vscode.Range { From c2f0155a676c742618831de6c5fbfd82353f7d1a Mon Sep 17 00:00:00 2001 From: Ramya Achutha Rao Date: Tue, 13 Mar 2018 20:55:34 -0700 Subject: [PATCH 3/3] Re-arranging code --- extensions/emmet/src/abbreviationActions.ts | 164 ++++++++++---------- 1 file changed, 78 insertions(+), 86 deletions(-) diff --git a/extensions/emmet/src/abbreviationActions.ts b/extensions/emmet/src/abbreviationActions.ts index 99156e2ceb0fb..d238d90e798a7 100644 --- a/extensions/emmet/src/abbreviationActions.ts +++ b/extensions/emmet/src/abbreviationActions.ts @@ -35,51 +35,8 @@ export function wrapWithAbbreviation(args: any) { return doWrapping(false, args); } -function revertPreview(editor: vscode.TextEditor, rangesToReplace: PreviewRangesWithContent[]): Thenable { - return editor.edit(builder => { - for (let i = 0; i < rangesToReplace.length; i++) { - builder.replace(rangesToReplace[i].previewRange, rangesToReplace[i].originalContent); - rangesToReplace[i].previewRange = rangesToReplace[i].originalRange; - } - }, { undoStopBefore: false, undoStopAfter: false }); -} - -function applyPreview(editor: vscode.TextEditor, expandAbbrList: ExpandAbbreviationInput[], rangesToReplace: PreviewRangesWithContent[]): Thenable { - let totalLinesInserted = 0; - - return editor.edit(builder => { - for (let i = 0; i < rangesToReplace.length; i++) { - const expandedText = expandAbbr(expandAbbrList[i]) || ''; - if (!expandedText) { - // Failed to expand text. We already showed an error inside expandAbbr. - break; - } - - const oldPreviewRange = rangesToReplace[i].previewRange; - const preceedingText = editor.document.getText(new vscode.Range(oldPreviewRange.start.line, 0, oldPreviewRange.start.line, oldPreviewRange.start.character)); - const indentPrefix = (preceedingText.match(/^(\s*)/) || ['', ''])[1]; - - let newText = expandedText.replace(/\n/g, '\n' + indentPrefix); // Adding indentation on each line of expanded text - newText = newText.replace(/\$\{[\d]*\}/g, '|'); // Removing Tabstops - newText = newText.replace(/\$\{[\d]*(:[^}]*)?\}/g, (match) => { // Replacing Placeholders - return match.replace(/^\$\{[\d]*:/, '').replace('}', ''); - }); - builder.replace(oldPreviewRange, newText); - - const expandedTextLines = newText.split('\n'); - const oldPreviewLines = oldPreviewRange.end.line - oldPreviewRange.start.line + 1; - const newLinesInserted = expandedTextLines.length - oldPreviewLines; - - let lastLineEnd = expandedTextLines[expandedTextLines.length - 1].length; - if (expandedTextLines.length === 1) { - // If the expandedText is single line, add the length of preceeding whitespace as it will not be included in line length. - lastLineEnd += oldPreviewRange.start.character; - } - - rangesToReplace[i].previewRange = new vscode.Range(oldPreviewRange.start.line + totalLinesInserted, oldPreviewRange.start.character, oldPreviewRange.end.line + totalLinesInserted + newLinesInserted, lastLineEnd); - totalLinesInserted += newLinesInserted; - } - }, { undoStopBefore: false, undoStopAfter: false }); +export function wrapIndividualLinesWithAbbreviation(args: any) { + return doWrapping(true, args); } function doWrapping(individualLines: boolean, args: any) { @@ -88,7 +45,7 @@ function doWrapping(individualLines: boolean, args: any) { } const editor = vscode.window.activeTextEditor; - let rootNode = parseDocument(editor.document, false); + const rootNode = parseDocument(editor.document, false); if (individualLines) { if (editor.selections.length === 1 && editor.selection.isEmpty) { vscode.window.showInformationMessage('Select more than 1 line and try again.'); @@ -99,17 +56,25 @@ function doWrapping(individualLines: boolean, args: any) { return; } } + const syntax = getSyntaxFromArgs({ language: editor.document.languageId }); + if (!syntax) { + return; + } + + let inPreview = false; + let currentValue = ''; + const helper = getEmmetHelper(); // Fetch general information for the succesive expansions. i.e. the ranges to replace and its contents let rangesToReplace: PreviewRangesWithContent[] = editor.selections.sort((a: vscode.Selection, b: vscode.Selection) => { return a.start.compareTo(b.start); }).map(selection => { let rangeToReplace: vscode.Range = selection.isReversed ? new vscode.Range(selection.active, selection.anchor) : selection; if (!rangeToReplace.isSingleLine && rangeToReplace.end.character === 0) { - let previousLine = rangeToReplace.end.line - 1; - let lastChar = editor.document.lineAt(previousLine).text.length; + const previousLine = rangeToReplace.end.line - 1; + const lastChar = editor.document.lineAt(previousLine).text.length; rangeToReplace = new vscode.Range(rangeToReplace.start, new vscode.Position(previousLine, lastChar)); } else if (rangeToReplace.isEmpty) { - let { active } = selection; - let currentNode = getNode(rootNode, active, true); + const { active } = selection; + const currentNode = getNode(rootNode, active, true); if (currentNode && (currentNode.start.line === active.line || currentNode.end.line === active.line)) { rangeToReplace = new vscode.Range(currentNode.start, currentNode.end); } else { @@ -117,7 +82,11 @@ function doWrapping(individualLines: boolean, args: any) { } } - rangeToReplace = ignoreExtraWhitespaceSelected(rangeToReplace, editor.document); + const firstLineOfSelection = editor.document.lineAt(rangeToReplace.start).text.substr(rangeToReplace.start.character); + const matches = firstLineOfSelection.match(/^(\s*)/); + const extraWhiteSpaceSelected = matches ? matches[1].length : 0; + rangeToReplace = new vscode.Range(rangeToReplace.start.line, rangeToReplace.start.character + extraWhiteSpaceSelected, rangeToReplace.end.line, rangeToReplace.end.character); + let textToWrapInPreview: string[]; let textToReplace = editor.document.getText(rangeToReplace); if (individualLines) { @@ -137,32 +106,56 @@ function doWrapping(individualLines: boolean, args: any) { }; }); - const syntax = getSyntaxFromArgs({ language: editor.document.languageId }); - if (!syntax) { - return; + function revertPreview(): Thenable { + return editor.edit(builder => { + for (let i = 0; i < rangesToReplace.length; i++) { + builder.replace(rangesToReplace[i].previewRange, rangesToReplace[i].originalContent); + rangesToReplace[i].previewRange = rangesToReplace[i].originalRange; + } + }, { undoStopBefore: false, undoStopAfter: false }); } - let inPreview = false; - let currentValue = ''; + function applyPreview(expandAbbrList: ExpandAbbreviationInput[]): Thenable { + let totalLinesInserted = 0; - function inputChanged(value: string): string { - if (value !== currentValue) { - currentValue = value; - makeChanges(value, inPreview, false).then((out) => { - if (typeof out === 'boolean') { - inPreview = out; + return editor.edit(builder => { + for (let i = 0; i < rangesToReplace.length; i++) { + const expandedText = expandAbbr(expandAbbrList[i]) || ''; + if (!expandedText) { + // Failed to expand text. We already showed an error inside expandAbbr. + break; } - }); - } - return ''; - } - const abbreviationPromise = (args && args['abbreviation']) ? Promise.resolve(args['abbreviation']) : vscode.window.showInputBox({ prompt: 'Enter Abbreviation', validateInput: inputChanged }); - const helper = getEmmetHelper(); + const oldPreviewRange = rangesToReplace[i].previewRange; + const preceedingText = editor.document.getText(new vscode.Range(oldPreviewRange.start.line, 0, oldPreviewRange.start.line, oldPreviewRange.start.character)); + const indentPrefix = (preceedingText.match(/^(\s*)/) || ['', ''])[1]; - function makeChanges(inputAbbreviation: string | undefined, inPreview: boolean, definitive: boolean): Thenable { + let newText = expandedText.replace(/\n/g, '\n' + indentPrefix); // Adding indentation on each line of expanded text + newText = newText.replace(/\$\{[\d]*\}/g, '|'); // Removing Tabstops + newText = newText.replace(/\$\{[\d]*(:[^}]*)?\}/g, (match) => { // Replacing Placeholders + return match.replace(/^\$\{[\d]*:/, '').replace('}', ''); + }); + builder.replace(oldPreviewRange, newText); + + const expandedTextLines = newText.split('\n'); + const oldPreviewLines = oldPreviewRange.end.line - oldPreviewRange.start.line + 1; + const newLinesInserted = expandedTextLines.length - oldPreviewLines; + + let lastLineEnd = expandedTextLines[expandedTextLines.length - 1].length; + if (expandedTextLines.length === 1) { + // If the expandedText is single line, add the length of preceeding whitespace as it will not be included in line length. + lastLineEnd += oldPreviewRange.start.character; + } + + rangesToReplace[i].previewRange = new vscode.Range(oldPreviewRange.start.line + totalLinesInserted, oldPreviewRange.start.character, oldPreviewRange.end.line + totalLinesInserted + newLinesInserted, lastLineEnd); + totalLinesInserted += newLinesInserted; + } + }, { undoStopBefore: false, undoStopAfter: false }); + } + + function makeChanges(inputAbbreviation: string | undefined, definitive: boolean): Thenable { if (!inputAbbreviation || !inputAbbreviation.trim() || !helper.isAbbreviationValid(syntax, inputAbbreviation)) { - return inPreview ? revertPreview(editor, rangesToReplace).then(() => { return false; }) : Promise.resolve(inPreview); + return inPreview ? revertPreview().then(() => { return false; }) : Promise.resolve(inPreview); } let extractedResults = helper.extractAbbreviationFromText(inputAbbreviation); @@ -174,7 +167,7 @@ function doWrapping(individualLines: boolean, args: any) { let { abbreviation, filter } = extractedResults; if (definitive) { - const revertPromise = inPreview ? revertPreview(editor, rangesToReplace) : Promise.resolve(); + const revertPromise = inPreview ? revertPreview() : Promise.resolve(); return revertPromise.then(() => { const expandAbbrList: ExpandAbbreviationInput[] = rangesToReplace.map(rangesAndContent => { let rangeToReplace = rangesAndContent.originalRange; @@ -194,27 +187,26 @@ function doWrapping(individualLines: boolean, args: any) { return { syntax: syntax || '', abbreviation, rangeToReplace: rangesAndContent.originalRange, textToWrap: rangesAndContent.textToWrapInPreview, filter }; }); - return applyPreview(editor, expandAbbrList, rangesToReplace); + return applyPreview(expandAbbrList); } - // On inputBox closing + function inputChanged(value: string): string { + if (value !== currentValue) { + currentValue = value; + makeChanges(value, false).then((out) => { + if (typeof out === 'boolean') { + inPreview = out; + } + }); + } + return ''; + } + const abbreviationPromise = (args && args['abbreviation']) ? Promise.resolve(args['abbreviation']) : vscode.window.showInputBox({ prompt: 'Enter Abbreviation', validateInput: inputChanged }); return abbreviationPromise.then(inputAbbreviation => { - return makeChanges(inputAbbreviation, inPreview, true); + return makeChanges(inputAbbreviation, true); }); } -export function wrapIndividualLinesWithAbbreviation(args: any) { - return doWrapping(true, args); -} - -function ignoreExtraWhitespaceSelected(range: vscode.Range, document: vscode.TextDocument): vscode.Range { - const firstLineOfSelection = document.lineAt(range.start).text.substr(range.start.character); - const matches = firstLineOfSelection.match(/^(\s*)/); - const extraWhiteSpaceSelected = matches ? matches[1].length : 0; - - return new vscode.Range(range.start.line, range.start.character + extraWhiteSpaceSelected, range.end.line, range.end.character); -} - export function expandEmmetAbbreviation(args: any): Thenable { if (!validate() || !vscode.window.activeTextEditor) { return fallbackTab();