From 41d9ef7025346a5ca84511c0953cdf3b7ca6f3a9 Mon Sep 17 00:00:00 2001 From: Jonatan Heyman Date: Thu, 25 Jan 2024 17:44:38 +0100 Subject: [PATCH] Copy whole current line(s) when selection(s) are empty (#177) * Copy whole current line(s) when selection(s) are empty * Fix tests on Linux/Windows --- src/editor/copy-paste.js | 23 ++++++++-- tests/emacs-clipboard-keys.spec.js | 68 +++++++++++++++++++++++++++--- 2 files changed, 82 insertions(+), 9 deletions(-) diff --git a/src/editor/copy-paste.js b/src/editor/copy-paste.js index 6585957e..ba27b930 100644 --- a/src/editor/copy-paste.js +++ b/src/editor/copy-paste.js @@ -11,9 +11,26 @@ const blockSeparatorRegex = new RegExp(`\\n∞∞∞(${languageTokensMatcher})(- function copiedRange(state) { let content = [], ranges = [] - for (let range of state.selection.ranges) if (!range.empty) { - content.push(state.sliceDoc(range.from, range.to)) - ranges.push(range) + for (let range of state.selection.ranges) { + if (!range.empty) { + content.push(state.sliceDoc(range.from, range.to)) + ranges.push(range) + } + } + if (ranges.length == 0) { + // if all ranges are empty, we want to copy each whole (unique) line for each selection + const copiedLines = [] + for (let range of state.selection.ranges) { + if (range.empty) { + const line = state.doc.lineAt(range.head) + const lineContent = state.sliceDoc(line.from, line.to) + if (!copiedLines.includes(line.from)) { + content.push(lineContent) + ranges.push(range) + copiedLines.push(line.from) + } + } + } } return { text: content.join(state.lineBreak), ranges } } diff --git a/tests/emacs-clipboard-keys.spec.js b/tests/emacs-clipboard-keys.spec.js index 560c0984..83cca301 100644 --- a/tests/emacs-clipboard-keys.spec.js +++ b/tests/emacs-clipboard-keys.spec.js @@ -1,15 +1,13 @@ import { test, expect } from "@playwright/test"; import { HeynotePage } from "./test-utils.js"; -let heynotePage +let heynotePage, modifierKey -test.beforeEach(async ({ page }) => { +test.beforeEach(async ({ page, browserName }) => { heynotePage = new HeynotePage(page) await heynotePage.goto() -}); - + modifierKey = heynotePage.isMac ? "Meta" : "Control" -test("test emacs copy/pase/cut key bindings", async ({ page, browserName }) => { if (browserName !== "chromium") { // This test only works in Chromium due to accessing the clipboard test.skip() @@ -21,7 +19,16 @@ test("test emacs copy/pase/cut key bindings", async ({ page, browserName }) => { await page.locator("css=select.metaKey").selectOption("alt") } await page.locator("body").press("Escape") +}); +async function clearBuffer() { + await heynotePage.setContent(` +∞∞∞text +`) +} + + +test("test emacs copy/pase/cut key bindings", async ({ page }) => { await page.locator("body").pressSequentially("test") await page.locator("body").press("Control+Space") await page.locator("body").press("Control+A") @@ -29,7 +36,7 @@ test("test emacs copy/pase/cut key bindings", async ({ page, browserName }) => { expect(await heynotePage.getBlockContent(0)).toBe("test") await page.locator("body").press("Control+Y") expect(await heynotePage.getBlockContent(0)).toBe("testtest") - + await page.locator("body").press("Control+E") await page.locator("body").press("Control+Space") await page.locator("body").press("Control+A") @@ -39,3 +46,52 @@ test("test emacs copy/pase/cut key bindings", async ({ page, browserName }) => { await page.locator("body").press("Control+Y") expect(await heynotePage.getBlockContent(0)).toBe("testtesttesttest") }) + + +// The following tests doesn't really test anything specific to the Emacs key bindings, but triggering +// Copy/Paste by keyboard shortcuts is not possible in Playwright, so we test this functionality using +// the Emacs key bindings + +test("copy current line", async ({ page }) => { + await page.locator("body").pressSequentially("test line! ") + await page.keyboard.press("Alt+W") + await page.keyboard.press("Alt+W") + await clearBuffer() + expect(await heynotePage.getBlockContent(0)).toBe("") + await page.locator("body").press("Control+Y") + await page.locator("body").press("Control+Y") + expect(await heynotePage.getBlockContent(0)).toBe("test line! test line! ") +}) + +test("copy current multiple cursors", async ({ page }) => { + await heynotePage.setContent(` +∞∞∞text +line 1 +line 2`) + await page.keyboard.press("Control+A") + await page.keyboard.press(`${modifierKey}+Alt+ArrowUp`) + await page.locator("body").pressSequentially("test") + await page.keyboard.press("Alt+W") + await clearBuffer() + expect(await heynotePage.getBlockContent(0)).toBe("") + await page.keyboard.press("Control+Y") + //await page.waitForTimeout(100); + expect(await heynotePage.getBlockContent(0)).toBe(`testline 1\ntestline 2`) +}) + +test("copy current multiple cursors on same line", async ({ page }) => { + await heynotePage.setContent(` +∞∞∞text +test`) + await page.keyboard.press("Control+A") + await page.keyboard.press(`${modifierKey}+Alt+ArrowDown`) + await page.locator("body").pressSequentially("1") + expect(await heynotePage.getBlockContent(0)).toBe("1test1") + await page.keyboard.press("Alt+W") + + await clearBuffer() + expect(await heynotePage.getBlockContent(0)).toBe("") + + await page.keyboard.press("Control+Y") + expect(await heynotePage.getBlockContent(0)).toBe("1test1") +})