Copy as Markdown Link

Well, the macro simply places a link in the clipboard.

I wonder if you would get more control by moving the addition of any padding into the paste stage ?

A KM-defined variant of ⌘V (⌘⌥V, etc) which adds flanking space around the clipboard content ?

1 Like

Thanks for the suggestion. Found a fix using Insert Text by Pasting:
Screenshot 2021-02-07 at 15.55.27

1 Like

Screen Shot 2021-02-07 at 3.29.44 PM

@ComplexPoint @OAL

Every time I activate the copy as markdown link, the icon in the dock pops up. are you saying this doesnt happen to any of you? that's why I find it odd that it happens to me.

I'm on Big Sur.

It's possible that that's the difference.

(Catalina here)

Perhaps it rings a bell with @peternlewis ?

Me too.

On the dock icon bounce:

I'm on Big Sur.

I think what may be happening is this particular macro is causing the KM Editor to load if not already open.

Test: I closed down all apps except Finder and the Editor. I invoked the macro on a file in the Finder, no bounce when the dock was hidden or unhidden. I closed down the Editor, invoked the macro and the Editor opened, bouncing on the dock as it did so. Closed the Editor again, tried another macro, and the Editor did not open. Tried this macro, editor opened again.

Thanks Kevin – that would explain why I haven't see it.

( Still cautiously Catalina here)

@peternlewis might this be because the macro searches for and runs sub-macros, except when the front application is either:

  • a browser
  • or an application with a simple document window interface ?

