.kmtrigger
files simply contain the UUID of the triggered macro.
You should be able to obtain the name of that macro by selecting (one or more) .kmtrigger
files in the Finder, and running the macro below:
Macro names for selected KM trigger files Macro
Macro names for selected KM trigger files.kmmacros (23 KB)
JavaScript Source
(() => {
'use strict';
// Name(s) of macro(s) for .kmtrigger file(s) selected in Finder
// Rob Trew 2019
// Ver 0.1
// main :: IO ()
const main = () =>
unlines(concatMap(
fp => fp.endsWith('.kmtrigger') ? [
takeFileName(fp) + ' -> ' +
kmMacroNameFromUUID(strip(readFile(fp)))
] : [],
selectedPaths()
));
// KEYBOARD MAESTRO FUNCTIONS -------------------------
// kmMacroFromUUIDLR :: String -> String -> Either String Dict
const kmMacroFromUUIDLR = strUUID => {
const
js = ObjC.unwrap,
ms = concatMap(
group => maybe(
[],
x => x,
foldl(
(m, x) => m.Nothing ? (
strUUID === x.UID ? Just(x) : m
) : m,
Nothing(),
(group.Macros || [])
)
), ObjC.deepUnwrap(
$.NSDictionary.dictionaryWithContentsOfFile(
js(js($.NSFileManager.defaultManager
.URLsForDirectoryInDomains(
$.NSApplicationSupportDirectory,
$.NSUserDomainMask
))[0].path) +
'/Keyboard Maestro/Keyboard Maestro Macros.plist'
)
)
.MacroGroups
);
return 0 < ms.length ? (
Right(ms[0])
) : Left('No match found for ' + strUUID);
};
// kmMacroNameFromUUID :: UUID String -> Either Name Message
const kmMacroNameFromUUID = uuid =>
either(
x => 'Error :: ' + x,
x => x,
bindLR(
kmMacroFromUUIDLR(uuid),
m => Right(m.Name)
)
);
// JAVASCRIPT FOR AUTOMATION --------------------------
// selectedPaths :: () -> [pathString]
const selectedPaths = () =>
Application('Finder')
.selection()
.map(x => decodeURI(x.url())
.slice(7));
// GENERIC FUNCTIONS ----------------------------
// https://github.com/RobTrew/prelude-jxa
// Just :: a -> Maybe a
const Just = x => ({
type: 'Maybe',
Nothing: false,
Just: x
});
// Left :: a -> Either a b
const Left = x => ({
type: 'Either',
Left: x
});
// Nothing :: Maybe a
const Nothing = () => ({
type: 'Maybe',
Nothing: true,
});
// Right :: b -> Either a b
const Right = x => ({
type: 'Either',
Right: x
});
// bindLR (>>=) :: Either a -> (a -> Either b) -> Either b
const bindLR = (m, mf) =>
undefined !== m.Left ? (
m
) : mf(m.Right);
// concatMap :: (a -> [b]) -> [a] -> [b]
const concatMap = (f, xs) =>
xs.reduce((a, x) => a.concat(f(x)), []);
// Briefer but slower:
// concatMap :: (a -> [b]) -> [a] -> [b]
// const concatMap = (f, xs) =>
// [].concat(...xs.map(f))
// either :: (a -> c) -> (b -> c) -> Either a b -> c
const either = (fl, fr, e) =>
'Either' === e.type ? (
undefined !== e.Left ? (
fl(e.Left)
) : fr(e.Right)
) : undefined;
// foldl :: (a -> b -> a) -> a -> [b] -> a
const foldl = (f, a, xs) => xs.reduce(f, a);
// maybe :: b -> (a -> b) -> Maybe a -> b
const maybe = (v, f, m) =>
m.Nothing ? v : f(m.Just);
// readFile :: FilePath -> IO String
const readFile = fp => {
const
e = $(),
uw = ObjC.unwrap,
s = uw(
$.NSString.stringWithContentsOfFileEncodingError(
$(fp)
.stringByStandardizingPath,
$.NSUTF8StringEncoding,
e
)
);
return undefined !== s ? (
s
) : uw(e.localizedDescription);
};
// strip :: String -> String
const strip = s => s.trim();
// takeFileName :: FilePath -> FilePath
const takeFileName = strPath =>
'' !== strPath ? (
('/' !== strPath[strPath.length - 1]) ? (
strPath.split('/')
.slice(-1)[0]
) : ''
) : '';
// unlines :: [String] -> String
const unlines = xs => xs.join('\n');
// MAIN ---
return main();
})();