Skip to content

Commit 20dbc2d

Browse files
authored
Merge pull request #2539 from obsidian-tasks-group/explain-sortby
feat: Make 'explain' show 'sort by' commands
2 parents fa8562d + 3c9d30e commit 20dbc2d

26 files changed

+128
-6
lines changed

docs/Introduction.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ _In recent [releases](https://github.com/obsidian-tasks-group/obsidian-tasks/rel
1414
-->
1515

1616
- X.Y.Z: 🔥 Add [[Layout#Full Mode|'full mode']] to turn off `short mode`.
17-
- X.Y.Z: 🔥 Add any [[Grouping|'group by']] instructions to [[Explaining Queries|explain]] output.
17+
- X.Y.Z: 🔥 Add any [[Grouping|'group by']] and [[Sorting|'sort by']] instructions to [[Explaining Queries|explain]] output.
1818
- 5.3.0: 🔥 Add [[Postponing|postpone button]] to Tasks query results.
1919
- 5.3.0: 🔥 Add [[Toggling and Editing Statuses#'Change task status' context menu|'change task status' menu]] to Reading mode and Tasks query results.
2020
- 5.3.0: 🔥 Add documentation section about [[About Editing|editing tasks]].

docs/Queries/Explaining Queries.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ 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 [[Grouping|'group by']] instructions are listed (since Tasks X.Y.Z)
24+
- Any [[Sorting|'sort by']] instructions are listed (since Tasks X.Y.Z)
2425

2526
## Examples
2627

@@ -53,6 +54,8 @@ Explanation of this Tasks code block query:
5354
due date is before 2022-10-22 (Saturday 22nd October 2022)
5455
5556
No grouping instructions supplied.
57+
58+
No sorting instructions supplied.
5659
```
5760
<!-- endSnippet -->
5861

@@ -84,6 +87,8 @@ Explanation of this Tasks code block query:
8487
using regex: '^Root\/Sub-Folder\/Sample File\.md' with flag 'i'
8588
8689
No grouping instructions supplied.
90+
91+
No sorting instructions supplied.
8792
```
8893
<!-- endSnippet -->
8994

@@ -113,6 +118,8 @@ Explanation of this Tasks code block query:
113118
is recurring
114119
115120
No grouping instructions supplied.
121+
122+
No sorting instructions supplied.
116123
```
117124
<!-- endSnippet -->
118125

@@ -157,6 +164,8 @@ Explanation of this Tasks code block query:
157164
description includes 7
158165
159166
No grouping instructions supplied.
167+
168+
No sorting instructions supplied.
160169
```
161170
<!-- endSnippet -->
162171

@@ -194,6 +203,8 @@ Explanation of the global query:
194203
195204
No grouping instructions supplied.
196205
206+
No sorting instructions supplied.
207+
197208
At most 50 tasks.
198209
199210
Explanation of this Tasks code block query:
@@ -206,6 +217,8 @@ Explanation of this Tasks code block query:
206217
2022-10-30 (Sunday 30th October 2022) inclusive
207218
208219
No grouping instructions supplied.
220+
221+
No sorting instructions supplied.
209222
```
210223
<!-- endSnippet -->
211224

@@ -245,6 +258,8 @@ Explanation of this Tasks code block query:
245258
description includes Some Cryptic String
246259
247260
No grouping instructions supplied.
261+
262+
No sorting instructions supplied.
248263
```
249264
<!-- endSnippet -->
250265

docs/Queries/Line Continuations.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ Explanation of this Tasks code block query:
3737
priority is lowest
3838
3939
No grouping instructions supplied.
40+
41+
No sorting instructions supplied.
4042
```
4143
<!-- endSnippet -->
4244

@@ -77,6 +79,8 @@ Explanation of this Tasks code block query:
7779
description includes \
7880
7981
No grouping instructions supplied.
82+
83+
No sorting instructions supplied.
8084
```
8185
<!-- endSnippet -->
8286

docs/Queries/Regular Expressions.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ Explanation of this Tasks code block query:
9999
using regex: '^Root\/Sub-Folder\/Sample File\.md' with flag 'i'
100100
101101
No grouping instructions supplied.
102+
103+
No sorting instructions supplied.
102104
```
103105
<!-- endSnippet -->
104106

docs/Scripting/Placeholders.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ Explanation of this Tasks code block query:
5454
description includes Some Cryptic String
5555
5656
No grouping instructions supplied.
57+
58+
No sorting instructions supplied.
5759
```
5860
<!-- endSnippet -->
5961

src/Query/Explain/Explainer.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export class Explainer {
3434
const results: string[] = [];
3535
results.push(this.explainFilters(query));
3636
results.push(this.explainGroups(query));
37+
results.push(this.explainSorters(query));
3738
results.push(this.explainQueryLimits(query));
3839
results.push(this.explainDebugSettings());
3940

@@ -73,6 +74,19 @@ export class Explainer {
7374
return result;
7475
}
7576

77+
public explainSorters(query: Query) {
78+
const numberOfSorters = query.sorting.length;
79+
if (numberOfSorters === 0) {
80+
return this.indent('No sorting instructions supplied.\n');
81+
}
82+
83+
let result = '';
84+
for (let i = 0; i < numberOfSorters; i++) {
85+
result += this.indentation + query.sorting[i].instruction + '\n';
86+
}
87+
return result;
88+
}
89+
7690
public explainQueryLimits(query: Query) {
7791
function getPluralisedText(limit: number) {
7892
let text = `At most ${limit} task`;

src/Query/Filter/Field.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,21 @@ export abstract class Field {
175175
return new RegExp(`^sort by ${this.fieldNameSingularEscaped()}( reverse)?`, 'i');
176176
}
177177

178+
/**
179+
* Reconstruct a 'sorter by' instruction to use for sorting of this field.
180+
*
181+
* This is used to simplify the construction of {@link Sorter} objects.
182+
* @param reverse
183+
* @protected
184+
*/
185+
protected sorterInstruction(reverse: boolean) {
186+
let instruction = `sort by ${this.fieldNameSingular()}`;
187+
if (reverse) {
188+
instruction += ' reverse';
189+
}
190+
return instruction;
191+
}
192+
178193
/**
179194
* Return a function to compare two Task objects, for use in sorting by this field's value.
180195
*
@@ -190,7 +205,7 @@ export abstract class Field {
190205
* @param reverse - false for normal sort order, true for reverse sort order.
191206
*/
192207
public createSorter(reverse: boolean): Sorter {
193-
return new Sorter(this.fieldNameSingular(), this.comparator(), reverse);
208+
return new Sorter(this.sorterInstruction(reverse), this.fieldNameSingular(), this.comparator(), reverse);
194209
}
195210

196211
/**

src/Query/Filter/TagsField.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export class TagsField extends MultiTextField {
7272
const reverse = !!match[1];
7373
const propertyInstance = isNaN(+match[2]) ? 1 : +match[2];
7474
const comparator = TagsField.makeCompareByTagComparator(propertyInstance);
75-
return new Sorter(this.fieldNameSingular(), comparator, reverse);
75+
return new Sorter(line, this.fieldNameSingular(), comparator, reverse);
7676
}
7777

7878
/**

src/Query/Sorter.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,21 @@ export type Comparator = (a: Task, b: Task) => number;
1616
* It stores the comparison function as a {@link Comparator}.
1717
*/
1818
export class Sorter {
19+
public readonly instruction: string;
1920
public readonly property: string;
2021
public readonly comparator: Comparator;
2122

2223
/**
2324
* Constructor.
2425
*
26+
* @param instruction - the query instruction that created this object
2527
* @param property - the name of the property.
2628
* @param comparator - {@link Comparator} function, for sorting in the standard direction.
2729
* If `reverse` is true, it will automatically be converted to reverse the sort direction.
2830
* @param reverse - whether the sort order should be reversed.
2931
*/
30-
constructor(property: string, comparator: Comparator, reverse: boolean) {
32+
constructor(instruction: string, property: string, comparator: Comparator, reverse: boolean) {
33+
this.instruction = instruction;
3134
this.property = property;
3235
this.comparator = Sorter.maybeReverse(reverse, comparator);
3336
}

tests/Config/DebugSettings.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ describe('DebugSettings', () => {
3939
4040
No grouping instructions supplied.
4141
42+
sort by status
43+
4244
NOTE: All sort instructions, including default sort order, are disabled, due to 'ignoreSortInstructions' setting.
4345
"
4446
`);

0 commit comments

Comments
 (0)