Create and Edit Lists in Keyboard Maestro with AppleScript

July 23, 2013

Create and Edit Lists in Keyboard Maestro with AppleScript → via @_patrickwelker

Outline

1. Introduction

The plethora of features and the custom hacks that can be created with Keyboard Maestro are the reason it has earned a place in the top 5 of my favorite Mac apps. Still, there is room for improvements. Today I want to address one feature that already exists, but which isn’t usable for me: lists in a dialog prompt.

In this post I’ll cover the status quo of support for lists in Keyboard Maestro and two workarounds for different scenarios where lists can come in handy. To wrap it up, the last section shows you my present setup of how I create new notes and append notes to lists, as well as how I use a piece of AppleScript to generate a list of recently modified files which prompts me to choose one document along with several other options.

But first things first. Terminology. The following picture illustrates what I refer to when I speak of ‘lists’ in this context:

Lists vs. Palettes

In Keyboard Maestro you can create simpler versions of these traditional GUI element, too. Although they won’t look and act exactly like the one from the screen shot I took (it’s MarsEdit by the way) they are useful in certain contexts. Before we dive in deeper, here’s a comparison of the key features of both, lists and palettes, with the latter being my favorite for replacing ‘dialog lists’ most times.

Lists are good for…

  • displaying a huge amount of options
  • low priority lists that you don’t visit regularly or that are not crucial to your workflow
  • saving some valuable space in that good old brain of yours (since there is no need to learn or memorize shortcuts)
  • a simpler approach to keyboard navigation (by using the arrow keys or typing the starting letters of the list entry)

Palettes are good for…

  • displaying a few selected and important macros (I’ve tried large palettes and came to the conclusion that they don’t work for me - no matter how many dividers I setup to structure and organize them. Nowadays I try to limit myself to a maximum amount of ten macros in a palette.)
  • keyboard aficionados because they tend to react a tad quicker - they’re as simple as it gets
  • swift keyboard navigation, especially when you get accustomed to shortcuts
  • shortcut versatility, assigning multiple hot keys to one macro, c.f. “1. Links” in the example above is linked to three hot keys: 1, NUM1 and L.
  • nesting and triggering other palettes

2. Status Quo of Lists in Keyboard Maestro

Keyboard Maestro 6 brought some new features which many users (including me) have been waiting for. Above all, I enjoy having the ability to trigger macro palettes with a macro which makes my previous workaround obsolete. The new text tokens are also a nice addition.

To give you an example of how useful and versatile lists are, here’s an example by Gabe from Macdrifter where he makes use of them with his Quick Note macro:

Quick Note by Gabe Weatherhead

These lists can be created in Keyboard Maestro by making use of the | character aka pipe to create multiple values. It’s a good option, especially for users who use their mouse more than the keyboard.

Your sharp eyes might still stuck on that last remark…. Right, that’s exactly the problem I have with Keyboard Maestro’s implementation of this somewhat hidden feature. You can’t navigate such a list with your keyboard which leads to me not using native Keyboard Maestro lists at all. The point of the whole exercise for me is not to leave my keyboard and gain a swift way to choose from an array of list items. At the moment Keyboard Maestro forces you to pick the entry via the mouse, there just is no other way.

3. Using TextExpander for lists

The fill-in snippet of TextExpander gives you multiple choices in a popup menu which makes it in some cases a quite useful replacement.

I make use of the double space suffix technique by Kaushik Gopal which I find brillant and more logical than the usual approach with a period or semicolon prefix, so here’s my kao SPACE SPACE snippet for a list of my beloved Kaomoji Emoticons:1

Kaomoji TextExpander

Since I’m deeply in love with Keyboard Maestro and want to preserve the just fallen in love kind of feeling in our relationship for as long as possible, I created a one-action macro to trigger the TextExpander snippet:

text-to-string

Here’s the corresponding snippet:

