Place the cursor at the end of the first task that is not @done

Here’s a draft of:

// First not @done selected in project containing cursor
// or first not @done in document, if project complete.
Expand disclosure triangle to view JS source
(() => {
    "use strict";

    // Rob Trew @2021, 2024

    // First not @done selected in project containing cursor
    // or first not @done in document, if project complete.

    // Ver 2.07

    const enclosingProject = "ancestor-or-self::project[-1]";

    const firstNotDone = "//task not @done[0]";

    // ------------------- JXA CONTEXT -------------------

    // main :: IO ()
    const main = () => {
        const doc = Application("TaskPaper").documents.at(0);

        return doc.exists()
            ? doc.evaluate({
                script: `${TaskPaperContext}`,
                withOptions: {
                    enclosingProject,
                    firstNotDone
                }
            })
            : "No documents open in TaskPaper";
    };

    // ---------------- TASKPAPER CONTEXT ----------------

    // TaskPaperContext :: Editor -> IO ()
    const TaskPaperContext = (editor, options) => {
        const
            outline = editor.outline,

            { enclosingProject, firstNotDone } = options,

            match = outline.evaluateItemPath(
                enclosingProject + firstNotDone,
                editor.selection.startItem
            )[0] || outline.evaluateItemPath(
                firstNotDone
            )[0];

        return match
            ? (
                editor.moveSelectionToItems(
                    match, match.bodyString.length
                ),
                `${match.bodyContentString}`
            )
            : "No remaining tasks in document.";
    };

    // MAIN ---
    return main();
})();
1 Like

The weekend arrives early in your timezone! :slight_smile:

Colour me impressed! The code is brilliant, and I will have to put time into studying it.

I hereby dub you: Honorable Knight of JavaScript!

The work is all Jesse’s :slight_smile:

( I had just been slow to grasp the use of that contextItem argument )

1 Like

I’ll respectfully disagree with that, but thanks :slight_smile:

2 Likes

Regardless of the specifics, both of you are wonderful!

1 Like