From c128baf0c41d5113c1b876f691e0185201b1f500 Mon Sep 17 00:00:00 2001 From: Divyansh Singh <40380293+brc-dd@users.noreply.github.com> Date: Tue, 20 May 2025 09:47:27 +0530 Subject: [PATCH] fix(client): properly skip removed lines when copying code blocks x-ref: https://github.com/vuejs/vitepress/issues/4751#issuecomment-2892833187 --- src/client/app/composables/copyCode.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/client/app/composables/copyCode.ts b/src/client/app/composables/copyCode.ts index 2c458bb4..4d35e012 100644 --- a/src/client/app/composables/copyCode.ts +++ b/src/client/app/composables/copyCode.ts @@ -1,5 +1,8 @@ import { inBrowser } from 'vitepress' +const shellRE = /language-(shellscript|shell|bash|sh|zsh)/ +const ignoredNodes = ['.vp-copy-ignore', '.diff.remove'].join(', ') + export function useCopyCode() { if (inBrowser) { const timeoutIdMap: WeakMap = new WeakMap() @@ -7,22 +10,19 @@ export function useCopyCode() { const el = e.target as HTMLElement if (el.matches('div[class*="language-"] > button.copy')) { const parent = el.parentElement - const sibling = el.nextElementSibling?.nextElementSibling + const sibling = el.nextElementSibling?.nextElementSibling //
 tag
         if (!parent || !sibling) {
           return
         }
 
-        const isShell = /language-(shellscript|shell|bash|sh|zsh)/.test(
-          parent.className
-        )
-
-        const ignoredNodes = ['.vp-copy-ignore', '.diff.remove']
+        const isShell = shellRE.test(parent.className)
 
         // Clone the node and remove the ignored nodes
         const clone = sibling.cloneNode(true) as HTMLElement
-        clone
-          .querySelectorAll(ignoredNodes.join(','))
-          .forEach((node) => node.remove())
+        clone.querySelectorAll(ignoredNodes).forEach((node) => node.remove())
+        // remove extra newlines left after removing ignored nodes (affecting textContent because it is inside `
`)
+        // doesn't affect the newlines already in the code because they are rendered as `\n`
+        clone.innerHTML = clone.innerHTML.replace(/\n+/g, '\n')
 
         let text = clone.textContent || ''