What’s an idomatic way for my omnijs plugin to build an array of all selected items and their descendants?
Right now, I’m doing something ugly and inefficient:
I iterate through all selected items, pushing each and all of its descendants into a new array, then dispose of all the duplicates in the new array when I’m done.
My way works, but there’s got to be a tidy way to do this that’s escaping me.
And to be clear, I don’t want to force the application to visibly expand anything–I just want the data.
Does anyone have a way?
draft8
March 31, 2019, 2:05am
2
I think you should be able to get the top level items of the selection:
// topSelections :: IO () -> [OO Item]
const topSelections = () => {
const
d = document,
o = d.outline;
return o.itemsSortedByPosition(
o.topItems(
d.editors[0].selection.items
)
);
};
and then collect and concatenate their descendant lists, which will be distinct.
1 Like
draft8
March 31, 2019, 2:45am
3
Expanding a little, and calling some omniJS code from JXA, assuming an active OO window:
(() => {
'use strict';
// OmniJS context -------------------------------------
// selectedNodesDescendantCount :: Int
const selectedNodesDescendantCount = () => {
const main = () => {
const xs = topSelections();
return concat(xs.map(x => x.descendants)).length
};
// concat :: [[a]] -> [a]
// concat :: [String] -> String
const concat = xs =>
0 < xs.length ? (() => {
const unit = 'string' !== typeof xs[0] ? (
[]
) : '';
return unit.concat.apply(unit, xs);
})() : [];
// topSelections :: IO () -> [OO Item]
const topSelections = () => {
const
d = document,
o = d.outline;
return o.itemsSortedByPosition(
o.topItems(
d.editors[0].selection.items
)
);
};
// MAIN ---
return main();
}
// JXA context ----------------------------------------
// outlineOmniJSWithArgs :: Function -> [...OptionalArgs] -> a
function outlineOmniJSWithArgs(f) {
return Application('omniOutliner')
.evaluateJavascript(
`(${f})(${Array.from(arguments)
.slice(1).map(JSON.stringify)})`
);
};
return outlineOmniJSWithArgs(
selectedNodesDescendantCount
)
})();
1 Like