Skip to content

Commit de61d8f

Browse files
authored
Merge pull request #3365 from obsidian-tasks-group/explain-remaining-instructions
feat: Explain 'ignore global filter'
2 parents 0aabc76 + aea2028 commit de61d8f

File tree

8 files changed

+72
-6
lines changed

8 files changed

+72
-6
lines changed

docs/Queries/Global Query.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ You can set a global query in the settings that Tasks will add to the start of a
3535
3636
If you need to ignore the Global Query in a given Tasks block you may add `ignore global query` instruction to any place of the block.
3737
38-
For example, this allows you to have your task seaches ignore certain folders by default. And then in few searches, you can enable searching for tasks in those folders.
38+
For example, this allows you to have your task searches ignore certain folders by default. And then in a few searches, you can enable searching for tasks in those folders.
3939
4040
> [!example]
4141
>
@@ -44,6 +44,9 @@ For example, this allows you to have your task seaches ignore certain folders by
4444
> ignore global query
4545
> ```
4646
47+
> [!note]
48+
> Any use of `ignore global query` inside the Global Query itself is harmless, but ignored.
49+
4750
> [!released]
4851
The `ignore global query` instruction was added in Tasks 4.6.0.
4952

src/Config/GlobalQuery.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ export class GlobalQuery {
4949
* @param tasksFile
5050
*/
5151
public query(tasksFile: OptionalTasksFile = undefined): Query {
52-
return new Query(this._source, tasksFile);
52+
const query = new Query(this._source, tasksFile);
53+
query.removeIllegalGlobalQueryInstructions();
54+
return query;
5355
}
5456

5557
/**

src/Query/Explain/Explainer.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export class Explainer {
3333
* - end with a single newline.
3434
*/
3535
const results: string[] = [];
36+
results.push(this.explainIgnoreGlobalQuery(query));
3637
results.push(this.explainFilters(query));
3738
results.push(this.explainGroups(query));
3839
results.push(this.explainSorters(query));
@@ -50,6 +51,13 @@ export class Explainer {
5051
return result;
5152
}
5253

54+
private explainIgnoreGlobalQuery(query: Query) {
55+
if (!query.ignoreGlobalQuery) {
56+
return '';
57+
}
58+
return this.indent('ignore global query\n');
59+
}
60+
5361
public explainFilters(query: Query) {
5462
if (query.filters.length === 0) {
5563
return this.indent('No filters supplied. All tasks will match the query.\n');

src/Query/Query.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,16 @@ export class Query implements IQuery {
9696
}
9797
}
9898

99+
/**
100+
* Remove any instructions that are not valid for Global Queries:
101+
*/
102+
public removeIllegalGlobalQueryInstructions() {
103+
// It does not make sense to use 'ignore global query'
104+
// in global queries: the value is ignored, and it would be confusing
105+
// for 'explain' output to report that it had been supplied:
106+
this._ignoreGlobalQuery = false;
107+
}
108+
99109
public get filePath(): string | undefined {
100110
return this.tasksFile?.path ?? undefined;
101111
}
@@ -117,6 +127,7 @@ export class Query implements IQuery {
117127
break;
118128
case this.explainQueryRegexp.test(line):
119129
this._queryLayoutOptions.explainQuery = true;
130+
// We intentionally do not explain the 'explain' statement, as it clutters up documentation.
120131
break;
121132
case this.ignoreGlobalQueryRegexp.test(line):
122133
this._ignoreGlobalQuery = true;

src/Query/QueryRendererHelper.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ export function explainResults(
4040
}
4141

4242
const explainer = new Explainer(' ');
43-
function explainQuery(label: string, globalQueryQuery: Query) {
44-
return `${label}:\n\n${explainer.explainQuery(globalQueryQuery)}`;
43+
function explainQuery(label: string, query: Query) {
44+
return `${label}:\n\n${explainer.explainQuery(query)}`;
4545
}
4646

4747
const tasksBlockQuery = new Query(source, tasksFile);

tests/Config/GlobalQuery.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ describe('GlobalQuery tests', () => {
3232
expect(globalQuery.query().source).toEqual('# this should be the new global query');
3333
});
3434

35+
it('should ignore any "ignore global query" instruction', () => {
36+
const globalQuery = new GlobalQuery('ignore global query');
37+
38+
expect(globalQuery.query().ignoreGlobalQuery).toEqual(false);
39+
});
40+
3541
it.each(['', ' ', '\n', '\n \n ', ' \n \n'])(
3642
'should have no instructions if only line breaks and spaces were set in the query',
3743
(globalQuerySource) => {

tests/Query/Explain/Explainer.test.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ show urgency
6565
short mode
6666
limit 50
6767
limit groups 3
68+
69+
ignore global query
6870
`;
6971

