Skip to content

Commit 0692838

Browse files
committed
Merge
1 parent e21a006 commit 0692838

94 files changed

Lines changed: 3315 additions & 1386 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎README.md‎

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,11 @@ If you want to develop plugins, Step 1 is to read the [NotePlan Knowledgebase Do
1717

1818
The following items are required for NotePlan Plugin Development
1919

20-
- Node 14 or 16 -- **Do Not Use any Node version <14 or >16** (see "Switching Node Versions")
20+
- Node -- we're currently running on v24. (You might find a Node version manager [like "n"](https://www.npmjs.com/package/n) helpful. This way you can flip in and out of Node versions at will.)
2121
- NotePlan 3.4 or greater
22-
- macOS Catalina 10.15.2 or greater (strongly recommend macOS Big Sur 11.x or Monterey 12.x)
22+
- macOS Catalina 10.15.2 or greater (and best to be on the latest version)
2323
- github CLI `gh` is strongly recommended - [how to install gh](https://cli.github.com/)
2424

25-
## Switching Node Versions
26-
27-
The NotePlan plugin code has not yet been migrated to Node versions >16. If you are developing elsewhere using Node v17+, you will want to switch to Node v16 when you are doing NotePlan Plugin development. The fast/easy way to do that is with a Node version manager [like "n"](https://www.npmjs.com/package/n). This way you can flip in and out of Node versions at will.
28-
2925
## Plugin Information
3026

3127
If you have an idea for a plugin, [submit them here](https://feedback.noteplan.co/plugins-scripting) or inquire in the [NotePlan Discord community](https://discord.gg/D4268MT)'s `#plugin` channel.
@@ -45,7 +41,7 @@ When you have cloned this repository, you will not only have the tooling, but yo
4541

4642
**Step 2: Install Node (if not installed)**
4743

48-
Make sure you have the proper version of `node` installed (if you need to install node, `brew install node@16` is the quickest method, or you can follow instructions on [node website](https://nodejs.org/en/download/)).
44+
Make sure you have the proper version of `node` installed (if you need to install node, `brew install node` is the quickest method, or you can follow instructions on [node website](https://nodejs.org/en/download/)).
4945

5046
**Step 3: Initialize Local Development Environment**
5147

@@ -219,7 +215,7 @@ The common script you will run `npc plugin:dev <plugin>` however, you may need t
219215
### Viewing Plugin Logs
220216

221217
Everything your plugin (or its WebView) logs goes into NotePlan's rolling log file. `nplog` is a
222-
terminal viewer for it — it follows the newest log file across NotePlan restarts, filters live by
218+
terminal viewer for it; it follows the newest log file across NotePlan restarts, filters live by
223219
regex as you type, and keeps pretty-printed objects together as a single entry instead of
224220
scattering them across lines.
225221

@@ -245,6 +241,15 @@ symlinks under `.claude/skills/` and `.cursor/skills/`.
245241
See [scripts/nplog/README.md](scripts/nplog/README.md) for key bindings, headless
246242
options, and how to use the skill outside this repo.
247243

244+
### Extra logging
245+
246+
An extra level of logging from NP to the plugin console is available by running:
247+
`defaults write co.noteplan.NotePlan3 NotePlanAPIVerboseBridgeLogging --bool true`
248+
at a command line. ???
249+
250+
It can be turned off with:
251+
`defaults delete co.noteplan.NotePlan3 NotePlanAPIVerboseBridgeLogging`
252+
248253
## Editor Setup
249254

250255
Use the setup guide for your preferred editor (we prefer Visual Studio Code), and then read the section on Working with Multiple Files.
@@ -290,7 +295,9 @@ If you don't have an editor set up to lint as you code, you can run `npm run tes
290295

291296
### Using Flow
292297

293-
By practice, NotePlan plugins use [flow](https://flow.org/) for static type checking. You can get more information by referencing [NotePlan Flow Guide](https://github.com/NotePlan/plugins/blob/main/Flow_Guide.md)
298+
The NotePlan plugins in this official repository use [flow](https://flow.org/) for static type checking. You can get more information by referencing [NotePlan Flow Guide](https://github.com/NotePlan/plugins/blob/main/Flow_Guide.md)
299+
300+
Private plugins don't need to use flow, but it is recommended, if you want them to be visible in the list of plugins inside the NP app.
294301

295302
## NotePlan Plugin Support
296303

‎dwertheimer.TaskSorting/CHANGELOG.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44

55
See Plugin [README](https://github.com/NotePlan/plugins/blob/main/dwertheimer.TaskSorting/README.md) for details on available commands and use case.
66

7+
## [1.3.2] - 2026-10-11 (@dwertheimer)
8+
9+
### Fixed
10+
- **`Sort tasks under heading (choose)` no longer pops up dialogs when run from a template, x-callback or another plugin.** A daily-note template calling it for a heading that isn't in today's note (e.g. a "CCC" section on a day off) showed a "No tasks found under heading" warning every time. When the heading is passed as an argument, "No tasks found under heading" and "No note is open" are now written to the plugin log instead. Running the command from the menu still shows them. Thanks to @jgclark for reporting it.
11+
712
## [1.3.1] - 2026-08-11 (@dwertheimer)
813

914
### Fixed

‎dwertheimer.TaskSorting/__tests__/sortTasksUnderHeadingSetting.test.js‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,3 +95,30 @@ describe('sortTasksUnderHeading() honours the "Combine Related Task Types?" sett
9595
expect(checklistIdx).toBeLessThan(openIdx)
9696
})
9797
})
98+
99+
// A template like `invokePluginCommandByName("Sort tasks under heading (choose)", ..., ["CCC", [...]])`
100+
// in a daily-note template runs on days when the note has no "CCC" heading. That used to pop a
101+
// "No tasks found" dialog every time. Runs that pass a heading are scripted and must stay silent.
102+
describe('sortTasksUnderHeading() does not pop up dialogs when called with arguments', () => {
103+
let promptSpy
104+
beforeAll(() => {
105+
promptSpy = jest.spyOn(CommandBar, 'prompt')
106+
})
107+
afterEach(() => promptSpy.mockClear())
108+
109+
test('a heading that is not in the note is silent when passed as an argument', async () => {
110+
const note = makeNote()
111+
global.Editor = note
112+
global.Editor.note = note
113+
const before = note.paragraphs.map((p) => p.content)
114+
await f.sortTasksUnderHeading('CCC', ['-priority', 'content'], note)
115+
expect(promptSpy).not.toHaveBeenCalled()
116+
expect(note.paragraphs.map((p) => p.content)).toEqual(before)
117+
})
118+
119+
test('no open note is silent when a heading was passed as an argument', async () => {
120+
global.Editor = { note: null }
121+
await f.sortTasksUnderHeading('CCC', ['content'])
122+
expect(promptSpy).not.toHaveBeenCalled()
123+
})
124+
})

‎dwertheimer.TaskSorting/plugin.json‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
"noteplan.minAppVersion": "3.4.0",
44
"plugin.id": "dwertheimer.TaskSorting",
55
"plugin.name": "🥷 Task Sorting & Tools",
6-
"plugin.version": "1.3.1",
7-
"plugin.lastUpdateInfo": "1.3.0: Indented subtasks are no longer flattened when sorting -- a task now keeps its whole nested subtree, at every depth. 'Sort tasks under heading' now respects the 'Combine Related Task Types?' setting (it was previously ignored by that command). NOTE: indent with TABS -- NotePlan does not report space-indentation to plugins, so space-indented subtasks cannot be preserved.",
6+
"plugin.version": "1.3.2",
7+
"plugin.lastUpdateInfo": "1.3.2: 'Sort tasks under heading' no longer pops up 'No tasks found' or 'No note is open' dialogs when run from a template, x-callback or another plugin (it logs them instead). Thanks to @jgclark.",
88
"plugin.description": "Commands for sorting tasks in a note",
99
"plugin.releaseStatus": "",
1010
"plugin.author": "dwertheimer",

‎dwertheimer.TaskSorting/src/sortTasks.js‎

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { chooseOption, chooseHeading, showMessage } from '@helpers/userInput'
55
import { getTagParamsFromString } from '@helpers/general'
66
import { removeHeadingFromNote, getBlockUnderHeading } from '@helpers/NPParagraph'
77
import { sortListBy, getTasksByType, getAllDescendants, TASK_TYPES, type GroupedTasks, type SortableParagraphSubset } from '@helpers/sorting'
8-
import { logDebug, logWarn, logError, clo, JSP } from '@helpers/dev'
8+
import { logDebug, logInfo, logWarn, logError, clo, JSP } from '@helpers/dev'
99
import { findStartOfActivePartOfNote, findEndOfActivePartOfNote } from '@helpers/paragraph'
1010
import { saveEditorIfNecessary } from '@helpers/NPEditor'
1111
import { getBooleanValue, getStringArrayValue } from '@helpers/dataManipulation'
@@ -1145,6 +1145,14 @@ export async function sortTasksUnderHeading(
11451145
// `null` default (not `true`) so the "Combine Related Task Types?" setting is consulted -- see #770.
11461146
_interleaveTaskTypes: string | boolean | null = null,
11471147
): Promise<void> {
1148+
// A heading passed in as an argument means a template, x-callback or another plugin is driving this
1149+
// run, not someone choosing from the menu. Those runs must stay silent: e.g. a daily-note template
1150+
// that sorts a "CCC" section should not pop a dialog on days the note has no such heading.
1151+
const isInteractive = !_heading
1152+
const tellUser = async (message: string): Promise<void> => {
1153+
if (isInteractive) await showMessage(message)
1154+
else logInfo(pluginJson, `sortTasksUnderHeading: ${message} (not shown: called with arguments)`)
1155+
}
11481156
try {
11491157
logDebug(`sortTasksUnderHeading: starting for heading="${_heading ?? ''}" sortOrder="${String(_sortOrder)}" with note override? ${_noteOverride ? 'yes' : 'no'}`)
11501158
logDebug(`sortTasksUnderHeading: About to saveEditorIfNecessary()`)
@@ -1153,7 +1161,7 @@ export async function sortTasksUnderHeading(
11531161
const noteToUse = _noteOverride || Editor.note
11541162
if (!noteToUse) {
11551163
logError(pluginJson, `sortTasksUnderHeading: There is no noteToUse. Bailing`)
1156-
await showMessage('No note is open')
1164+
await tellUser('No note is open')
11571165
return
11581166
}
11591167

@@ -1193,11 +1201,11 @@ export async function sortTasksUnderHeading(
11931201
if (noteToUse) await writeOutTasks(noteToUse, sortedTasks, false, false, '', heading, interleaveTaskTypes, false)
11941202
}
11951203
} else {
1196-
await showMessage(`No tasks found under heading "${heading}"`)
1204+
await tellUser(`No tasks found under heading "${heading}"`)
11971205
}
11981206
} else {
11991207
logError(pluginJson, `sortTasksUnderHeading: There is no noteToUse. Bailing`)
1200-
await showMessage('No note is open')
1208+
await tellUser('No note is open')
12011209
}
12021210
} catch (error) {
12031211
logError(pluginJson, JSON.stringify(error))

0 commit comments

Comments
 (0)