Yes, the issue is the code you are pasting is meant to be executed in JS Context, whereas the plugin is being executing inside OmniJS Context. If you paste the function I called omniJSContext
inside this function:
var action = new PlugIn.Action(function(selection) {
// CODE GOES HERE
}
and call it with trailing parenthesis, as:
var action = new PlugIn.Action(function(selection) {
// CODE GOES HERE
}
omniJSContext();
I polished default template a little bit. You can paste this code into a text editor, save it with .omnijs
extension and move it to you Plug-Ins folder inside OmniFocus iCloud Drive folder.
Plug-In code:
/*{
"type": "action",
"label": "Script Name for Automation Menu"
}*/
(() => Object.assign(
new PlugIn.Action(selection => {
// main :: IO ()
const main = () => {
// OMNI JS CODE ---------------------------------------
const omniJSContext = () => {
// main :: IO ()
const main = () => {
const
todayTag = 'today',
oTag = tagFoundOrCreated(todayTag);
const p = strTag => x =>
(isTodayOrPast(x.deferDate) && !hasTag(strTag)(x)) ||
(!isTodayOrPast(x.deferDate) && hasTag(strTag)(x))
return compose(
splitArrow(
map(removeTag(oTag))
)(map(addTag(oTag))),
partition(x => !isTodayOrPast(x.deferDate)),
filter(p(todayTag)),
filter(x => x.deferDate !== null)
)(flattenedTasks)
};
// OMNIFOCUS FUNCTIONS ----------------------------------------------
// isTodayOrPast :: Date -> Bool
const isTodayOrPast = date => {
const todayDate = new Date()
return (
todayDate.setHours(0),
todayDate.setMinutes(0),
todayDate.setSeconds(0),
todayDate.setDate(todayDate.getDate() + parseInt(1)),
date <= todayDate
)
}
// hasTag :: Tag Name -> OFItem -> Bool
const hasTag = strTag => task =>
elem(strTag)(
map(
x => x.name
)(task.tags)
)
// addTag :: Tag Object -> OFItem -> OFItem
const addTag = oTag => item => {
item.addTag(oTag)
return item
}
// removeTag :: Tag Object -> OFItem -> OFItem
const removeTag = oTag => item => {
item.removeTag(oTag)
return item
}
// tagFoundOrCreated :: Tag Name -> Tag Object
const tagFoundOrCreated = strTag =>
tagNamed(strTag) || new Tag(strTag)
// GENERIC FUNCTIONS --------------------------------------------
// https://github.com/RobTrew/prelude-jxa
// Tuple (,) :: a -> b -> (a, b)
const Tuple = a =>
b => ({
type: 'Tuple',
'0': a,
'1': b,
length: 2
});
// compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
const compose = (...fs) =>
x => fs.reduceRight((a, f) => f(a), x);
// elem :: Eq a => a -> [a] -> Bool
// elem :: Char -> String -> Bool
const elem = x =>
xs => {
const t = xs.constructor.name;
return 'Array' !== t ? (
xs['Set' !== t ? 'includes' : 'has'](x)
) : xs.some(eq(x));
};
// eq (==) :: Eq a => a -> a -> Bool
const eq = a =>
// True when a and b are equivalent in the terms
// defined below for their shared data type.
b => {
const t = typeof a;
return t !== typeof b ? (
false
) : 'object' !== t ? (
'function' !== t ? (
a === b
) : a.toString() === b.toString()
) : (() => {
const kvs = Object.entries(a);
return kvs.length !== Object.keys(b).length ? (
false
) : kvs.every(([k, v]) => eq(v)(b[k]));
})();
};
// filter :: (a -> Bool) -> [a] -> [a]
const filter = f => xs => xs.filter(f);
// map :: (a -> b) -> [a] -> [b]
const map = f =>
// The list obtained by applying f
// to each element of xs.
// (The image of xs under f).
xs => (
Array.isArray(xs) ? (
xs
) : Array.from(xs)
).map(f);
// partition :: (a -> Bool) -> [a] -> ([a], [a])
const partition = p => xs =>
xs.reduce(
(a, x) =>
p(x) ? (
Tuple(a[0].concat(x))(a[1])
) : Tuple(a[0])(a[1].concat(x)),
Tuple([])([])
);
// splitArrow (***) :: (a -> b) -> (c -> d) -> ((a, c) -> (b, d))
const splitArrow = f =>
// The functions f and g combined in a single function
// from a tuple (x, y) to a tuple of (f(x), g(y))
g => tpl => Tuple(f(tpl[0]))(
g(tpl[1])
);
// MAIN -----------------------------------------
return main()
};
omniJSContext()
};
return main()
}, {
validate: selection => true
})
))();
Tell me if it works for you.