7072
it('all types of instruction - not indented', () => {
@@ -73,7 +75,9 @@ limit groups 3
7375

7476
const query = new Query(sampleOfAllInstructionTypes, new TasksFile('sample.md'));
7577
expect(explainer.explainQuery(query)).toMatchInlineSnapshot(`
76-
"filter by function \\
78+
"ignore global query
79+
80+
filter by function \\
7781
task.path === '{{query.file.path}}'
7882
=>
7983
filter by function task.path === '{{query.file.path}}' =>
@@ -126,7 +130,9 @@ limit groups 3
126130
const query = new Query(sampleOfAllInstructionTypes, new TasksFile('sample.md'));
127131
const indentedExplainer = new Explainer(' ');
128132
expect(indentedExplainer.explainQuery(query)).toMatchInlineSnapshot(`
129-
" filter by function \\
133+
" ignore global query
134+
135+
filter by function \\
130136
task.path === '{{query.file.path}}'
131137
=>
132138
filter by function task.path === '{{query.file.path}}' =>
@@ -343,6 +349,11 @@ describe('explain layout instructions', () => {
343349
expect(explainLayout('full')).toEqual('full\n');
344350
expect(explainLayout('full mode')).toEqual('full mode\n');
345351
});
352+
353+
it('should NOT explain explain', () => {
354+
// Intentionally do not explain the 'explain' instruction, as it just clutters up the documentation.
355+
expect(explainLayout('explain')).toEqual('');
356+
});
346357
});
347358

348359
describe('explain limits', () => {

tests/Query/QueryRendererHelper.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,8 @@ describe('explain', () => {
148148
expect(explainResults(query.source, new GlobalFilter(), globalQuery)).toMatchInlineSnapshot(`
149149
"Explanation of this Tasks code block query:
150150
151+
ignore global query
152+
151153
No filters supplied. All tasks will match the query.
152154
"
153155
`);
@@ -163,6 +165,8 @@ describe('explain', () => {
163165
expect(explainResults(query.source, new GlobalFilter(), globalQuery, queryFile)).toMatchInlineSnapshot(`
164166
"Explanation of the Query File Defaults (from properties/frontmatter in the query's file):
165167
168+
ignore global query
169+
166170
description includes I came from the TQ_extra_instructions property
167171
168172
Explanation of this Tasks code block query:
@@ -171,6 +175,27 @@ describe('explain', () => {
171175
"
172176
`);
173177
});
178+
179+
it('should discard "ignore global query" from explanation if present in the global query itself', () => {
180+
const globalQuery = new GlobalQuery('ignore global query');
181+
const querySource = 'description includes from query';
182+
183+
const explanation = explainResults(querySource, new GlobalFilter(), globalQuery);
184+
185+
// It does not make sense to put 'ignore global query' in the global query.
186+
// If the user did so, we should ignore it in any explanations.
187+
expect(explanation).not.toContain('ignore global query');
188+
expect(explanation).toMatchInlineSnapshot(`
189+
"Explanation of the global query:
190+
191+
No filters supplied. All tasks will match the query.
192+
193+
Explanation of this Tasks code block query:
194+
195+
description includes from query
196+
"
197+
`);
198+
});
174199
});
175200

176201
/**

0 commit comments

Comments
 (0)