Skip to content

Commit 0aabc76

Browse files
authored
Merge pull request #3364 from obsidian-tasks-group/explain-layout-statements
feat: Include layout instructions in 'explain' output
2 parents 50e94b7 + d73d261 commit 0aabc76

File tree

6 files changed

+108
-22
lines changed

6 files changed

+108
-22
lines changed

docs/Queries/Explaining Queries.md

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ This has a number of benefits:
2121
- This often explains why tasks are missing from results.
2222
- If there is a [[Global Query|global query]] enabled, it too is included in the explanation.
2323
- Any [[query file defaults]]-generated instructions are listed (since Tasks 7.15.0).
24-
- Note that `show/hide` [[layout]] are not yet shown in `explain` output, however. We are tracking this in [issue #2093](https://github.com/obsidian-tasks-group/obsidian-tasks/issues/2093).
2524
- Any [[Grouping|'group by']] instructions are listed (since Tasks 5.4.0).
2625
- Any [[Sorting|'sort by']] instructions are listed (since Tasks 5.4.0).
2726

@@ -255,22 +254,16 @@ Explanation of the Query File Defaults (from properties/frontmatter in the query
255254
256255
not done
257256
257+
short mode
258+
259+
show tree
260+
258261
Explanation of this Tasks code block query:
259262
260263
No filters supplied. All tasks will match the query.
261264
```
262265
<!-- endSnippet -->
263266
264-
> [!info]- Why are the generated layout instructions not visible?
265-
> The Query File Defaults will have generated these instructions:
266-
>
267-
> ```text
268-
> short mode
269-
> show tree
270-
> ```
271-
>
272-
> Currently, the `explain` output does not display [[layout]] instructions. We are tracking this in [issue #2093](https://github.com/obsidian-tasks-group/obsidian-tasks/issues/2093).
273-
274267
### Placeholder values are expanded
275268
276269
> [!released]

src/Query/Explain/Explainer.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { getSettings } from '../../Config/Settings';
22
import type { Query } from '../Query';
3+
import type { Statement } from '../Statement';
34

45
export class Explainer {
56
private readonly indentation: string;
@@ -35,6 +36,7 @@ export class Explainer {
3536
results.push(this.explainFilters(query));
3637
results.push(this.explainGroups(query));
3738
results.push(this.explainSorters(query));
39+
results.push(this.explainLayout(query));
3840
results.push(this.explainQueryLimits(query));
3941
results.push(this.explainDebugSettings());
4042

@@ -57,19 +59,15 @@ export class Explainer {
5759
}
5860

5961
public explainGroups(query: Query) {
60-
if (query.grouping.length === 0) {
61-
return '';
62-
}
63-
64-
return query.grouping.map((group) => group.statement.explainStatement(this.indentation)).join('\n\n') + '\n';
62+
return this.explainStatements(query.grouping.map((group) => group.statement));
6563
}
6664

6765
public explainSorters(query: Query) {
68-
if (query.sorting.length === 0) {
69-
return '';
70-
}
66+
return this.explainStatements(query.sorting.map((sort) => sort.statement));
67+
}
7168

72-
return query.sorting.map((sort) => sort.statement.explainStatement(this.indentation)).join('\n\n') + '\n';
69+
public explainLayout(query: Query) {
70+
return this.explainStatements(query.layoutStatements);
7371
}
7472

7573
public explainQueryLimits(query: Query) {
@@ -107,6 +105,14 @@ export class Explainer {
107105
return result;
108106
}
109107

108+
private explainStatements(statements: Statement[]) {
109+
if (statements.length === 0) {
110+
return '';
111+
}
112+
113+
return statements.map((statement) => statement.explainStatement(this.indentation)).join('\n\n') + '\n';
114+
}
115+
110116
private indent(description: string) {
111117
return this.indentation + description;
112118
}

src/Query/Query.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,11 @@ export class Query implements IQuery {
3434

3535
private _limit: number | undefined = undefined;
3636
private _taskGroupLimit: number | undefined = undefined;
37+
3738
private readonly _taskLayoutOptions: TaskLayoutOptions = new TaskLayoutOptions();
3839
private readonly _queryLayoutOptions: QueryLayoutOptions = new QueryLayoutOptions();
40+
public readonly layoutStatements: Statement[] = [];
41+
3942
private readonly _filters: Filter[] = [];
4043
private _error: string | undefined = undefined;
4144
private readonly _sorting: Sorter[] = [];
@@ -106,9 +109,11 @@ export class Query implements IQuery {
106109
switch (true) {
107110
case this.shortModeRegexp.test(line):
108111
this._queryLayoutOptions.shortMode = true;
112+
this.saveLayoutStatement(statement);
109113
break;
110114
case this.fullModeRegexp.test(line):
111115
this._queryLayoutOptions.shortMode = false;
116+
this.saveLayoutStatement(statement);
112117
break;
113118
case this.explainQueryRegexp.test(line):
114119
this._queryLayoutOptions.explainQuery = true;
@@ -124,7 +129,7 @@ export class Query implements IQuery {
124129
case this.parseGroupBy(line, statement):
125130
break;
126131
case this.hideOptionsRegexp.test(line):
127-
this.parseHideOptions(line);
132+
this.parseHideOptions(statement);
128133
break;
129134
case this.commentRegexp.test(line):
130135
// Comment lines are ignored
@@ -341,7 +346,8 @@ ${statement.explainStatement(' ')}
341346
}
342347
}
343348

344-
private parseHideOptions(line: string): void {
349+
private parseHideOptions(statement: Statement): void {
350+
const line = statement.anyPlaceholdersExpanded;
345351
const hideOptionsMatch = line.match(this.hideOptionsRegexp);
346352
if (hideOptionsMatch === null) {
347353
return;
@@ -350,14 +356,20 @@ ${statement.explainStatement(' ')}
350356
const option = hideOptionsMatch[2].toLowerCase();
351357

352358
if (parseQueryShowHideOptions(this._queryLayoutOptions, option, hide)) {
359+
this.saveLayoutStatement(statement);
353360
return;
354361
}
355362
if (parseTaskShowHideOptions(this._taskLayoutOptions, option, !hide)) {
363+
this.saveLayoutStatement(statement);
356364
return;
357365
}
358366
this.setError('do not understand hide/show option', new Statement(line, line));
359367
}
360368

369+
private saveLayoutStatement(statement: Statement) {
370+
this.layoutStatements.push(statement);
371+
}
372+
361373
private parseFilter(line: string, statement: Statement) {
362374
const filterOrError = FilterParser.parseFilter(line);
363375
if (filterOrError != null) {

tests/Query/Explain/DocsSamplesForExplain.test.explain_query_file_defaults_explanation.approved.explanation.text

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ Explanation of the Query File Defaults (from properties/frontmatter in the query
55

66
not done
77

8+
short mode
9+
10+
show tree
11+
812
Explanation of this Tasks code block query:
913

1014
No filters supplied. All tasks will match the query.

tests/Query/Explain/Explainer.test.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ limit groups 3
106106
107107
sort by path
108108
109+
show urgency
110+
111+
short mode
112+
109113
At most 50 tasks.
110114
111115
At most 3 tasks per group (if any "group by" options are supplied).
@@ -155,6 +159,10 @@ limit groups 3
155159
156160
sort by path
157161
162+
show urgency
163+
164+
short mode
165+
158166
At most 50 tasks.
159167
160168
At most 3 tasks per group (if any "group by" options are supplied).
@@ -312,6 +320,31 @@ describe('explain sorters', () => {
312320
});
313321
});
314322

323+
describe('explain layout instructions', () => {
324+
function explainLayout(source: string) {
325+
const query = new Query(source);
326+
return explainer.explainLayout(query);
327+
}
328+
329+
it('should explain hide due date', () => {
330+
expect(explainLayout('hide due date')).toEqual('hide due date\n');
331+
});
332+
333+
it('should explain show tree', () => {
334+
expect(explainLayout('show tree')).toEqual('show tree\n');
335+
});
336+
337+
it('should explain short mode', () => {
338+
expect(explainLayout('short')).toEqual('short\n');
339+
expect(explainLayout('short mode')).toEqual('short mode\n');
340+
});
341+
342+
it('should explain full mode', () => {
343+
expect(explainLayout('full')).toEqual('full\n');
344+
expect(explainLayout('full mode')).toEqual('full mode\n');
345+
});
346+
});
347+
315348
describe('explain limits', () => {
316349
it('should explain limit 5', () => {
317350
const source = 'limit 5';

tests/Query/QueryRendererHelper.test.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,44 @@ describe('explain', () => {
7474
7575
not done
7676
77+
short mode
78+
79+
show tree
80+
81+
show tags
82+
83+
show id
84+
85+
show depends on
86+
87+
show priority
88+
89+
show recurrence rule
90+
91+
show on completion
92+
93+
show created date
94+
95+
show start date
96+
97+
show scheduled date
98+
99+
show due date
100+
101+
show cancelled date
102+
103+
show done date
104+
105+
show urgency
106+
107+
show backlink
108+
109+
show edit button
110+
111+
show postpone button
112+
113+
show task count
114+
77115
Explanation of this Tasks code block query:
78116
79117
No filters supplied. All tasks will match the query.

0 commit comments

Comments
 (0)