"Move to Project": to beginning or end?

The “Move to Project” command prepends the selected item/branch to the top of a (sub)project.
Any way to have it appended at the end instead? Thank you.

In the meanwhile, a script which moves the selected items to the end of the chosen project list.

(A variant of an earlier script, with an added destination option – see end of script)

(function (dctOptions) {
    'use strict';
// ver 0.2 option at end of script
//         for moving tasks to start or end of chosen project

    // TASKPAPER CONTEXT FUNCTIONS

    // PROJECTS IN ACTIVE DOCUMENT
    function tpProjectList(editor, options) {

        return (editor.selection.selectedItems.length > 0) ?
            editor.outline.evaluateItemPath(
                '//@type=project')
            .map(function (p) {
                var strName = p.bodyString;

                return {
                    id: p.id,
                    name: strName.slice(
                        0, strName.indexOf(':')
                    )
                }
            }) : [];
    }

    // MOVEMENT OF SELECTED ITEMS TO START OR END OF CHOSEN PROJECT
    function tpMoveSelected(editor, options) {

        var outline = editor.outline,
            lstSelns = editor.selection.selectedItems,
            lngSelns = lstSelns.length,
            blnStart = options.toStart;

        if (lngSelns > 0) {
            var oFirst = lstSelns[0],
                oLast = lngSelns > 1 ? lstSelns[lngSelns - 1] : oFirst,

                oProject = outline.getItemForID(
                    options.projectID
                ),
                oFirstChild = oProject.firstChild || (function () {
                    outline.groupUndoAndChanges(function () {
                        oProject.appendChildren(outline.createItem());
                    });
                    return oProject.firstChild;
                })();

            // If we have a non-circular destination, make the move ...
            if (oFirstChild && (lstSelns.indexOf(oFirstChild) === -1)) {
                outline.groupUndoAndChanges(function () {

                    if (blnStart) {
                        outline.insertItemsBefore(
                            lstSelns,
                            oFirstChild
                        );
                    } else {
                        oProject.appendChildren(lstSelns);
                    }

                });

                // make sure that source and target are both visible
                editor.hoistedItem = null;
                editor.itemPathFilter = '';

                // Select the newly moved items, for more visibility
                editor.moveSelectionToItems(
                    oFirst, 0,
                    oLast, oLast.bodyString.length
                );

                return lstSelns.length;
            } else return 0
        } else return 0;
    }

    // JAVASCRIPT FOR AUTOMATION CONTEXT

    // PROJECTS IN ACTIVE DOCUMENT ?
    var tp3 = Application("com.hogbaysoftware.TaskPaper3"),
        ds = tp3.documents,
        d = ds.length ? ds[0] : undefined,
        lstProjects = d ? d.evaluate({
            script: tpProjectList.toString(),
        }) : [];

    // USER CHOICE OF TARGET PROJECT ?
    if (lstProjects.length > 0) {
        var a = Application.currentApplication(),
            sa = (a.includeStandardAdditions = true, a),
            e = Application("SystemUIServer"),
            se = (e.includeStandardAdditions = true, e);

        var lstMenu = lstProjects.map(function (x) {
                return x.name;
            }),

            varChoice = (se.activate(),
                se.chooseFromList(lstMenu, {
                    withTitle: "Move items to " +
                    (dctOptions.toStart ? 'start' : 'end' ) +
                    " of chosen Project",
                    withPrompt: 'Choose:',
                    defaultItems: lstMenu[0],
                    okButtonName: 'OK',
                    cancelButtonName: 'Cancel',
                    multipleSelectionsAllowed: false,
                    emptySelectionAllowed: true
                })),

            lstChoice = varChoice ? varChoice : [];

        if (lstChoice.length > 0) {
            // MAKE THE MOVE IN TASKPAPER 3
            var dctChoice = lstProjects[lstMenu.indexOf(lstChoice[0])],
                lngMoved = d.evaluate({
                    script: tpMoveSelected.toString(),
                    withOptions: {
                        projectID: dctChoice.id,
                        toStart: dctOptions.toStart
                    }
                });

            // AND REPORT ON ANY RESULT
            if (lngMoved > 0) {
                sa.displayNotification('in TaskPaper 3 Preview', {
                    withTitle: lngMoved + ' selected item' + (
                        lngMoved > 1 ? 's' : ''
                    ) + " moved",
                    subtitle: "to " +
                        (dctOptions.toStart ? "start" : "end") +
                        " of '" + dctChoice.name + "'",
                    sound: 'glass'
                })
            }
            tp3.activate();
            return lngMoved;
        }
    }
})({
    toStart: false // if false, the items are moved to end of project list
});

2 Likes

I’ve added a note to myself to eventually add a preference for this. But I don’t think I’ll do that soon (instead use @complexpoint 's script). I actually had it this way to start… then switched due to requests :slight_smile:

1 Like

Thank you, @complexpoint. Useful and expertly done, as usual.

I’ll be looking forward to this preference, @jessegrosjean. You surely have a more accurate sense of priorities than me, but on my end the current implementation is a bit flawed, conceptually and practically. I use the command to categorize brainstormed lists, in which the order of items tends to be significant, but the items end up categorized in inverted order.

I am trying to use this script with Version 3.8.17 (477) but nothing happens. (Script is properly installed in the designated scripts folder, etc.; other scripts are working fine.) Any thoughts/suggestions? My guess is that the script worked with older versions of TaskPaper, but newer versions made changes that broke the script. Or maybe changes to MacOS are to blame.

Background / my use case: I want to move tasks to the bottom of the project they are already in (trying to implement Mark Forster’s Final Version Perfected or Autofocus systems).

I think you may just need to replace the string above with:

Application("TaskPaper")
1 Like

As usual, @complexpoint for the win! You’re the best — it works perfectly. Thank you.

1 Like

Actually, now that I have it up and running, I’m finding that it works unless I try to move the first task in a project to the end of the same project. If I select the first task in the project, execute the script, select the same project to which the task belongs, and press OK, nothing happens. But if I try to move the first task in the project to the bottom of another project, that works fine. And likewise, if I try to move any task other than the first one in a project to the bottom of that same project, that works fine too.

(Subproject behavior: Moving the first task in a project to the bottom of one of its subprojects works fine. Moving the first task in a subproject to the bottom of the parent project works fine. But moving the first task in a subproject to the bottom of the same subproject does not work.)

Not a big deal, but I wanted to point it out because I noticed the behavior and thought it might help in some small way.