Skip to content

Instantly share code, notes, and snippets.

@oin
Last active October 31, 2020 13:10
Show Gist options
  • Save oin/da74383f335a8c55e69cf56548759ce3 to your computer and use it in GitHub Desktop.
Save oin/da74383f335a8c55e69cf56548759ce3 to your computer and use it in GitHub Desktop.
Keyboard Maestro macro that displays a searchable list of headings of the current Bear note on Cmd+R. Caution: Doesn't work when the Marked app is installed, and the macro needs to be adjusted to your system.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<dict>
<key>Activate</key>
<string>Normal</string>
<key>CreationDate</key>
<real>625178916.75752902</real>
<key>Macros</key>
<array>
<dict>
<key>Actions</key>
<array>
<dict>
<key>MacroActionType</key>
<string>SelectMenuItem</string>
<key>Menu</key>
<array>
<string>Note</string>
<string>Preview in Marked</string>
</array>
<key>TargetApplication</key>
<dict>
<key>BundleIdentifier</key>
<string>net.shinyfrog.bear</string>
<key>Name</key>
<string>Bear</string>
<key>NewFile</key>
<string>/Applications/Bear.app</string>
</dict>
<key>TargetingType</key>
<string>Specific</string>
</dict>
<dict>
<key>MacroActionType</key>
<string>Pause</string>
<key>Time</key>
<string>0.2</string>
<key>TimeOutAbortsMacro</key>
<true/>
</dict>
<dict>
<key>KeyCode</key>
<integer>53</integer>
<key>MacroActionType</key>
<string>SimulateKeystroke</string>
<key>Modifiers</key>
<integer>0</integer>
<key>ReleaseAll</key>
<false/>
<key>TargetApplication</key>
<dict/>
<key>TargetingType</key>
<string>Front</string>
</dict>
<dict>
<key>DisplayKind</key>
<string>Variable</string>
<key>HonourFailureSettings</key>
<true/>
<key>IncludeStdErr</key>
<false/>
<key>MacroActionType</key>
<string>ExecuteJavaScriptForAutomation</string>
<key>Path</key>
<string></string>
<key>Text</key>
<string>ObjC.import('AppKit');
function getBearHeadingList() {
const pb = $.NSPasteboard.pasteboardWithName('mkStreamingPreview');
const str = ObjC.unwrap(pb.stringForType('public.utf8-plain-text'));
const lines = str.split('\n');
const regex = /^#+\s+/;
var headings = [];
for(var i=0; i&lt;lines.length; ++i) {
const line = lines[i];
const match = line.match(regex);
if(!match || match.length == 0) {
continue;
}
const title = line.substring(match[0].length);
const level = Math.max(0, match[0].length - 2);
headings.push("· ".repeat(level) + title);
}
return headings;
}
getBearHeadingList().join("\n");</string>
<key>TimeOutAbortsMacro</key>
<true/>
<key>TrimResults</key>
<true/>
<key>TrimResultsNew</key>
<true/>
<key>UseText</key>
<true/>
<key>Variable</key>
<string>BearHeadingList</string>
</dict>
<dict>
<key>Destination</key>
<string>Variable</string>
<key>DestinationVariable</key>
<string>BearSelectedHeading</string>
<key>MacroActionType</key>
<string>PromptWithList</string>
<key>NotifyOnFailure</key>
<false/>
<key>PromptUID</key>
<string>7BC60A82-2B38-4A53-8552-CE172933399A</string>
<key>Sort</key>
<false/>
<key>Source</key>
<string>Variable</string>
<key>TimeOutAbortsMacro</key>
<true/>
<key>Variable</key>
<string>BearHeadingList</string>
</dict>
<dict>
<key>DisplayKind</key>
<string>Variable</string>
<key>HonourFailureSettings</key>
<true/>
<key>IncludeStdErr</key>
<false/>
<key>MacroActionType</key>
<string>ExecuteJavaScriptForAutomation</string>
<key>Path</key>
<string></string>
<key>Text</key>
<string>function prepareURL() {
var kme = Application("Keyboard Maestro Engine");
const heading = kme.getvariable("BearSelectedHeading");
if(!heading || !heading.length) {
return null;
}
const title = heading.replace("· ", "");
if(!title.length) {
return null;
}
const encodedTitle = encodeURIComponent(title);
return "bear://x-callback-url/open-header?header=" + encodedTitle + "&amp;edit=yes";
}
prepareURL();</string>
<key>TimeOutAbortsMacro</key>
<true/>
<key>TrimResults</key>
<true/>
<key>TrimResultsNew</key>
<true/>
<key>UseText</key>
<true/>
<key>Variable</key>
<string>BearHeadingURL</string>
</dict>
<dict>
<key>Conditions</key>
<dict>
<key>ConditionList</key>
<array>
<dict>
<key>ConditionType</key>
<string>Variable</string>
<key>Variable</key>
<string>BearHeadingURL</string>
<key>VariableConditionType</key>
<string>IsNotEmpty</string>
<key>VariableValue</key>
<string>value</string>
</dict>
</array>
<key>ConditionListMatch</key>
<string>All</string>
</dict>
<key>ElseActions</key>
<array/>
<key>MacroActionType</key>
<string>IfThenElse</string>
<key>ThenActions</key>
<array>
<dict>
<key>IsDefaultApplication</key>
<true/>
<key>MacroActionType</key>
<string>OpenURL</string>
<key>TimeOutAbortsMacro</key>
<true/>
<key>URL</key>
<string>%Variable%BearHeadingURL%</string>
</dict>
</array>
<key>TimeOutAbortsMacro</key>
<true/>
</dict>
</array>
<key>CreationDate</key>
<real>625236050.752967</real>
<key>ModificationDate</key>
<real>625240019.51981997</real>
<key>Name</key>
<string>Go to heading</string>
<key>Triggers</key>
<array>
<dict>
<key>FireType</key>
<string>Pressed</string>
<key>KeyCode</key>
<integer>15</integer>
<key>MacroTriggerType</key>
<string>HotKey</string>
<key>Modifiers</key>
<integer>256</integer>
</dict>
</array>
<key>UID</key>
<string>B3859348-6123-4E34-BC70-BA6F0BEF5870</string>
</dict>
</array>
<key>Name</key>
<string>Bear</string>
<key>Targeting</key>
<dict>
<key>Targeting</key>
<string>Included</string>
<key>TargetingApps</key>
<array>
<dict>
<key>BundleIdentifier</key>
<string>net.shinyfrog.bear</string>
<key>Name</key>
<string>Bear</string>
<key>NewFile</key>
<string>/Applications/Bear.app</string>
</dict>
</array>
</dict>
<key>ToggleMacroUID</key>
<string>1D3C1E03-07B3-4151-8682-8973BEDD26C3</string>
<key>UID</key>
<string>FCA883FA-D43D-491E-A010-B4C4865040B5</string>
</dict>
</array>
</plist>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment