JSON array of (UUID, Name) pairs for all macros in selected groups

To access particular elements of the list, see token:JSONValue [Keyboard Maestro Wiki]

JSON Array of (UUID- Name) pairs for all macros in selected groups.kmmacros (4.7 KB)


Expand disclosure triangle to view JS source
(() => {
    "use strict";

    // JSON list of (UUID, Name) pairs
    // for all macros in selected groups.

    // Rob Trew @2024

    const main = () => {
        const km = Application("Keyboard Maestro");

        return sortBy(
            comparing(snd)
        )(
            km.selectedMacroGroups().flatMap(group => {
                const macros = group.macros;

                return zip(
                    macros.id()
                )(
                    macros.name()
                );
            })
        );
    };

    // --------------------- GENERIC ---------------------

    // comparing :: Ord a => (b -> a) -> b -> b -> Ordering
    const comparing = f =>
        // The ordering of f(x) and f(y) as a value
        // drawn from {-1, 0, 1}, representing {LT, EQ, GT}.
        x => y => {
            const
                a = f(x),
                b = f(y);

            return a < b
                ? -1
                : a > b
                    ? 1
                    : 0;
        };


    // snd :: (a, b) -> b
    const snd = tpl =>
        // Second member of a pair.
        tpl[1];


    // sortBy :: (a -> a -> Ordering) -> [a] -> [a]
    const sortBy = f =>
        // A copy of xs sorted by the comparator function f.
        xs => xs.slice()
        .sort((a, b) => f(a)(b));


    // zip :: [a] -> [b] -> [(a, b)]
    const zip = xs =>
        // The paired members of xs and ys, up to
        // the length of the shorter of the two lists.
        ys => Array.from({
            length: Math.min(xs.length, ys.length)
        }, (_, i) => [xs[i], ys[i]]);


    // MAIN --
    return JSON.stringify(main(), null, 2);
})();
1 Like

PS we can, FWIW, do the same thing in AppleScript, but then we don't get the JSON for free ...

JSON Array of (UUID- Name) pairs for all macros in selected groups (AS version).kmmacros (4.6 KB)

use framework "Foundation"

on run
    tell application "Keyboard Maestro"
        script go
            on |λ|(group)
                tell macros of group to my zip(its id, its name)
            end |λ|
        end script
        
        my showJSON(my concatMap(go, selected macro groups))
    end tell
end run


-- concatMap :: (a -> [b]) -> [a] -> [b]
on concatMap(f, xs)
    set lng to length of xs
    set acc to {}
    
    tell mReturn(f)
        repeat with i from 1 to lng
            set acc to acc & (|λ|(item i of xs, i, xs))
        end repeat
    end tell
    acc
end concatMap


-- mReturn :: First-class m => (a -> b) -> m (a -> b)
on mReturn(f)
    -- 2nd class handler function lifted into 1st class script wrapper. 
    if script is class of f then
        f
    else
        script
            property |λ| : f
        end script
    end if
end mReturn


-- zip :: [a] -> [b] -> [(a, b)]
on zip(xs, ys)
    set nxs to length of xs
    set nys to length of ys
    
    if nxs < nys then
        set n to nxs
    else
        set n to nys
    end if
    
    set lst to {}
    repeat with i from 1 to n
        set end of lst to {item i of xs, item i of ys}
    end repeat
    return lst
end zip

-- showJSON :: List -> JSON String
on showJSON(xs)
    set ca to current application
    set json to ca's NSJSONSerialization's dataWithJSONObject:xs options:1 |error|:(missing value)
    if json is missing value then
        "Could not serialize as JSON"
    else
        (ca's NSString's alloc()'s initWithData:json encoding:(ca's NSUTF8StringEncoding)) as text
    end if
end showJSON