Skip to content

Commit

Permalink
Queries can be filtered by their preceding heading
Browse files Browse the repository at this point in the history
For details see README.

Fixes #35
  • Loading branch information
schemar committed May 5, 2021
1 parent 1a12c86 commit 611fe89
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,11 @@ The following filters exist:
- `due (before|after|on) <date>`
- `path (includes|does not include) <path>`
- `description (includes|does not include) <string>`
- `heading (includes|does not include) <string>`
- Whether or not the heading preceding the task includes the given string.
- Always tries to match the closest heading above the task, regardless of heading level.
- Will never match a task that does not have a preceding heading in its file.
- Matches case-insensitive (disregards capitalization).
- `exclude sub-items`
- When this is set, the result list will only include tasks that are not indented in their file. It will only show tasks that are top level list items in their list.
- `limit to <number> tasks`
Expand Down Expand Up @@ -241,6 +246,13 @@ All open tasks that are due within the next two weeks, but are not overdue (due
due before in two weeks
```

All done tasks that are anywhere in the vault under a `tasks` heading (e.g. `## Tasks`):

```tasks
done
heading includes tasks
```

Show all tasks that aren't done, are due on the 9th of April 2021, and where the path includes `GitHub`:

```tasks
Expand Down
32 changes: 32 additions & 0 deletions src/Query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export class Query {
private readonly doneRegexp = /done (before|after|on)? ?(.*)/;
private readonly pathRegexp = /path (includes|does not include) (.*)/;
private readonly descriptionRegexp = /description (includes|does not include) (.*)/;
private readonly headingRegexp = /heading (includes|does not include) (.*)/;
private readonly limitRegexp = /limit (to )?(\d+)( tasks?)?/;
private readonly excludeSubItemsString = 'exclude sub-items';

Expand Down Expand Up @@ -54,6 +55,9 @@ export class Query {
case this.descriptionRegexp.test(line):
this.parseDescriptionFilter({ line });
break;
case this.headingRegexp.test(line):
this.parseHeadingFilter({ line });
break;
case this.limitRegexp.test(line):
this.parseLimit({ line });
break;
Expand Down Expand Up @@ -166,6 +170,34 @@ export class Query {
}
}

private parseHeadingFilter({ line }: { line: string }): void {
const headingMatch = line.match(this.headingRegexp);
if (headingMatch !== null) {
const filterMethod = headingMatch[1].toLowerCase();
if (filterMethod === 'includes') {
this._filters.push(
(task: Task) =>
task.precedingHeader !== null &&
task.precedingHeader
.toLowerCase()
.includes(headingMatch[2]),
);
} else if (headingMatch[1] === 'does not include') {
this._filters.push(
(task: Task) =>
task.precedingHeader !== null &&
!task.precedingHeader
.toLowerCase()
.includes(headingMatch[2]),
);
} else {
this._error = 'do not understand query filter (heading)';
}
} else {
this._error = 'do not understand query filter (heading)';
}
}

private parseLimit({ line }: { line: string }): void {
const limitMatch = line.match(this.limitRegexp);
if (limitMatch !== null) {
Expand Down

0 comments on commit 611fe89

Please sign in to comment.