(I don't know enough about Big Sur to understand why behaviour in that context might be slightly different, if indeed it is.)

Just ran the same test using this macro with Safari. KM Editor did not open.

1 Like

Perhaps Peter will tell us that KM does need the KM editor application to be open to find sub-macros, and that this macro may not suit users who don't want to have the KM app running all the time ?

Updated the com.apple.finder sub-macro

( in the original post above, and at https://github.com/RobTrew/copy-as-md-link )

If nothing is selected in the macOS Finder, the Copy as Markdown Link main macro now copies a Markdown link to the folder viewed by the front Folder window.

(it previously displayed a Nothing selected in Finder message)

JS Source
(() => {
    'use strict';
    // Rob Trew @2020
    const
        finder = Application('com.apple.finder'),
        xs = finder.selection();
    return 0 < xs.length ? (
        xs.map(
            x => `[${x.name()}](${x.url()})`
        ).join('\n')
    ) : (() => {
        const
            url = finder.insertionLocation().url(),
            fp = decodeURI(url).slice(7);
        return `[${fp}](${url})`;
    })();
})();

How does it search for sub macros? If it uses AppleScript to the Keyboard Maestro editor, then it would need the editor running to do that.

Other than the AppleScript referencing the Keyboard Maestro editor, I don't know why Keyboard Maestro would launch, but it would depend on the script I suppose. And whatever the system does. Keyboard Maestro does not generally launch the Keyboard Maestro editor itself, except when you explicitly ask it to or after an update.

Thanks for giving this some thought

It searches, using JavaScript for Automation, in a group named MD Links,

JS source :: finding the group
    // kmGroupByNameLR :: String -> Either String KMGroup
    const kmGroupByNameLR = groupName => {
        // Either a message, if no group of the given
        // name is found, or a reference to a group.
        const
            groups = Application('Keyboard Maestro')
            .macroGroups.where({
                name: groupName
            });
        return 0 < groups.length ? (
            Right(groups.at(0))
        ) : Left(
            'KM group not found: ' + groupName
        );
    };

and looks in that group for a macro with a name that matches the bundle id of the front application:

JS source :: finding the macro
    // kmMacroByGroupAndNameLR :: KMGroup -> String ->
    // Either String KMMacro
    const kmMacroByGroupAndNameLR = group =>
        // Either a message, if no macro of the given 
        // name is found in the referenced group,
        // or a reference to a macro.
        macroName => {
            const
                ms = group.macros.where({
                    name: macroName
                });
            return 0 < ms.length ? (
                Right(ms.at(0))
            ) : Left(
                'No KM macro found by name: ' + (
                    macroName
                ) + '\nin group ' + group.name()
            )
        };

There's no use of an activate method on the Keyboard Maestro application.

In the case of a no-find error, the alert dialog (which shows the no-find message ) does activate an instance of System Events.

JS source :: message to user if macro not found
    // alert :: String => String -> IO String
    const alert = title =>
        s => {
            const sa = Object.assign(
                Application('System Events'), {
                    includeStandardAdditions: true
                });
            return (
                sa.activate(),
                sa.displayDialog(s, {
                    withTitle: title,
                    buttons: ['OK'],
                    defaultButton: 'OK'
                }),
                s
            );
        };

JXA in this case is still doing OSA requests to the Keyboard Maestro editor, so yes, the Keyboard Maestro editor must be running to process such requests.

Application('Keyboard Maestro') (or potentially any use thereof) will launch the Keyboard Maestro editor.

1 Like

Got it – so the 'bouncing' is the app opening, and seen on first use of the macro by people whose habit is to keep Keyboard Maestro closed.

If for any reason they then close the app, they will see it opening again when the macro is next used.

(Copy As Markdown link chooses a specific sub-macro for particular apps, and needs Keyboard Maestro.app as the repository of sub-macros)

I personally prefer to keep Keyboard Maestro running, so I haven't seen this, and I think the immediate solution is just to leave Keyboard Maestro running, by default.

I'll take a look, perhaps over the weekend, at the cost/benefit, in terms of additional complexity and maintenance time, of trying an approach which maps bundleIDs to macro UUIDs through an actively maintained JS dictionary, rather than through osascript to the Group and Macro collections.

Thinking this through and experimenting a little, I find that I can bypass the Keyboard Maestro app, and use the Engine only by maintaining a mapping of each application bundle id to the corresponding sub-macro UUID.

But before I repost, a question for @peternlewis:

If I post an updated macro group here (it contains 30+ sub-macros), will the UUID for each macro persist when others download a copy and import it into their copy of KM, or would their copy need to regenerate the list of (app bundleID -> macro UUID) mappings ?

Example of a map
{
  "app.soulver.mac": "26E5498B-A75A-4ED5-9CEC-8FEA37065470",
  "com.agiletortoise.Drafts-OSX": "39E16879-839F-48F2-A6E6-1786C71CC777",
  "com.amazon.Kindle": "F547E9C5-B98C-4D41-8200-3E901301E412",
  "com.apple.AddressBook": "06E5AD7D-7B75-4693-980C-CF976F4550BF",
  "com.apple.finder": "2626F019-00BB-4673-8FFF-8951007F04F6",
  "com.apple.iCal": "544AE8B8-2115-48E0-93DE-C8EA202C773F",
  "com.apple.mail": "DD01F5EE-5C11-4CCC-9812-D3CBB9992B41",
  "com.culturedcode.ThingsMac": "987CAFF7-4F70-479E-B904-77951F78E187",
  "com.devon-technologies.think3": "BBE7FE30-0DC7-49C0-8D73-434731A9C810",
  "com.flexibits.fantastical2.mac": "02F4C082-9FB2-4E86-A5C6-B6ADC4B0B5B1",
  "com.happenapps.Quiver": "0461A380-1770-4E6C-AD05-76606C37D343",
  "com.houdah.HoudahSpot4": "92CEA724-340D-4A95-8EE4-71ED5A61CE53",
  "com.literatureandlatte.scrivener3": "ACA8F294-9784-4700-9669-E2F26A06141F",
  "com.lukilabs.lukiapp": "F0F53070-9404-4EB4-A1F5-7D3B5DD8D62A",
  "com.multimarkdown.nvUltra": "932C62D8-0A67-4442-9F54-AB36C72C1515",
  "com.OakTree.Accordance": "7B3BF0C5-81FE-4283-900C-2997A54AE621",
  "com.omnigroup.OmniFocus3": "807CFEC6-5B7A-4A79-BDD0-BB4F6506B8CE",
  "com.omnigroup.OmniFocus3.MacAppStore": "B3169CC6-6482-47E8-AA98-F9D00DC052D0",
  "com.omnigroup.OmniPlan3": "14FA415E-F1E6-4991-B9FD-A319D21ACDA7",
  "com.omnigroup.OmniPlan4": "A5DE452C-923A-4747-9DF7-B8269A473293",
  "com.panic.Nova": "5D689369-7240-4DDE-9FCB-AF5DFFFDE4F0",
  "com.panic.Transmit": "8E20DD40-B180-490C-A4BD-E248EF417FA2",
  "com.panic.transmit.mas": "5028564D-691D-4E67-A053-EFEE757D03F3",
  "com.reederapp.5.macOS": "9FEA90F1-542F-4231-B4BD-5ADDDF6D9298",
  "com.reederapp.macOS": "4B909105-12BA-4141-9F2E-A33BB7B5BBE4",
  "com.sonnysoftware.bookends": "1011E7F7-8471-4D2A-B0D0-0943E1523C4C",
  "com.soulmen.ulysses-setapp": "75E588FE-2D2F-42E6-86F0-8104C7960598",
  "com.spotify.client": "DD3929E5-5681-4FBD-9010-22A5F9A9CED3",
  "com.stairways.keyboardmaestro.editor": "99C77823-EBFC-4D9C-89E7-566687F0673E",
  "com.toketaware.ithoughtsx": "6A609F65-4F5D-4C82-97BD-AB9F0FEFDAA2",
  "com.ulyssesapp.mac": "A1C9FAD9-5F46-46F5-9AC3-885A0F046244",
  "de.zettelkasten.TheArchive": "0D6F0B13-755C-493D-B7BB-FC52F73CA13C",
  "md.obsidian": "0CF6AA0F-24F5-4C34-B309-B4033930EBC2",
  "net.shinyfrog.bear": "9881DA35-C336-4D54-B559-0BF9EF7E9EB2",
  "org.mozilla.firefox": "091EFAC5-DC5E-4501-B685-431574AE99BC",
  "QReader.MarginStudyMac": "F94CFFEA-7493-4249-9611-AA654CFF4FF6"
}

thank you! I'm happy it was able to be reproduced!

I can't wait to know if you find a solution! I use this macro for everything now.

For now im having to hide the dock entirely so that it stops from bouncing (that's how much I use it). I have a hard muscle memory to stop myself from cmd+tab and quitting apps. so I think if you can just have it use the menu bar engine that would be ideal!

Generally the UUID of macros that are exported will be retained when they are imported, presuming they don't exist already (which would normally only happen if you re-import the same macros multiple times).

However if there is any conflicts, then Keyboard Maestro will create replacement UUIDs (and internal to that import, and macro references will be updated for the new UUIDs, the code is actually painfully complicated).

Perhaps make a way to read the UUIDs which only needs to be done once (or after changes).

1 Like

First update to a new version (in original post) which now:

fetches sub-macro UUIDs from a JSON dictionary held in a KM variable.

Keyboard Maestro.app now is only needed when first generating that dictionary, or regenerating it after new sub-macros are added.

For those who have wanted to keep Keyboard Maestro.app closed, and were discomforted by seeing it open to select submacros, should now find that this only happens on the first run (after installation of this version), and not thereafter, unless additional sub-macros are installed.

The speed of MD Link copying may also have increased, for many applications.

Test reports welcome.

So Far So Good! everything works perfectly! if anything comes up I will most definitely bring it up here. such a great update! thank you very much! :slight_smile:

1 Like

@ComplexPoint, this macro is incredibly useful. Thanks so much for sharing it and updating it periodically.

I have HoudahSpot, but through a Setapp subscription. When I run Copy as Markdown Link, a dialog appears that includes the following: Consider adding a macro named 'com.houdah.HoudahSpot-setapp' to the KM Group 'MD link tools'.

I copied com.houdah.HoudahSpot4 and renamed the copy com.houdah.HoudahSpot-setapp, but the dialog still appears. Is this because the Setapp About reports: Version 6.0.4 (Build setapp-580). Or am I missing something else?

Thanks!