Repository: obsidian-tasks-group/obsidian-tasks
Pull request #2538 (2023-12-26 21:02:50)

feat: Use indentation to separate global & code block query explanation
<!--- Provide a general summary of your changes in the Title above -->

# Description

Use indentation in the `explain` output, so that it is easier to see which instructions are from the Global Query, and which from the Tasks Query Block.

## Motivation and Context

I've been finding that it's quite hard to see the end of the Global Query explanation and the start of the Tasks Query Block explanation in my main vault.

## How has this been tested?

- Updating and adding automated tests
- Exploratory testing in the demo vault.

## Screenshots (if appropriate)


### Before:

```text
Explanation of the global query:

heading includes tasks

No grouping instructions supplied.

At most 50 tasks.

Explanation of this Tasks code block query:

not done

due next week =>
  due date is between:
    2022-10-24 (Monday 24th October 2022) and
    2022-10-30 (Sunday 30th October 2022) inclusive

No grouping instructions supplied.
```

### After

```text
Explanation of the global query:

  heading includes tasks

  No grouping instructions supplied.

  At most 50 tasks.

Explanation of this Tasks code block query:

  not done

  due next week =>
    due date is between:
      2022-10-24 (Monday 24th October 2022) and
      2022-10-30 (Sunday 30th October 2022) inclusive

  No grouping instructions supplied.
```

## Types of changes

<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->

Changes visible to users:

- [x] **New feature** (prefix: `feat` - non-breaking change which adds functionality)
- [x] **Documentation** (prefix: `docs` - improvements to any documentation content **for users**)

Internal changes:

- [x] **Refactor** (prefix: `refactor` - non-breaking change which only improves the design or structure of existing code, and making no changes to its external behaviour)
- [x] **Tests** (prefix: `test` - additions and improvements to unit tests and the smoke tests)

## Checklist

<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->

