Get Selected Text, Otherwise Clipboard

I’ve seen this topic raised in a number of forum threads. Here’s a fast and robust technique that I’m currently using.

PURPOSE

The purpose of this macro is to demonstrate a method to populate a Keyboard Maestro variable (local_Text) with the currently selected text, or if no text is selected, the contents of the System Clipboard.

The text can be selected in a browser or any macOS app that supports text. Note that this technique uses the System Clipboard, but it does not modify it.

I’ve found this method to be faster and more robust that others I’ve tried (e.g., checking for an active Copy menu item).


TESTED WITH

• Keyboard Maestro 11.0.3
• Sequoia 15.1 (24B5055e)/MacBookPro18,2
• Mojave 10.14.16/Macmini6,2
• High Sierra 10.13.6/iMac11,1445


VERSION HISTORY

( expand / collapse )

1.0 initial version

2.0

a) Renamed macro to Get Selected Text or Clipboard if No Text is Selected to Get Selected Text, Otherwise Clipboard.

b) Uses the Copy action and the %ActionResult% token rather than the CLIPBOARDSEED() function.

c) A 0.5 second Pause is no longer required due to the new approach.

d) If no text is selected and the Copy action (or Type a Keystroke [⌘C] action) runs, macOS generates a pop sound. This sound is muted.


DOWNLOADS

1. Actions that can be inserted into a macro

Download: Get Selected Text- Otherwise Clipboard.kmmacros (32 KB)

Macro-Image


2. Submacro that can be called using the Execute a Macro action

Submacro and Caller.kmmacros (35.4 KB)


3. Subroutine macro that can be called using the Execute a Subroutine action

Subroutine and Caller.kmmacros (35.8 KB)

9 Likes

Thanks! In case you weren't aware, your macro looks similar to existing work here:

But I ended up using yours with some modifications. :slight_smile:

1 Like

I've updated the OP with Version 2.0 of Get Selected Text, Otherwise Clipboard:

  • Renamed macro to Get Selected Text or Clipboard if No Text is Selected to Get Selected Text, Otherwise Clipboard.

  • Uses the Copy action and the %ActionResult% token rather than the CLIPBOARDSEED() function.

  • A 0.5 second Pause is no longer required due to the new approach.

  • If no text is selected and the Copy action (or Type a Keystroke [⌘C] action) runs, macOS generates a pop sound. This sound is muted.

4 Likes

I'm likely suffering from the PBKAC disease. I'm attempting to use the Macro as the start of something longer. There is something I'm not understanding about variables. (well there's alot I don't understand).

  1. Get Selected Text's last action - "Not Required" is enabled it correctly displays my selected text. - however that display halts my macro run.
  2. When that action is disable and I use the debugger and variable inspector, %local_Text% is empty.

Contents of the Variable Inspector:

I'm clearly missing something obvious. I would appreciate any help.

1 Like

Hello Mark (@mlevison) :wave:

Your Variable is empty because you’ve provided no Value to it.

If the Macro from Jim would provide a global Variable with the text you probably wouldn’t see an empty value. But that is not the case. It is a Local Variable.

A Local Variable stores its value only for the time of a single Macro Instance. They aren’t readable from other Macros (for example SubMacros) as long you don’t use them in parameters as TriggerValue for them.

If you want to use Variables between Macro Instances you’ll have to use Instance Variables because they don’t belong to single Instances. If a Macro has SubMacros every Instance Variable of this Instance could be shared between all SubMacros and the Main Macros running Instance. But if the instance is cancelled due to Macro ending the Values are all gone like if you’ve used Local Variables.

I hope this makes everything more clear to you how Variables work.

Greetings from Germany :de:

Tobias

4 Likes

Hi, @mlevison; I should have more clearly described the original macro. It was not designed to be called, instead it was intended to demonstrate a technique, thus the actions could be embedded within your macro.

With that said, it could be revised to be used as a submacro or subroutine; the latter being my recommendation. If you’d like help with that, please let me know. I’m away from my computer now, but could help about five hours from now.

2 Likes

@_jims the subroutine hint was magic. It did the job. I've no idea how to create a subroutine, so I dupilcated an existing one and then copied your actions over. Adding a return value was easy enough.

@Nr.5-need_input As a recovering programmer the comment local variables made sense. I just needed Jim's hint to go create a subroutine.

2 Likes

Same as any other macro, except you give it the "Subroutine" trigger:

image

...which will result in:

...and you can set your Subroutine options.

See the Subroutines page and its links for more.

4 Likes

Hi, @mlevison. I'm glad you were able to convert it to a subroutine macro.

For future reference, I've clarified the OP and added submacro and subroutine versions. As @Nr.5-need_input suggested, the submacro employs an instance variable.

2 Likes