%fillpopup:name=Kaomoji:default=-_-;:(^_^):<( '.' )>:(♥‿♥):(ᵔᴥᵔ):ᶘ ᵒᴥᵒᶅ:[•.•ิ]:(•͡.•͡):ಠ_ರೃ:⊙﹏⊙:ε-(´・`) フ:-_-*:(◐‿◑):(•ˋ _ ˊ•):o┤*`□´ *├o:ヽ(`⌒´メ)ノ:(-̩__-̩):\(^ ^)/:\(-_- ):(´。_。`):(z_z~.):v(^_^)v:o(^_^o):(″・ิ_・ิ)っ:◕‿↼:ƪ(˘▽˘ƪ)%

What I gain from this ménage à trois is that I can put the macro in a palette or trigger it via a hot key.

However, when using TextExpander you can’t pass the output of a list item into a variable and make use of it anywhere else in the macro. After all it’s TextExpander and it does best what it’s build for. Use it for that purpose. If you want more advanced lists read on.

4. Using Keyboard Maestro and AppleScript for lists

As simple as it is, the TextExpander example above represents a use case scenario where lists make more sense to me than using Keyboard Maestro palettes. Now, to make lists even more useful we can use AppleScript and build a list.

4.1 Kaomoji Emoticon Example

property kaoList : {"-_-;", "(^_^)", "<( '.' )>", "◕‿‿◕", "(♥‿♥)", "(ᵔᴥᵔ)", "ᶘ ᵒᴥᵒᶅ", "[•.•ิ]", "(•͡.•͡)", "(*_*)", "ಠ_ರೃ", "⊙﹏⊙", "٩(͡๏̯͡๏)۶", "٩(●̮̮̃•̃)۶", "ε-(´・`) フ", "-_-*", "(◐‿◑)", "(•ˋ _ ˊ•)", "o┤*`□´ *├o", "ヽ(`⌒´メ)ノ", "(-̩__-̩)", "\(^ ^)/", "\(-_- )", "(>_<\")", "(´。_。`)", "(z_z~.)", "v(^_^)v", "o(^_^o)", "(″・ิ_・ิ)っ", "◕‿↼", "(=^.^=)/", "ƪ(˘▽˘ƪ)"}
-----------------------------------------------------
tell application "Keyboard Maestro Engine"
    activate
    set selectedEmoji to choose from list the kaoList with title "Kaomoji" with prompt "Your Emoticon feels like…"
    -- OK and Cancel actions
    if selectedEmoji is false then -- Play beep and cancel all running macros
	    beep 1
	    do script "Cancel All Macros"
	    error number -128
    else
	    return selectedEmoji
    end if
end tell

As you can see, the output can be reused, which is always a good thing. Here’s the rest which shows you how the AppleScript is embedded in a simple macro:

Kaomoji Macro

DOWNLOAD

4.2 Apple Mail “Reply To” Example

Aside from Gabe’s Quick Note macro there’s also Federico Viticci’s recently released macro for Automating Mail Signatures and Senders with AppleScript and Keyboard Maestro. His post provided the initial spark to write this article since I forgot about this feature which I so deliberately abandoned from my workflow until now.

Emoticons are great and all, but they usually don’t count towards having anything to do with productivity. So, here’s a more useful example for Apple Mail users. I checked with Federico and he allowed me to tinker with his AppleScript.

How the reply to macro works

Like outlined above, the advantage is that you can navigate the list with the arrow keys and even type the first one or two letters to jump directly to an entry. For instance if I want to repsond via my zapp@brannigan.com address I just need to press z and the entry gets selected.

Here’s the AppleScript to set this up:

-----------------------------------------------------
--	Name: Simple List Handler for Apple Mail
--	Author: Patrick Welker <http://rocketink.net>
--	Version: 1.0 (July 21, 2013)
--	For Apple Mail and Keyboard Maestro (<http://www.keyboardmaestro.com>)
-----------------------------------------------------
--	Apple Mail Part borrow from Federico Viticci of MacStories (<http://www.macstories.net/tutorials/automating-mail-signatures-and-senders-with-applescript-and-keyboard-maestro/>)
-----------------------------------------------------
--	Installation
--	1. Use this script with an "Execute AppleScript action" and assign a hot key to it, c.f. ⌘R
-- 	2. Add/Remove your list items and setup a default item in the configuration below
-----------------------------------------------------
--	Configuration
property emailList : {"Federico Viticci <viticci@macstories.net>", "President of Special Business <prompt@5by5.tv>", "Federico Viticci <me@ticci.org>", "Federico Viticci <viticci@me.com>"}
property defaultEmail : "President of Special Business <prompt@5by5.tv>"
property signatureList : {"Signature #1", "Signature #2", "Signature #3", "Signature #4", "Signature #5", "Signature #6", "None"}
property defaultSignature : "Signature #1"
property cancelSignatureDialog : true -- If Cancel/ESC dialog then use no signature; set to false for default signature
--	Optional
set titleEmailDialog to "My Adresses List"
set titleSignatureDialog to "Pick Signature"
-----------------------------------------------------
tell application "Keyboard Maestro Engine"
    activate
    --	Prompt for "Send From" Address
    set selectedEmail to choose from list the emailList with title titleEmailDialog default items defaultEmail
    if selectedEmail is false then -- Cancel script
	    beep 1
	    error number -128
    else -- Gets the selected list and creates a variable
	    set fromAccount to selectedEmail as text
    end if
    --	Prompt for signature
    set selectedSignature to choose from list the signatureList with prompt "For no signature press Cancel." with title titleSignatureDialog default items defaultSignature
    if selectedSignature is false then -- If cancel rules
	    if cancelSignatureDialog then
		    set selectedSignature to ""
		    set mySignature to selectedSignature as text
	    else
		    set selectedSignature to defaultSignature
		    set mySignature to selectedSignature as text
	    end if
    else
	    set mySignature to selectedSignature as text
    end if
end tell
--	Apple Mail: fills in "From Address" and chosen signature
tell application "Mail"
    activate
    set theSignatureName to mySignature
    set theMessages to the selected messages of the front message viewer
    set theMessage to first item of theMessages
    set theOutgoingMessage to reply theMessage with opening window
    set message signature of theOutgoingMessage to signature theSignatureName
    set sender of theOutgoingMessage to fromAccount
end tell

DOWNLOAD

5. The Combined Power Of Palettes And Lists

Since lists and palettes are only two different ways with the same goal in mind, it’s obvious to combine them to get automation done more efficiently.

I just have started with using lists after Federico’s post and right now I only have one bigger use case with which I’ll also end this post.

5.1 Prelude - My setup for managing notes and lists

Before I go into detail on the palettes and lists in my repertoire, let me give you a brief introduction on what I use on the Mac and what apps I prefer on iOS. It’s just a short description to give you a better idea of why I choose the macros in the upcoming sections and an why this works for me.

5.1.1 The Mac

nvALT is my database for almost every Markdown or plain text file on my Mac. My notes folder lives in Dropbox which is my favorite way of syncing my documents to iOS while still having easy access to them on the Mac. iCloud has never worked for me, it’s just not my kind of sync. I can’t stand the idea of data I frequently access being tucked away in the depths of OS X. Keeping my notes on my NAS would also be a good solution. Sadly there are close to zero iOS text editors with support for WebDAV – Brett Terpstra’s iTextEditors lists only 6 editors which support this feature at the moment.

There are a lot of editors I have installed (and use) on my Mac, but the point here is not to list and praise them all here, it’s rather highlighting the fact that having my notes in one location makes it easy for me to find and edit them.

I have three types of plain text files in my notes folder which serve different purposes:

  • .md for all notes
  • .txt for all lists
  • .taskpaper for my projects

5.1.2 iOS

On iOS my main editor is Notesy – it’s my nvALT for the iPhone/iPad. In addition I manage my lists with the relatively young Listacular which has recently replaced Listary for me.2

Listacular does a splendid job at managing lists. It reads two file formats (.txt and .taskpaper) and has basic Markdown support. Its trick is that it differentiates between the various Markdown list markers. By using an asterisks your list stays a list, when pre-appending a hyphen you get a todo list with checkboxes.

This works for me because my (running) lists all have a .txt extension. The good thing with this approach is that I only see what I want to see on Listacular: lists.

Facts about Listacular:

  • it doesn’t allow to choose or ignore extensions like other text editors do (= if you have .taskpaper files in your notes folders they will show up and there’s no way to avoid that)
  • no support for .md files
  • it can merge lists making it a good alternative to share grocery lists and alike
  • it’s free for up to three lists (the upgrade costs $2.99 via IAP)

5.2 The Notes Palette

There are some repetitive patterns in my workflow. One of them is creating new notes and lists, the other is adding to my already existing lists. The notes palette (⌘Page Down) aims to be my starting point for any of those actions. It’s a work in progress and I’m not sure wether I keep all of the macros, remove some or even add more to it from my global palette (^Space) like ‘create a new email’.

The structure of the palette:

Notes Palette

Credit: all icons used in the macros are made by Alex Shutin from The Working Group.

5.2.1 Appending To An Existing List

The “1. Add to List [A]” macro just opens another palette for one action like this:

execute macro action

Since all of the 4 macros basically perform the same action, I will only cover the first one here (which also happens to be the longest macro out of those four).

(1) After starting the macro, a list pops up and I can pick which list to add something to. The script is structured just like in the example at 4.1 with the kaomoji emoticons.

available lists

(2) Next there’s a prompt where I enter my list items. Remember, you can always create multiline notes by adding a line-break with ⌥↩ – don’t worry about Keyboard Maestro only displaying one line.

(3) What follows are all the if conditions for the various lists:

  • My scratch file is formated as a normal Markdown note (with readability in mind). It adds a level 3 header, the date and time to each entry.
  • A new OmniFocus entry is created via OmniFocusCLI: Natural Language Tasks by Don Southard. In my honest opinion, it’s the best way to get tasks into OmniFocus – OmniFocus doesn’t even have to be open (and also won’t get opened). Read the blog entry to learn why it’s a brilliant implementation and how to install in on your system.
  • My various running lists. Each line I’ve entered in (2) will also be a new line in the corresponding list pre-appended by an asterisks to match Listacular’s list syntax.
  • My grocery list. Same as the running lists, but the list marker is a hyphen to make the entries show up as tasks in Listacular.

(4) Play a sound, send a notification and delete all variables. √

A visual representation of the macro:

UPDATE: I added an easier to maintain version here.

append prompt

DOWNLOAD

5.2.2 The Blog Palette

the blog palette

I just added this for the sake of giving you the overall picture of the setup. Going into details would go beyond the scope of this post.

One last note, the “Edit Post” macro makes use of the AppleScript which I’ll introduce in section 5.2.4. Often times I need to correct some spelling mistakes and that’s where this macro jumps to the rescue. It opens up a list with all my posts and syncs them to my Jekyll blog after I’ve finished updating them.

5.2.3 Create A New Note Or List

To be frank: I’m not too fond of these. They are a mix between the add to list macro from 5.2.1 and the recently modified macro in 5.2.4. These macros started as a proof of concept and gradually evolved into something bigger.

Both macros (i) create a new text file (note = .md, list = .txt), (ii) prompt you for a name, (iii) open up the note in the editor you choose from a list, (iv) ask you if you’d like a preview in Marked and if you answer with yes (v) the two windows get aligned filling one half of the screen each. Admitted, this is pointless when you start with a blank canvas, that’s why…

5.2.4 Edit And Preview Recently Modified Notes

This AppleScript is the secret star of this blog post and also resembles my 1st serious go at doing something with Apple’s scripting language. The aim was to make it versatile, useful and something that people could in fact integrated in their note taking or reviewing workflow.

In a normal week I drop several notes into nvALT. It often happens that those files are somehow project related and that I keep coming back to the same documents within said week just to edit them. That’s where this script can come in handy. It prompts you for several steps:

Recently Modified Notes

Most parts are customizable. You can optionally turn on Marked to always open up, same goes for the window aligning (which I borrowed from Rob Trew) and some other options. Take a look at the user configuration part of the script where I also explain briefly how to set it up and where the known problems are at.3

Side note: I had problems embedding this script, so here’s a link to the Gist for now.

DOWNLOAD

DOWNLOAD PACK (OF THIS POST)

Versions of the script I use

At present I run several trimmed down versions of this script. They are shortened because I don’t want to get prompted all the time and want a specific behavior for certain actions. If you find the script useful, I’d advise you to just edit the file to your liking. Here are my iterations:

  • Show me the 10 last drafts for RocketINK and open the selected one in FoldingText with a Marked preview (without asking me anything).
  • Show me all my TaskPaper files and open the selected one in TaskPaper without opening Marked.
  • Show me the 12 last nvALT notes with @reference in the title
  • Show me all my blog posts and prompt me to open them in Sublime Text or FoldingText, also open up Marked.
Other possible use cases
  • If you’re active on GitHub you could make a list of all your ReadMe files. Then, if you update a repo just choose the corresponding repository ReadMe and edit the document in your favorite editor. Advanced users could also setup a commit and upload action.
  • Add an additional prompt to enter a search term for viewing the last 10 modified notes in nvALT that contain a specific word or tag. You just have to enter another prompt for the “searchNotes” property.

Note: If your not into the script but use nvALT then add this nvalt://find/* to your LaunchBar or this nvalt://find/{query} to your Alfred searches. … I had to mention it because I’m not sure every nvALT’ler knows about the URL scheme. I use it all the time.

  1. A hat tip to Sean Korzdorfer who introduced me to this site by tweeting about it. A great resource for fans of this modern Japanese tradition.

  2. Listary is a superior app, but it depends on Simplenote which I don’t use anymore. It has a lot of features Listacular lacks at the moment, but so far I’m happy with my decision.

  3. In short, the easiest way to get this running at the moment is to export the script as an application. I know… not the best solution, but I hope some clever person will point me in the right direction to make it more Keyboard Maestro/Service/LaunchBar friendly.

comments powered by Disqus

Related Posts