- [x] My code follows the code style of this project and passes `yarn run lint`.
- [x] My change requires a change to the documentation.
- [x] I have [updated the documentation](https://publish.obsidian.md/tasks-contributing/Documentation/About+Documentation) accordingly.
- [x] My change has adequate [Unit Test coverage](https://publish.obsidian.md/tasks-contributing/Testing/About+Testing).

## Terms

<!--
By submitting this pull request, you must agree to follow our
[contributing guide](https://publish.obsidian.md/tasks-contributing) and
[Code of Conduct](https://github.com/obsidian-tasks-group/obsidian-tasks/blob/main/CODE_OF_CONDUCT.md).
Put an x in the boxes to confirm you agree.
-->

- [x] My contribution follow this project's [contributing guide](https://publish.obsidian.md/tasks-contributing)
- [x] I agree to follow this project's [Code of Conduct](https://github.com/obsidian-tasks-group/obsidian-tasks/blob/main/CODE_OF_CONDUCT.md)



Patch:
diff --git a/docs/Queries/Explaining Queries.md b/docs/Queries/Explaining Queries.md
index b5177777..510582a3 100644
--- a/docs/Queries/Explaining Queries.md
+++ b/docs/Queries/Explaining Queries.md
@@ -43,16 +43,16 @@ the results begin with the following, on `2022-10-21`:
 ```text
 Explanation of this Tasks code block query:
 
-starts after 2 years ago =>
-  start date is after 2020-10-21 (Wednesday 21st October 2020) OR no start date
+  starts after 2 years ago =>
+    start date is after 2020-10-21 (Wednesday 21st October 2020) OR no start date
 
-scheduled after 1 week ago =>
-  scheduled date is after 2022-10-14 (Friday 14th October 2022)
+  scheduled after 1 week ago =>
+    scheduled date is after 2022-10-14 (Friday 14th October 2022)
 
-due before tomorrow =>
-  due date is before 2022-10-22 (Saturday 22nd October 2022)
+  due before tomorrow =>
+    due date is before 2022-10-22 (Saturday 22nd October 2022)
 
-No grouping instructions supplied.
+  No grouping instructions supplied.
 ```
 <!-- endSnippet -->
 
@@ -80,10 +80,10 @@ the results begin with the following:
 ```text
 Explanation of this Tasks code block query:
 
-path regex matches /^Root/Sub-Folder/Sample File\.md/i =>
-  using regex:     '^Root\/Sub-Folder\/Sample File\.md' with flag 'i'
+  path regex matches /^Root/Sub-Folder/Sample File\.md/i =>
+    using regex:     '^Root\/Sub-Folder\/Sample File\.md' with flag 'i'
 
-No grouping instructions supplied.
+  No grouping instructions supplied.
 ```
 <!-- endSnippet -->
 
@@ -105,14 +105,14 @@ the results begin with the following, on `2022-10-21`:
 ```text
 Explanation of this Tasks code block query:
 
-not done
+  not done
 
-(due before tomorrow) AND (is recurring) =>
-  AND (All of):
-    due date is before 2022-10-22 (Saturday 22nd October 2022)
-    is recurring
+  (due before tomorrow) AND (is recurring) =>
+    AND (All of):
+      due date is before 2022-10-22 (Saturday 22nd October 2022)
+      is recurring
 
-No grouping instructions supplied.
+  No grouping instructions supplied.
 ```
 <!-- endSnippet -->
 
@@ -142,21 +142,21 @@ the results begin with the following, on `2022-10-21`:
 ```text
 Explanation of this Tasks code block query:
 
-( (description includes 1) AND (description includes 2) AND (description includes 3) ) OR ( (description includes 5) AND (description includes 6) AND (description includes 7) ) AND NOT (description includes 7) =>
-  OR (At least one of):
-    AND (All of):
-      description includes 1
-      description includes 2
-      description includes 3
-    AND (All of):
+  ( (description includes 1) AND (description includes 2) AND (description includes 3) ) OR ( (description includes 5) AND (description includes 6) AND (description includes 7) ) AND NOT (description includes 7) =>
+    OR (At least one of):
       AND (All of):
-        description includes 5
-        description includes 6
-        description includes 7
-      NOT:
-        description includes 7
-
-No grouping instructions supplied.
+        description includes 1
+        description includes 2
+        description includes 3
+      AND (All of):
+        AND (All of):
+          description includes 5
+          description includes 6
+          description includes 7
+        NOT:
+          description includes 7
+
+  No grouping instructions supplied.
 ```
 <!-- endSnippet -->
 
@@ -190,22 +190,22 @@ the results begin with the following, on `2022-10-21`:
 ```text
 Explanation of the global query:
 
-heading includes tasks
+  heading includes tasks
 
-No grouping instructions supplied.
+  No grouping instructions supplied.
 
-At most 50 tasks.
+  At most 50 tasks.
 
 Explanation of this Tasks code block query:
 
-not done
+  not done
 
-due next week =>
-  due date is between:
-    2022-10-24 (Monday 24th October 2022) and
-    2022-10-30 (Sunday 30th October 2022) inclusive
+  due next week =>
+    due date is between:
+      2022-10-24 (Monday 24th October 2022) and
+      2022-10-30 (Sunday 30th October 2022) inclusive
 
-No grouping instructions supplied.
+  No grouping instructions supplied.
 ```
 <!-- endSnippet -->
 
@@ -234,17 +234,17 @@ the results begin with the following:
 ```text
 Explanation of this Tasks code block query:
 
-path includes some/sample/file path.md
+  path includes some/sample/file path.md
 
-root includes some/
+  root includes some/
 
-folder includes some/sample/
+  folder includes some/sample/
 
-filename includes file path.md
+  filename includes file path.md
 
-description includes Some Cryptic String 
+  description includes Some Cryptic String 
 
-No grouping instructions supplied.
+  No grouping instructions supplied.
 ```
 <!-- endSnippet -->
 
diff --git a/docs/Queries/Line Continuations.md b/docs/Queries/Line Continuations.md
index f4bf8844..7af5e8c4 100644
--- a/docs/Queries/Line Continuations.md
+++ b/docs/Queries/Line Continuations.md
@@ -31,12 +31,12 @@ explain
 ```text
 Explanation of this Tasks code block query:
 
-(priority is highest) OR (priority is lowest) =>
-  OR (At least one of):
-    priority is highest
-    priority is lowest
+  (priority is highest) OR (priority is lowest) =>
+    OR (At least one of):
+      priority is highest
+      priority is lowest
 
-No grouping instructions supplied.
+  No grouping instructions supplied.
 ```
 <!-- endSnippet -->
 
@@ -74,9 +74,9 @@ explain
 ```text
 Explanation of this Tasks code block query:
 
-description includes \
+  description includes \
 
-No grouping instructions supplied.
+  No grouping instructions supplied.
 ```
 <!-- endSnippet -->
 
diff --git a/docs/Queries/Regular Expressions.md b/docs/Queries/Regular Expressions.md
index d0234df6..dc927055 100644
--- a/docs/Queries/Regular Expressions.md
+++ b/docs/Queries/Regular Expressions.md
@@ -95,10 +95,10 @@ path regex matches /^Root/Sub-Folder/Sample File\.md/i
 ```text
 Explanation of this Tasks code block query:
 
-path regex matches /^Root/Sub-Folder/Sample File\.md/i =>
-  using regex:     '^Root\/Sub-Folder\/Sample File\.md' with flag 'i'
+  path regex matches /^Root/Sub-Folder/Sample File\.md/i =>
+    using regex:     '^Root\/Sub-Folder\/Sample File\.md' with flag 'i'
 
-No grouping instructions supplied.
+  No grouping instructions supplied.
 ```
 <!-- endSnippet -->
 
diff --git a/docs/Scripting/Placeholders.md b/docs/Scripting/Placeholders.md
index ac44d588..f00c2f83 100644
--- a/docs/Scripting/Placeholders.md
+++ b/docs/Scripting/Placeholders.md
@@ -43,17 +43,17 @@ the results begin with the following, which demonstrates how each value inside `
 ```text
 Explanation of this Tasks code block query:
 
-path includes some/sample/file path.md
+  path includes some/sample/file path.md
 
-root includes some/
+  root includes some/
 
-folder includes some/sample/
+  folder includes some/sample/
 
-filename includes file path.md
+  filename includes file path.md
 
-description includes Some Cryptic String 
+  description includes Some Cryptic String 
 
-No grouping instructions supplied.
+  No grouping instructions supplied.
 ```
 <!-- endSnippet -->
 
diff --git a/src/Query/Explain/Explainer.ts b/src/Query/Explain/Explainer.ts
index 7c71d49f..076f02d8 100644
--- a/src/Query/Explain/Explainer.ts
+++ b/src/Query/Explain/Explainer.ts
@@ -2,6 +2,16 @@ import { getSettings } from '../../Config/Settings';
 import type { Query } from '../Query';
 
 export class Explainer {
+    private readonly indentation: string;
+
+    /**
+     * Constructor.
+     * @param indentation - the indentation to use for the output. Defaults to 'not indented'.
+     */
+    constructor(indentation: string = '') {
+        this.indentation = indentation;
+    }
+
     /**
      * Generate a text description of the contents of a query.
      *
@@ -40,12 +50,12 @@ export class Explainer {
     public explainFilters(query: Query) {
         const numberOfFilters = query.filters.length;
         if (numberOfFilters === 0) {
-            return 'No filters supplied. All tasks will match the query.\n';
+            return this.indent('No filters supplied. All tasks will match the query.\n');
         }
 
         return query.filters
             .map((filter) => {
-                return filter.explainFilterIndented('');
+                return filter.explainFilterIndented(this.indentation);
             })
             .join('\n');
     }
@@ -53,12 +63,12 @@ export class Explainer {
     public explainGroups(query: Query) {
         const numberOfGroups = query.grouping.length;
         if (numberOfGroups === 0) {
-            return 'No grouping instructions supplied.\n';
+            return this.indent('No grouping instructions supplied.\n');
         }
 
         let result = '';
         for (let i = 0; i < numberOfGroups; i++) {
-            result += query.grouping[i].instruction + '\n';
+            result += this.indentation + query.grouping[i].instruction + '\n';
         }
         return result;
     }
@@ -76,13 +86,13 @@ export class Explainer {
 
         if (query.limit !== undefined) {
             const result = getPluralisedText(query.limit) + '.\n';
-            results.push(result);
+            results.push(this.indent(result));
         }
 
         if (query.taskGroupLimit !== undefined) {
             const result =
                 getPluralisedText(query.taskGroupLimit) + ' per group (if any "group by" options are supplied).\n';
-            results.push(result);
+            results.push(this.indent(result));
         }
         return results.join('\n');
     }
@@ -91,9 +101,14 @@ export class Explainer {
         let result = '';
         const { debugSettings } = getSettings();
         if (debugSettings.ignoreSortInstructions) {
-            result +=
-                "NOTE: All sort instructions, including default sort order, are disabled, due to 'ignoreSortInstructions' setting.\n";
+            result += this.indent(
+                "NOTE: All sort instructions, including default sort order, are disabled, due to 'ignoreSortInstructions' setting.\n",
+            );
         }
         return result;
     }
+
+    private indent(description: string) {
+        return this.indentation + description;
+    }
 }
diff --git a/src/Query/Filter/Filter.ts b/src/Query/Filter/Filter.ts
index c7b4c4aa..2e90f43c 100644
--- a/src/Query/Filter/Filter.ts
+++ b/src/Query/Filter/Filter.ts
@@ -38,7 +38,7 @@ export class Filter {
         if (unindentedExplanation === this.instruction) {
             return `${indent}${this.instruction}\n`;
         } else {
-            return `${indent}${this.instruction} =>\n${explanation.asString('  ')}\n`;
+            return `${indent}${this.instruction} =>\n${explanation.asString(indent + '  ')}\n`;
         }
     }
 }
diff --git a/src/lib/QueryRendererHelper.ts b/src/lib/QueryRendererHelper.ts
index 1221f2d8..728aaecd 100644
--- a/src/lib/QueryRendererHelper.ts
+++ b/src/lib/QueryRendererHelper.ts
@@ -1,6 +1,7 @@
 import type { GlobalFilter } from '../Config/GlobalFilter';
 import type { GlobalQuery } from '../Config/GlobalQuery';
 import { Query } from '../Query/Query';
+import { Explainer } from '../Query/Explain/Explainer';
 
 /**
  * @summary
@@ -36,15 +37,17 @@ export function explainResults(
         result += `Only tasks containing the global filter '${globalFilter.get()}'.\n\n`;
     }
 
+    const explainer = new Explainer('  ');
     const tasksBlockQuery = new Query(source, path);
 
     if (!tasksBlockQuery.ignoreGlobalQuery) {
         if (globalQuery.hasInstructions()) {
-            result += `Explanation of the global query:\n\n${globalQuery.query(path).explainQuery()}\n`;
+            const globalQueryQuery = globalQuery.query(path);
+            result += `Explanation of the global query:\n\n${explainer.explainQuery(globalQueryQuery)}\n`;
         }
     }
 
-    result += `Explanation of this Tasks code block query:\n\n${tasksBlockQuery.explainQuery()}`;
+    result += `Explanation of this Tasks code block query:\n\n${explainer.explainQuery(tasksBlockQuery)}`;
 
     return result;
 }


Test patch:
diff --git a/tests/Query/Explain/DocsSamplesForExplain.test.explain_boolean_combinations.approved.explanation.text b/tests/Query/Explain/DocsSamplesForExplain.test.explain_boolean_combinations.approved.explanation.text
index d31a329a..9bda53ad 100644
--- a/tests/Query/Explain/DocsSamplesForExplain.test.explain_boolean_combinations.approved.explanation.text
+++ b/tests/Query/Explain/DocsSamplesForExplain.test.explain_boolean_combinations.approved.explanation.text
@@ -1,10 +1,10 @@
 Explanation of this Tasks code block query:
 
-not done
+  not done
 
-(due before tomorrow) AND (is recurring) =>
-  AND (All of):
-    due date is before 2022-10-22 (Saturday 22nd October 2022)
-    is recurring
+  (due before tomorrow) AND (is recurring) =>
+    AND (All of):
+      due date is before 2022-10-22 (Saturday 22nd October 2022)
+      is recurring
 
-No grouping instructions supplied.
+  No grouping instructions supplied.
diff --git a/tests/Query/Explain/DocsSamplesForExplain.test.explain_expands_dates.approved.explanation.text b/tests/Query/Explain/DocsSamplesForExplain.test.explain_expands_dates.approved.explanation.text
index 342edf65..6d84d9fd 100644
--- a/tests/Query/Explain/DocsSamplesForExplain.test.explain_expands_dates.approved.explanation.text
+++ b/tests/Query/Explain/DocsSamplesForExplain.test.explain_expands_dates.approved.explanation.text
@@ -1,12 +1,12 @@
 Explanation of this Tasks code block query:
 
-starts after 2 years ago =>
-  start date is after 2020-10-21 (Wednesday 21st October 2020) OR no start date
+  starts after 2 years ago =>
+    start date is after 2020-10-21 (Wednesday 21st October 2020) OR no start date
 
-scheduled after 1 week ago =>
-  scheduled date is after 2022-10-14 (Friday 14th October 2022)
+  scheduled after 1 week ago =>
+    scheduled date is after 2022-10-14 (Friday 14th October 2022)
 
-due before tomorrow =>
-  due date is before 2022-10-22 (Saturday 22nd October 2022)
+  due before tomorrow =>
+    due date is before 2022-10-22 (Saturday 22nd October 2022)
 
-No grouping instructions supplied.
+  No grouping instructions supplied.
diff --git a/tests/Query/Explain/DocsSamplesForExplain.test.explain_explains_task_block_with_global_query_active.approved.explanation.text b/tests/Query/Explain/DocsSamplesForExplain.test.explain_explains_task_block_with_global_query_active.approved.explanation.text
index 7ce44753..c8dea8db 100644
--- a/tests/Query/Explain/DocsSamplesForExplain.test.explain_explains_task_block_with_global_query_active.approved.explanation.text
+++ b/tests/Query/Explain/DocsSamplesForExplain.test.explain_explains_task_block_with_global_query_active.approved.explanation.text
@@ -1,18 +1,18 @@
 Explanation of the global query:
 
-heading includes tasks
+  heading includes tasks
 
-No grouping instructions supplied.
+  No grouping instructions supplied.
 
-At most 50 tasks.
+  At most 50 tasks.
 
 Explanation of this Tasks code block query:
 
-not done
+  not done
 
-due next week =>
-  due date is between:
-    2022-10-24 (Monday 24th October 2022) and
-    2022-10-30 (Sunday 30th October 2022) inclusive
+  due next week =>
+    due date is between:
+      2022-10-24 (Monday 24th October 2022) and
+      2022-10-30 (Sunday 30th October 2022) inclusive
 
-No grouping instructions supplied.
+  No grouping instructions supplied.
diff --git a/tests/Query/Explain/DocsSamplesForExplain.test.explain_line_continuation_-_double_slash.approved.explanation.text b/tests/Query/Explain/DocsSamplesForExplain.test.explain_line_continuation_-_double_slash.approved.explanation.text
index 9ee57de7..75ba68a7 100644
--- a/tests/Query/Explain/DocsSamplesForExplain.test.explain_line_continuation_-_double_slash.approved.explanation.text
+++ b/tests/Query/Explain/DocsSamplesForExplain.test.explain_line_continuation_-_double_slash.approved.explanation.text
@@ -1,5 +1,5 @@
 Explanation of this Tasks code block query:
 
-description includes \
+  description includes \
 
-No grouping instructions supplied.
+  No grouping instructions supplied.
diff --git a/tests/Query/Explain/DocsSamplesForExplain.test.explain_line_continuation_-_single_slash.approved.explanation.text b/tests/Query/Explain/DocsSamplesForExplain.test.explain_line_continuation_-_single_slash.approved.explanation.text
index 89f6b187..c45ca577 100644
--- a/tests/Query/Explain/DocsSamplesForExplain.test.explain_line_continuation_-_single_slash.approved.explanation.text
+++ b/tests/Query/Explain/DocsSamplesForExplain.test.explain_line_continuation_-_single_slash.approved.explanation.text
@@ -1,8 +1,8 @@
 Explanation of this Tasks code block query:
 
-(priority is highest) OR (priority is lowest) =>
-  OR (At least one of):
-    priority is highest
-    priority is lowest
+  (priority is highest) OR (priority is lowest) =>
+    OR (At least one of):
+      priority is highest
+      priority is lowest
 
-No grouping instructions supplied.
+  No grouping instructions supplied.
diff --git a/tests/Query/Explain/DocsSamplesForExplain.test.explain_nested_boolean_combinations.approved.explanation.text b/tests/Query/Explain/DocsSamplesForExplain.test.explain_nested_boolean_combinations.approved.explanation.text
index 27b78b58..262203b3 100644
--- a/tests/Query/Explain/DocsSamplesForExplain.test.explain_nested_boolean_combinations.approved.explanation.text
+++ b/tests/Query/Explain/DocsSamplesForExplain.test.explain_nested_boolean_combinations.approved.explanation.text
@@ -1,17 +1,17 @@
 Explanation of this Tasks code block query:
 
-( (description includes 1) AND (description includes 2) AND (description includes 3) ) OR ( (description includes 5) AND (description includes 6) AND (description includes 7) ) AND NOT (description includes 7) =>
-  OR (At least one of):
-    AND (All of):
-      description includes 1
-      description includes 2
-      description includes 3
-    AND (All of):
+  ( (description includes 1) AND (description includes 2) AND (description includes 3) ) OR ( (description includes 5) AND (description includes 6) AND (description includes 7) ) AND NOT (description includes 7) =>
+    OR (At least one of):
       AND (All of):
-        description includes 5
-        description includes 6
-        description includes 7
-      NOT:
-        description includes 7
+        description includes 1
+        description includes 2
+        description includes 3
+      AND (All of):
+        AND (All of):
+          description includes 5
+          description includes 6
+          description includes 7
+        NOT:
+          description includes 7
 
-No grouping instructions supplied.
+  No grouping instructions supplied.
diff --git a/tests/Query/Explain/DocsSamplesForExplain.test.explain_placeholders.approved.explanation.text b/tests/Query/Explain/DocsSamplesForExplain.test.explain_placeholders.approved.explanation.text
index 17a4a87b..2fbad4f5 100644
--- a/tests/Query/Explain/DocsSamplesForExplain.test.explain_placeholders.approved.explanation.text
+++ b/tests/Query/Explain/DocsSamplesForExplain.test.explain_placeholders.approved.explanation.text
@@ -1,13 +1,13 @@
 Explanation of this Tasks code block query:
 
-path includes some/sample/file path.md
+  path includes some/sample/file path.md
 
-root includes some/
+  root includes some/
 
-folder includes some/sample/
+  folder includes some/sample/
 
-filename includes file path.md
+  filename includes file path.md
 
-description includes Some Cryptic String 
+  description includes Some Cryptic String 
 
-No grouping instructions supplied.
+  No grouping instructions supplied.
diff --git a/tests/Query/Explain/DocsSamplesForExplain.test.explain_regular_expression.approved.explanation.text b/tests/Query/Explain/DocsSamplesForExplain.test.explain_regular_expression.approved.explanation.text
index c65bc56d..18a64def 100644
--- a/tests/Query/Explain/DocsSamplesForExplain.test.explain_regular_expression.approved.explanation.text
+++ b/tests/Query/Explain/DocsSamplesForExplain.test.explain_regular_expression.approved.explanation.text
@@ -1,6 +1,6 @@
 Explanation of this Tasks code block query:
 
-path regex matches /^Root/Sub-Folder/Sample File\.md/i =>
-  using regex:     '^Root\/Sub-Folder\/Sample File\.md' with flag 'i'
+  path regex matches /^Root/Sub-Folder/Sample File\.md/i =>
+    using regex:     '^Root\/Sub-Folder\/Sample File\.md' with flag 'i'
 
-No grouping instructions supplied.
+  No grouping instructions supplied.
diff --git a/tests/Query/Explain/Explainer.test.ts b/tests/Query/Explain/Explainer.test.ts
index 1c0dd179..9cce2393 100644
--- a/tests/Query/Explain/Explainer.test.ts
+++ b/tests/Query/Explain/Explainer.test.ts
@@ -33,11 +33,7 @@ describe('explain errors', () => {
 });
 
 describe('explain everything', () => {
-    it('all types of instruction', () => {
-        // Disable sort instructions
-        updateSettings({ debugSettings: new DebugSettings(true) });
-
-        const source = `
+    const sampleOfAllInstructionTypes = `
 not done
 (has start date) AND (description includes some)
 
@@ -52,7 +48,12 @@ short mode
 limit 50
 limit groups 3
 `;
-        const query = new Query(source);
+
+    it('all types of instruction - not indented', () => {
+        // Disable sort instructions
+        updateSettings({ debugSettings: new DebugSettings(true) });
+
+        const query = new Query(sampleOfAllInstructionTypes);
         expect(explainer.explainQuery(query)).toMatchInlineSnapshot(`
             "not done
 
@@ -72,6 +73,32 @@ limit groups 3
             "
         `);
     });
+
+    it('all types of instruction - indented', () => {
+        // Disable sort instructions
+        updateSettings({ debugSettings: new DebugSettings(true) });
+
+        const query = new Query(sampleOfAllInstructionTypes);
+        const indentedExplainer = new Explainer('  ');
+        expect(indentedExplainer.explainQuery(query)).toMatchInlineSnapshot(`
+            "  not done
+
+              (has start date) AND (description includes some) =>
+                AND (All of):
+                  has start date
+                  description includes some
+
+              group by priority reverse
+              group by happens
+
+              At most 50 tasks.
+
+              At most 3 tasks per group (if any "group by" options are supplied).
+
+              NOTE: All sort instructions, including default sort order, are disabled, due to 'ignoreSortInstructions' setting.
+            "
+        `);
+    });
 });
 
 describe('explain filters', () => {
diff --git a/tests/Query/Filter/Filter.test.ts b/tests/Query/Filter/Filter.test.ts
index 1ba71007..0f8f1208 100644
--- a/tests/Query/Filter/Filter.test.ts
+++ b/tests/Query/Filter/Filter.test.ts
@@ -16,6 +16,30 @@ describe('Filter', () => {
         expect(filter.explanation.asString()).toEqual(line);
         expect(filter.filterFunction).not.toBeUndefined();
     });
+
+    it('should create a Filter object with different explanation', () => {
+        const filter = new Filter(
+            // instruction differs from explanation
+            'some sample instruction',
+            (_task: Task) => {
+                return true;
+            },
+            new Explanation('some more detailed explanation of the filter'),
+        );
+
+        expect(filter.explainFilterIndented('')).toMatchInlineSnapshot(`
+            "some sample instruction =>
+              some more detailed explanation of the filter
+            "
+        `);
+
+        // Check that text is correctly indented:
+        expect(filter.explainFilterIndented('  ')).toMatchInlineSnapshot(`
+            "  some sample instruction =>
+                some more detailed explanation of the filter
+            "
+        `);
+    });
 });
 
 describe('FilterOrErrorMessage', () => {
diff --git a/tests/lib/QueryRendererHelper.test.ts b/tests/lib/QueryRendererHelper.test.ts
index f588faea..04f952bd 100644
--- a/tests/lib/QueryRendererHelper.test.ts
+++ b/tests/lib/QueryRendererHelper.test.ts
@@ -16,9 +16,9 @@ describe('explain', () => {
         expect(explainResults(query.source, new GlobalFilter(), new GlobalQuery())).toMatchInlineSnapshot(`
             "Explanation of this Tasks code block query:
 
-            No filters supplied. All tasks will match the query.
+              No filters supplied. All tasks will match the query.
 
-            No grouping instructions supplied.
+              No grouping instructions supplied.
             "
         `);
     });
@@ -34,9 +34,9 @@ describe('explain', () => {
 
             Explanation of this Tasks code block query:
 
-            No filters supplied. All tasks will match the query.
+              No filters supplied. All tasks will match the query.
 
-            No grouping instructions supplied.
+              No grouping instructions supplied.
             "
         `);
     });
@@ -49,15 +49,15 @@ describe('explain', () => {
         expect(explainResults(query.source, new GlobalFilter(), globalQuery)).toMatchInlineSnapshot(`
             "Explanation of the global query:
 
-            description includes hello
+              description includes hello
 
-            No grouping instructions supplied.
+              No grouping instructions supplied.
 
             Explanation of this Tasks code block query:
 
-            No filters supplied. All tasks will match the query.
+              No filters supplied. All tasks will match the query.
 
-            No grouping instructions supplied.
+              No grouping instructions supplied.
             "
         `);
     });
@@ -74,15 +74,15 @@ describe('explain', () => {
 
             Explanation of the global query:
 
-            description includes hello
+              description includes hello
 
-            No grouping instructions supplied.
+              No grouping instructions supplied.
 
             Explanation of this Tasks code block query:
 
-            No filters supplied. All tasks will match the query.
+              No filters supplied. All tasks will match the query.
 
-            No grouping instructions supplied.
+              No grouping instructions supplied.
             "
         `);
     });
@@ -95,9 +95,9 @@ describe('explain', () => {
         expect(explainResults(query.source, new GlobalFilter(), globalQuery)).toMatchInlineSnapshot(`
             "Explanation of this Tasks code block query:
 
-            No filters supplied. All tasks will match the query.
+              No filters supplied. All tasks will match the query.
 
-            No grouping instructions supplied.
+              No grouping instructions supplied.
             "
         `);
     });