AppleScript Open / Show Project

On Mac I’ve learnt how to create projects and add tasks - with AppleScript. (So now I can automate and create many more projects scalably, which is very useful to me.)

In common with other AppleScript dictionaries the OmniFocus one is inscrutable to me. One thing in particular I want to do is, having created a project, to switch to it in the Mac app.

How do I switch projects in the Mac app from AppleScript?

(Today my workaround is to issue Cmd+Down+Arrow from the script.)

I am, by the way, driving aspects of OmniFocus with AppleScript from MetaGrid buttons on iPad. It saves lots of keyboard interaction.

1 Like

I will look if this is possible when I reach my computer in a couple of hours. I haven’t coded regularly in this language since 2018 (despite working on very specific projects).

Any particular reason you chose AppleScript over JavaScript For Automation ?

I understand that. Despite its “English-like” syntax, AppleScript is a difficult and not intuitive language.

1 Like

I don’t much like AppleScript either. No particular reason for AppleScript over JXA - except that’s what I started with and got the rest of the code working as.

Looking forward to any resolution or clarity you can bring. And this being a forum it’d be beneficial for unspecified future searchers. :-)

2 Likes

Just looked into this. It is possible. Three variants of the solution, below.

Tell me if you have further questions.

AppleScript:

-- Create new project and display in Projects perspective

tell application "OmniFocus"
    tell default document
        set oProj to make new project with properties {name:"Plant a Tree"}
        tell first document window
            set perspective name to "Projects"
            set nodes to trees of sidebar whose id = (id of oProj)
            set selected trees of sidebar to nodes
        end tell
    end tell
end tell

JavaScript For Automation:

// Twitter: @unlocked2412
(() => {
    'use strict';

    // Create new project and display in Projects perspective
    // main :: IO ()
    const main = () => {
        const
            appOF = Application('OmniFocus'),
            win = appOF.defaultDocument.documentWindows[0],
            proj = newProject(appOF)('Plant a Tree'),
            nodes = win.sidebar.trees.whose({
                id: proj.id()
            });
        return (
            win.perspectiveName = 'Projects',
            win.sidebar.selectedTrees = nodes
        )
    };

    // FUNCTIONS --
    // newProject :: Application -> String -> OFProject
    const newProject = app => strName => {
        const
            proj = new app.Project({
                name: strName
            });
        return (
            app.defaultDocument.projects.push(proj),
            proj
        )
    }

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

OmniJS:

(() => {
    'use strict';

    // Create new project and display in Projects perspective
    // OMNI JS CODE ---------------------------------------
    const omniJSContext = strName => {
        // main :: IO ()
        const main = () => {
            const
                win = document.windows[0],
                ps = Perspective.BuiltIn.Projects,
                s = win.sidebar;
            return (
                win.perspective = ps,
                s.selectedNodes.forEach(n => n.isSelected = false),
                s.nodeForObject((new Project('Plant a Tree'))).isSelected = true
            )
        };

        return main();
    };


    // OmniJS Context Evaluation ------------------------------------------------
    return 0 < Application('OmniFocus').documents.length ? (
        Application('OmniFocus').evaluateJavascript(
            `(${omniJSContext})()`
        )
    ) : 'No documents open in OmniFocus.'
})();
3 Likes

Thank you!

I remain surprised that, while you’ve demonstrated it’s possible, it isn’t automatic or easy to code.

And thanks for goading me into reading the javascript solutions. :-)

2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.