From 934cd52fa8ef2ba127d6307dc684aacc1b72630f Mon Sep 17 00:00:00 2001 From: Meghan Kulkarni Date: Tue, 1 Aug 2023 13:14:56 -0700 Subject: [PATCH] Links paste as plain text over markdown links (#189366) * remove updateTitle * fixed ranges and tests * fix tests --- .../src/languageFeatures/copyFiles/shared.ts | 33 +++----- .../src/test/markdownLink.test.ts | 83 ++++++------------- 2 files changed, 36 insertions(+), 80 deletions(-) diff --git a/extensions/markdown-language-features/src/languageFeatures/copyFiles/shared.ts b/extensions/markdown-language-features/src/languageFeatures/copyFiles/shared.ts index 598c1e68cc8..5e0b4945a60 100644 --- a/extensions/markdown-language-features/src/languageFeatures/copyFiles/shared.ts +++ b/extensions/markdown-language-features/src/languageFeatures/copyFiles/shared.ts @@ -86,11 +86,6 @@ export interface SmartPaste { */ pasteAsMarkdownLink: boolean; - /** - * `true` if the link is being pasted over a markdown link. - */ - updateTitle: boolean; - } export enum PasteUrlAsFormattedLink { @@ -118,26 +113,24 @@ export async function createEditAddingLinksForUriList( const edits: vscode.SnippetTextEdit[] = []; let placeHolderValue: number = ranges.length; let label: string = ''; - let smartPaste = { pasteAsMarkdownLink: true, updateTitle: false }; + let pasteAsMarkdownLink: boolean = true; for (const range of ranges) { - let title = document.getText(range); const selectedRange: vscode.Range = new vscode.Range( new vscode.Position(range.start.line, document.offsetAt(range.start)), new vscode.Position(range.end.line, document.offsetAt(range.end)) ); if (useSmartPaste) { - smartPaste = checkSmartPaste(document, selectedRange); - title = smartPaste.updateTitle ? '' : document.getText(range); + pasteAsMarkdownLink = checkSmartPaste(document, selectedRange, range); } - const snippet = await tryGetUriListSnippet(document, urlList, token, title, placeHolderValue, smartPaste.pasteAsMarkdownLink, isExternalLink); + const snippet = await tryGetUriListSnippet(document, urlList, token, document.getText(range), placeHolderValue, pasteAsMarkdownLink, isExternalLink); if (!snippet) { return; } - smartPaste.pasteAsMarkdownLink = true; + pasteAsMarkdownLink = true; placeHolderValue--; edits.push(new vscode.SnippetTextEdit(range, snippet.snippet)); label = snippet.label; @@ -149,25 +142,23 @@ export async function createEditAddingLinksForUriList( return { additionalEdits, label }; } -export function checkSmartPaste(document: SkinnyTextDocument, selectedRange: vscode.Range): SmartPaste { - const SmartPaste: SmartPaste = { pasteAsMarkdownLink: true, updateTitle: false }; - if (selectedRange.isEmpty || /^[\s\n]*$/.test(document.getText(selectedRange)) || validateLink(document.getText(selectedRange)).isValid) { - return { pasteAsMarkdownLink: false, updateTitle: false }; +export function checkSmartPaste(document: SkinnyTextDocument, selectedRange: vscode.Range, range: vscode.Range): boolean { + if (selectedRange.isEmpty || /^[\s\n]*$/.test(document.getText(range)) || validateLink(document.getText(range)).isValid) { + return false; } for (const regex of smartPasteRegexes) { const matches = [...document.getText().matchAll(regex.regex)]; for (const match of matches) { if (match.index !== undefined) { - const useDefaultPaste = selectedRange.start.character > match.index && selectedRange.end.character < match.index + match[0].length; - SmartPaste.pasteAsMarkdownLink = !useDefaultPaste; - SmartPaste.updateTitle = regex.isMarkdownLink && selectedRange.start.character === match.index && selectedRange.end.character === match.index + match[0].length; - if (!SmartPaste.pasteAsMarkdownLink || SmartPaste.updateTitle) { - return SmartPaste; + const inLink = selectedRange.start.character > match.index && selectedRange.end.character < match.index + match[0].length; + const overLink = regex.isMarkdownLink && selectedRange.start.character === match.index && selectedRange.end.character === match.index + match[0].length; + if (inLink || overLink) { + return false; } } } } - return SmartPaste; + return true; } export function validateLink(urlList: string): { isValid: boolean; cleanedUrlList: string } { diff --git a/extensions/markdown-language-features/src/test/markdownLink.test.ts b/extensions/markdown-language-features/src/test/markdownLink.test.ts index 8c31609892f..115aee7128e 100644 --- a/extensions/markdown-language-features/src/test/markdownLink.test.ts +++ b/extensions/markdown-language-features/src/test/markdownLink.test.ts @@ -151,70 +151,52 @@ suite('createEditAddingLinksForUriList', () => { uri: vscode.Uri.file('/path/to/your/file'), offsetAt: function () { return 0; }, getText: function () { return 'hello world!'; }, - // lineAt: function (position: vscode.Position) { - // return { - // lineNumber: 0, - // text: 'hello world!', - // range: new vscode.Range(position, position), - // rangeIncludingLineBreak: new vscode.Range(position, position), - // firstNonWhitespaceCharacterIndex: 0, - // isEmptyOrWhitespace: false - // } as vscode.TextLine; - // } }; test('Should evaluate pasteAsMarkdownLink as true for selected plain text', () => { - const range = new vscode.Range(0, 0, 0, 12); - const smartPaste = checkSmartPaste(skinnyDocument, range); - assert.strictEqual(smartPaste.pasteAsMarkdownLink, true); + const pasteAsMarkdownLink = checkSmartPaste(skinnyDocument, new vscode.Range(0, 0, 0, 12), new vscode.Range(0, 0, 0, 12)); + assert.strictEqual(pasteAsMarkdownLink, true); }); test('Should evaluate pasteAsMarkdownLink as false for a valid selected link', () => { skinnyDocument.getText = function () { return 'https://www.microsoft.com'; }; - const range = new vscode.Range(0, 0, 0, 25); - const smartPaste = checkSmartPaste(skinnyDocument, range); - assert.strictEqual(smartPaste.pasteAsMarkdownLink, false); + const pasteAsMarkdownLink = checkSmartPaste(skinnyDocument, new vscode.Range(0, 0, 0, 25), new vscode.Range(0, 0, 0, 25)); + assert.strictEqual(pasteAsMarkdownLink, false); }); test('Should evaluate pasteAsMarkdownLink as false for a valid selected link with trailing whitespace', () => { skinnyDocument.getText = function () { return ' https://www.microsoft.com '; }; - const range = new vscode.Range(0, 0, 0, 30); - const smartPaste = checkSmartPaste(skinnyDocument, range); - assert.strictEqual(smartPaste.pasteAsMarkdownLink, false); + const pasteAsMarkdownLink = checkSmartPaste(skinnyDocument, new vscode.Range(0, 0, 0, 30), new vscode.Range(0, 0, 0, 30)); + assert.strictEqual(pasteAsMarkdownLink, false); }); test('Should evaluate pasteAsMarkdownLink as false for no selection', () => { - const range = new vscode.Range(0, 0, 0, 0); - const smartPaste = checkSmartPaste(skinnyDocument, range); - assert.strictEqual(smartPaste.pasteAsMarkdownLink, false); + const pasteAsMarkdownLink = checkSmartPaste(skinnyDocument, new vscode.Range(0, 0, 0, 0), new vscode.Range(0, 0, 0, 0)); + assert.strictEqual(pasteAsMarkdownLink, false); }); test('Should evaluate pasteAsMarkdownLink as false for selected whitespace and new lines', () => { skinnyDocument.getText = function () { return ' \r\n\r\n'; }; - const range = new vscode.Range(0, 0, 0, 7); - const smartPaste = checkSmartPaste(skinnyDocument, range); - assert.strictEqual(smartPaste.pasteAsMarkdownLink, false); + const pasteAsMarkdownLink = checkSmartPaste(skinnyDocument, new vscode.Range(0, 0, 0, 7), new vscode.Range(0, 0, 0, 7)); + assert.strictEqual(pasteAsMarkdownLink, false); }); test('Should evaluate pasteAsMarkdownLink as false for pasting within a backtick code block', () => { skinnyDocument.getText = function () { return '```\r\n\r\n```'; }; - const range = new vscode.Range(0, 5, 0, 5); - const smartPaste = checkSmartPaste(skinnyDocument, range); - assert.strictEqual(smartPaste.pasteAsMarkdownLink, false); + const pasteAsMarkdownLink = checkSmartPaste(skinnyDocument, new vscode.Range(0, 5, 0, 5), new vscode.Range(0, 5, 0, 5)); + assert.strictEqual(pasteAsMarkdownLink, false); }); test('Should evaluate pasteAsMarkdownLink as false for pasting within a tilde code block', () => { skinnyDocument.getText = function () { return '~~~\r\n\r\n~~~'; }; - const range = new vscode.Range(0, 5, 0, 5); - const smartPaste = checkSmartPaste(skinnyDocument, range); - assert.strictEqual(smartPaste.pasteAsMarkdownLink, false); + const pasteAsMarkdownLink = checkSmartPaste(skinnyDocument, new vscode.Range(0, 5, 0, 5), new vscode.Range(0, 5, 0, 5)); + assert.strictEqual(pasteAsMarkdownLink, false); }); test('Should evaluate pasteAsMarkdownLink as false for pasting within a math block', () => { skinnyDocument.getText = function () { return '$$$\r\n\r\n$$$'; }; - const range = new vscode.Range(0, 5, 0, 5); - const smartPaste = checkSmartPaste(skinnyDocument, range); - assert.strictEqual(smartPaste.pasteAsMarkdownLink, false); + const pasteAsMarkdownLink = checkSmartPaste(skinnyDocument, new vscode.Range(0, 5, 0, 5), new vscode.Range(0, 5, 0, 5)); + assert.strictEqual(pasteAsMarkdownLink, false); }); const linkSkinnyDoc: SkinnyTextDocument = { @@ -223,17 +205,9 @@ suite('createEditAddingLinksForUriList', () => { getText: function () { return '[a](bcdef)'; }, }; - test('Should evaluate updateTitle as true for pasting over a Markdown link', () => { - const range = new vscode.Range(0, 0, 0, 10); - const smartPaste = checkSmartPaste(linkSkinnyDoc, range); - assert.strictEqual(smartPaste.updateTitle, true); - }); - test('Should evaluate pasteAsMarkdownLink as false for pasting within a Markdown link', () => { - const range = new vscode.Range(0, 4, 0, 6); - const smartPaste = checkSmartPaste(linkSkinnyDoc, range); - - assert.strictEqual(smartPaste.pasteAsMarkdownLink, false); + const pasteAsMarkdownLink = checkSmartPaste(linkSkinnyDoc, new vscode.Range(0, 4, 0, 6), new vscode.Range(0, 4, 0, 6)); + assert.strictEqual(pasteAsMarkdownLink, false); }); @@ -243,16 +217,9 @@ suite('createEditAddingLinksForUriList', () => { getText: function () { return '![a](bcdef)'; }, }; - test('Should evaluate updateTitle as true for pasting over a Markdown image link', () => { - const range = new vscode.Range(0, 0, 0, 11); - const smartPaste = checkSmartPaste(imageLinkSkinnyDoc, range); - assert.strictEqual(smartPaste.updateTitle, true); - }); - test('Should evaluate pasteAsMarkdownLink as false for pasting within a Markdown image link', () => { - const range = new vscode.Range(0, 5, 0, 10); - const smartPaste = checkSmartPaste(imageLinkSkinnyDoc, range); - assert.strictEqual(smartPaste.pasteAsMarkdownLink, false); + const pasteAsMarkdownLink = checkSmartPaste(imageLinkSkinnyDoc, new vscode.Range(0, 5, 0, 10), new vscode.Range(0, 5, 0, 10)); + assert.strictEqual(pasteAsMarkdownLink, false); }); const inlineCodeSkinnyCode: SkinnyTextDocument = { @@ -262,9 +229,8 @@ suite('createEditAddingLinksForUriList', () => { }; test('Should evaluate pasteAsMarkdownLink as false for pasting within inline code', () => { - const range = new vscode.Range(0, 1, 0, 1); - const smartPaste = checkSmartPaste(inlineCodeSkinnyCode, range); - assert.strictEqual(smartPaste.pasteAsMarkdownLink, false); + const pasteAsMarkdownLink = checkSmartPaste(inlineCodeSkinnyCode, new vscode.Range(0, 1, 0, 1), new vscode.Range(0, 1, 0, 1)); + assert.strictEqual(pasteAsMarkdownLink, false); }); const inlineMathSkinnyDoc: SkinnyTextDocument = { @@ -274,9 +240,8 @@ suite('createEditAddingLinksForUriList', () => { }; test('Should evaluate pasteAsMarkdownLink as false for pasting within inline math', () => { - const range = new vscode.Range(0, 1, 0, 1); - const smartPaste = checkSmartPaste(inlineMathSkinnyDoc, range); - assert.strictEqual(smartPaste.pasteAsMarkdownLink, false); + const pasteAsMarkdownLink = checkSmartPaste(inlineMathSkinnyDoc, new vscode.Range(0, 1, 0, 1), new vscode.Range(0, 1, 0, 1)); + assert.strictEqual(pasteAsMarkdownLink, false); }); }); });