diff --git a/src/operations/SelectAllContent.ts b/src/operations/SelectAllContent.ts index 971d7ba..587501a 100644 --- a/src/operations/SelectAllContent.ts +++ b/src/operations/SelectAllContent.ts @@ -48,13 +48,10 @@ export class SelectAllContent implements Operation { const list = root.getListUnderCursor(); const contentStart = list.getFirstLineContentStartAfterCheckbox(); const contentEnd = list.getLastLineContentEnd(); - - if ( - selectionFrom.line < contentStart.line || - selectionTo.line > contentEnd.line - ) { - return false; - } + const listUnderSelectionFrom = root.getListUnderLine(selectionFrom.line); + const listStart = + listUnderSelectionFrom.getFirstLineContentStartAfterCheckbox(); + const listEnd = listUnderSelectionFrom.getContentEndIncludingChildren(); this.stopPropagation = true; this.updated = true; @@ -64,12 +61,37 @@ export class SelectAllContent implements Operation { selectionFrom.ch === contentStart.ch && selectionTo.line === contentEnd.line && selectionTo.ch === contentEnd.ch + ) { + if (list.getChildren().length) { + // select sub lists + root.replaceSelections([ + { anchor: contentStart, head: list.getContentEndIncludingChildren() }, + ]); + } else { + // select whole list + root.replaceSelections([{ anchor: rootStart, head: rootEnd }]); + } + } else if ( + listStart.ch == selectionFrom.ch && + listEnd.line == selectionTo.line && + listEnd.ch == selectionTo.ch ) { // select whole list root.replaceSelections([{ anchor: rootStart, head: rootEnd }]); - } else { + } else if ( + (selectionFrom.line > contentStart.line || + (selectionFrom.line == contentStart.line && + selectionFrom.ch >= contentStart.ch)) && + (selectionTo.line < contentEnd.line || + (selectionTo.line == contentEnd.line && + selectionTo.ch <= contentEnd.ch)) + ) { // select whole line root.replaceSelections([{ anchor: contentStart, head: contentEnd }]); + } else { + this.stopPropagation = false; + this.updated = false; + return false; } return true; diff --git a/src/operations/__tests__/SelectAllContent.test.ts b/src/operations/__tests__/SelectAllContent.test.ts new file mode 100644 index 0000000..0490d5e --- /dev/null +++ b/src/operations/__tests__/SelectAllContent.test.ts @@ -0,0 +1,56 @@ +import { makeEditor, makeRoot, makeSettings } from "../../__mocks__"; +import { SelectAllContent } from "../SelectAllContent"; + +test("when performed the first time, should select the whole line under cursor; when performed the second time, should select all sub-bullets of the cursor line if it is a parent-bullet", () => { + const root = makeRoot({ + editor: makeEditor({ + text: "- item 1\n- item 2\n - item 2.1\n - item 2.2\n- item 3\n", + cursor: { line: 1, ch: 2 }, + }), + settings: makeSettings(), + }); + + const op = new SelectAllContent(root); + + op.perform(); + expect(root.getSelection().anchor.line).toBe(1); + expect(root.getSelection().anchor.ch).toBe(2); + expect(root.getSelection().head.line).toBe(1); + expect(root.getSelection().head.ch).toBe(8); + + op.perform(); + expect(root.getSelection().anchor.line).toBe(1); + expect(root.getSelection().anchor.ch).toBe(2); + expect(root.getSelection().head.ch).toBe(14); + expect(root.getSelection().head.line).toBe(3); + + op.perform(); + expect(root.getSelection().anchor.line).toBe(0); + expect(root.getSelection().anchor.ch).toBe(0); + expect(root.getSelection().head.line).toBe(4); + expect(root.getSelection().head.ch).toBe(8); +}); + +test("when a whole line is selected and the selected line has no sub-bullets, should select the whole list", () => { + const root = makeRoot({ + editor: makeEditor({ + text: "- item 1\n- item 2\n - item 2.1\n - item 2.2\n- item 3\n", + cursor: { line: 4, ch: 2 }, + }), + settings: makeSettings(), + }); + + const op = new SelectAllContent(root); + + op.perform(); + expect(root.getSelection().anchor.line).toBe(4); + expect(root.getSelection().anchor.ch).toBe(2); + expect(root.getSelection().head.line).toBe(4); + expect(root.getSelection().head.ch).toBe(8); + + op.perform(); + expect(root.getSelection().anchor.line).toBe(0); + expect(root.getSelection().anchor.ch).toBe(0); + expect(root.getSelection().head.line).toBe(4); + expect(root.getSelection().head.ch).toBe(8); +});