Feature request: Jump to next/previous project

The commands “Jump to Next Project” and “Jump to Previous Project” would improve a lot the navigation in the editor pane.

I’d like to have keyboard shortcuts (like option+down or cmd+} for next project and option+up or cmd+{ for previous project) so I could easily navigate through projects without having to go to the sidebar or boringly hold the arrow keys jumping line by line.

In the meanwhile, you could attach the following JavaScript for Automation script to a keystroke using something like Keyboard Maestro or FastScripts.

(It jumps to and ‘hoists’ the next project).

If you change the word true in the final line to false, you will be able to save and use a second copy, which jumps back to (and hoists) the previous project.

Keyboard Maestro example:

//Ver 0.3 updated for TaskPaper 3 Preview build 168
//    0.2 hoist optional, options settable at end

(function (dctOptions) {
    'use strict';

    function fn(editor, options) {

        function next(id, lstID, blnDown) {
            var i = lstID.indexOf(id);

            // one after or one before (down or up)
            return i !== -1 ? (
                lstID[i + (blnDown ? 1 : -1)]
            ) : undefined;
        }
		
        // selection ?
        var sln = editor.selection.startItem;

        // project containing selection ?
        var prjs = sln ? sln.evaluateItemPath(
                'ancestor-or-self::@type=project[-1]'
            ) : [],
            prj = prjs.length ? prjs[0] : undefined;

        // following or preceding project ?
        // (options.down = true or false)
        if (prj) {
            var outline = editor.itemBuffer.outline,
                prjNext = outline.getItemForID(
                    next(
                        prj.id,
                        outline.evaluateItemPath('//@type=project')
                        .map(function (x) {
                            return x.id;
                        }),
                        options.down
                    )
                );

            if (prjNext) {
                if (options.hoist) editor.hoist(prjNext);
                else editor.makeVisible(prjNext);
                
                editor.moveSelectionToItems(prjNext, prjNext.bodyString.length);

                return prjNext.bodyString;
            }
        };
    }

    var tp = Application("TaskPaper"),

        ds = tp.documents,
        varResult = ds.length ? ds[0].evaluate({
            script: fn.toString(),
            withOptions: {
                down: dctOptions.down,
                hoist: dctOptions.hoist
            }
        }) : false;

    tp.activate();
    return varResult;

})({
    down: true,
    hoist: true
});

Thanks for providing this alternative solution, @complexpoint . But I just want to jump the cursor between projects in the current list, not focusing them.

If I had the cursor laying in any item of “Project 1”, I’d like to “Jump to Next Project” and have the cursor moved to the “Project 2” header. If I “Jump to Previous Project” I’d have the cursor moved to the “Project 1” header.

Is it possible to achieve this with a script? I’m not into TaskPaper scripting yet, but I want to start to understand the basics of its API as soon as Jesse publishes the documentation I can.

I’ve made a small edit to the script (above, ver 0.2) so that hoisting is optional.

If you edit the pair of scripts so that the options in the last two lines read:

{
    down: true,
    hoist: false
}

in the Next copy, and

{
    down: false,
    hoist: false
}

in the Previous copy

then you will find that the scripts simply move the cursor to the end of the next or previous projects, making the projects visible if they are hidden by filtering or folding.

Is it possible to achieve this with a script ?

The whole thing is deeply scriptable. The outlineEditor interface alone seems to have over 70 methods, covering more or less everything you can imagine, from selections and folding to filtering and tagging and outline structure traversal.