Skip to content

Commit 114c8cd

Browse files
refactor: Remove regexes from Commands files to Task where they can be tested (#1006)
* refactor,fix: Move regexes out of untested Commands files * removing something that should be a separate PR * fix: update comments to remove reference to filename where used * revert: no behavior change in refactor. Leave regex test for cursor reset to be removed in later PR * fix: mark checkbox regex as unicode so character escapes work correctly
1 parent 1bd8257 commit 114c8cd

File tree

3 files changed

+43
-10
lines changed

3 files changed

+43
-10
lines changed

src/Commands/CreateOrEdit.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,7 @@ const taskFromLine = ({ line, path }: { line: string; path: string }): Task => {
5858

5959
// If we are not on a line of a task, we take what we have.
6060
// The non-task line can still be a checklist, for example if it is lacking the global filter.
61-
const nonTaskRegex: RegExp = /^([\s\t>]*)[-*]? *(\[(.)\])? *(.*)/u;
62-
const nonTaskMatch = line.match(nonTaskRegex);
61+
const nonTaskMatch = line.match(Task.nonTaskRegex);
6362
if (nonTaskMatch === null) {
6463
// Should never happen; everything in the regex is optional.
6564
console.error('Tasks: Cannot create task on line:', line);

src/Commands/ToggleDone.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ export const toggleDone = (checking: boolean, editor: Editor, view: View) => {
3434
const toggledLine = toggleLine({ line, path });
3535
editor.setLine(lineNumber, toggledLine);
3636

37-
// The cursor is moved to the end of the line by default.
38-
// If there is text on the line, put the cursor back where it was on the line.
37+
// The cursor is moved to either the beginning of the line (usually) or the end of the line (if it was already at the end) by default.
38+
// Put the cursor back where it was on the line (if there is "text" on the line -- preserves behavior but buggy, will fix in future PR).
3939
if (/[^ [\]*-]/.test(toggledLine)) {
4040
editor.setCursor({
4141
line: cursorPosition.line,
@@ -72,13 +72,12 @@ const toggleLine = ({ line, path }: { line: string; path: string }): string => {
7272
// 1. a list item
7373
// 2. a simple text line
7474

75-
const listItemRegex = /^([\s\t>]*)([-*])/;
76-
if (listItemRegex.test(line)) {
75+
if (Task.listItemRegex.test(line)) {
7776
// Let's convert the list item to a checklist item.
78-
toggledLine = line.replace(listItemRegex, '$1$2 [ ]');
77+
toggledLine = line.replace(Task.listItemRegex, '$1$2 [ ]');
7978
} else {
8079
// Let's convert the line to a list item.
81-
toggledLine = line.replace(/^([\s\t>]*)/, '$1- ');
80+
toggledLine = line.replace(Task.indentationRegex, '$1- ');
8281
}
8382
}
8483
}

src/Task.ts

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,46 @@ export class Task {
8484

8585
public static readonly dateFormat = 'YYYY-MM-DD';
8686

87+
// Matches indentation before a list marker (including > for potentially nested blockquotes or Obsidian callouts)
88+
public static readonly indentationRegex = /^([\s\t>]*)/;
89+
90+
// Matches (but does not save) - or * list markers.
91+
public static readonly listMarkerRegex = /[-*]/;
92+
93+
// Matches a checkbox and saves the status character inside
94+
public static readonly checkboxRegex = /\[(.)\]/u;
95+
96+
// Matches the rest of the task after the checkbox.
97+
public static readonly afterCheckboxRegex = / *(.*)/u;
98+
8799
// Main regex for parsing a line. It matches the following:
88-
// - Indentation (including > for potentially nested blockquotes or Obsidian callouts)
100+
// - Indentation
89101
// - Status character
90102
// - Rest of task after checkbox markdown
91-
public static readonly taskRegex = /^([\s\t>]*)[-*] +\[(.)\] *(.*)/u;
103+
public static readonly taskRegex = new RegExp(
104+
this.indentationRegex.source +
105+
this.listMarkerRegex.source +
106+
' +' +
107+
this.checkboxRegex.source +
108+
this.afterCheckboxRegex.source,
109+
'u',
110+
);
111+
112+
// Used with the "Create or Edit Task" command to parse indentation and status if present
113+
public static readonly nonTaskRegex = new RegExp(
114+
this.indentationRegex.source +
115+
this.listMarkerRegex.source +
116+
'? *(' +
117+
this.checkboxRegex.source +
118+
')?' +
119+
this.afterCheckboxRegex.source,
120+
'u',
121+
);
122+
123+
// Used with "Toggle Done" command to detect a list item that can get a checkbox added to it.
124+
public static readonly listItemRegex = new RegExp(
125+
this.indentationRegex.source + '(' + this.listMarkerRegex.source + ')',
126+
);
92127

93128
// Match on block link at end.
94129
public static readonly blockLinkRegex = / \^[a-zA-Z0-9-]+$/u;

0 commit comments

Comments
 (0)