TaskPaper 3: Focus on Next (or Previous) Project

taskpaper
jxa

#1

A couple of keystrokes for TaskPaper 3 which 'hoist' (given full outline focus to) the next or previous project.

Focus on NEXT project.kmmacros (20.5 KB)

(The two scripts differ only in the arguments on the final lines, where two option choose between, prev/next, and hoist or simply move cursor)

//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
});


#2

Updated above to Ver 0.3 for compatibility with some new API in TaskPaper 3 Preview build 168


#3

Editability of the first post has expired, so here is an update, for the Release version of the TaskPaper 3 API.

The default setting is to 'focus' each successive or preceding project.
An option at the end of the script allows choice of an alternative 'hoisting' behaviour (project line not displayed, only its descendants).

Focus on NEXT or PREV TP3 Project.kmmacros (40.8 KB)

JavaScript source:

// Ver 0.4 updated for TaskPaper 3 release version API
// 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;
        }

        var outline = editor.outline,
            // selection ?
            sln = editor.selection.startItem,

            // project containing selection ?
            prjs = sln ? outline.evaluateItemPath(
                'ancestor-or-self::@type=project[-1]',
                sln
            ) : [],
            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
                    )
                );

            return prjNext ? (
                editor[(options.hoist ? 'hoist' : 'focus') + 'edItem'] = prjNext,
                editor.moveSelectionToItems(prjNext, prjNext.bodyString.length),
                prjNext.bodyString
            ) : undefined;
        };
    }

    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: false  // hoisting hides the project line - showing just descendants
});