Skip to content

Commit

Permalink
Change behaviors of ⌘A / ⌃A: Extend selection by level (#445)
Browse files Browse the repository at this point in the history
Change behaviors of ⌘A: Extend selection from current list item to all sublists of current list item, then to the whole list.
  • Loading branch information
twio142 authored Jul 31, 2023
1 parent 06dc87c commit e7b9b93
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 8 deletions.
38 changes: 30 additions & 8 deletions src/operations/SelectAllContent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
56 changes: 56 additions & 0 deletions src/operations/__tests__/SelectAllContent.test.ts
Original file line number Diff line number Diff line change
@@ -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);
});

0 comments on commit e7b9b93

Please sign in to comment.