Simple shortcut replacement

Fixed …

@dchar What you did with Drafts App action, does this exist on a Mac? Perhaps in Keyboard Maestro or something similar?

1 Like

This is awesome, thanks for sharing. Great piece of work.

Is it possible to have “Comments” that are ignored in the actual shortcuts draft that the shortcuts are defined in? I tried the default comment syntax of a # symbol for YAML, but it doesn’t seem like it allows expansion. I really just want it to skip over any lines that start with the # symbol; I don’t think this warrants any special algorithms to detect if that symbol is found after the beginning of the line. Essentially:

1 | # This is a comment describing the snippet below
2 | .prj
3 |   - Project 1
4 |   - Project 2

I want comments so that I can define my shortcuts a bit more descriptively in case I need to go back after a while and recall what it was for modifying the shortcuts. Hope that makes sense!

Nevermind; this was my mistake. Comments work fine!

1 Like

Can you please check

.longphrase: "

This is a long phrase

that is split across

multiple lines."

Results in a in “block style” without using “|”

Edit: I figured it out. You have to use an escape from YAML. Empty lines should contain \ in them.

1 Like

I just wanted to say thank you for this wonderful shortcut. I had been using TextExpander for my snippets in Drafts, but because I was only using it for Drafts, it didn’t feel like it was worth the monthly charge. I wanted something that would replace it using some automation, and your script exactly fit the bill.

I’ve made a couple of tweaks to your script since installing it. One was just to make it run from a directory of text files in the Drafts /Library directory. That’s really just personal preference: I prefer these kind of configuration files to be outside of my Drafts database. The other I have found really useful is to process the replacements through the draft.processTemplate method. This means I can have a snippet like .ddd: "[[date]]" which expands to today’s date. (I’m not quite sure why, but it only seems to work with the quote marks present.) Thought this second tweak might be something you would be interested in incorporating into your version.


Please message me patches of your changes.

For the second tweak, I just edited your replaceAll function. Here’s my new version:

function replaceAll(text, searchValue, newValue) {
    return text.split(searchValue).join(draft.processTemplate(newValue));
1 Like

@pdavisonreiber I added your changed and updated the documentation. Thanks!

Drafts Template Tags

Shortcuts can include tags that will be expanded by Drafts’ template engine. Some useful tags are [[date]] and [[template|path]].

Tags must be enclosed within double quotes when defining a shortcut as shown below.

.date: "[[date]]"

.location: "[[latitiude]] [[longitude]]"

.disclaimer: "[[template|corporate-disclaimer.txt]]"



Hi and thanks again for your great work!

I combined the action you made with this one to be able to use both - defined shortcuts and also placeholders for e.g. names and so on which arent defined as a shortcut.
This is really useful for me because often I write Messages / E-Mails to persons just a few times - and its not neccessary to save their names as a shortcut. The message itself stays the same so this way I have the benefits from both actions!
Another very important point is that I dont want the original template for a message to be replaced with the inserted values, thats why i create a duplicate of the parsed body and the template can be used 100s of times.

If somebody is interested I can share this to the directory, but I just need to make some tweaks for sharing the parsed draft.


Hello FloGroh,
I am interested in this modification, as it also affects my workflow and use case relatively exactly. Thanks for sharing.

@all: Thank you so much for sharing this workflow, great.

1 Like

Hi, here you go:

Personally I use the Share Action with this script (I didn‘t share it because its not very well developed baut ist works:) ):

var p = Prompt.create();
p.title = "Share draft:";
p.message = "Select an option or cancel if you need the draft later.";
var buttonArray = ["iMessage","WhatsApp","Clipboard","E-Mail"];

for(str in buttonArray)


var didSelect =;

if(didSelect == true)
	var selection = p.buttonPressed;
	if (selection == "iMessage")
		var msg = Message.create();
 		msg.body = draft.content;
		var result = msg.send();
		if (result == true)
			app.displaySuccessMessage("successfully sent iMessage");
		} else
			app.displayWarningMessage("did not sent the iMessage");
	} else if (selection == "Clipboard")
	} else if (selection == "E-Mail")
		var mail = Mail.create();
		var mailP = Prompt.create();
		mailP.title = "E-Mail Subject";
		mailP.message = "select subject for your E-Mail";

		mailP.addButton("use custom subject");
		mailP.addTextField("custom subject","custom subject","");
		mailP.addButton("use title of draft");		
		var titleIsSubject = 0;
		var mailPdidSelect =;
		if(mailPdidSelect == true)
			var mailPselection = mailP.buttonPressed;
			var subject;
			if(mailPselection == "use title of draft")
				subject = draft.title;
				titleIsSubject = 1;
			} else if (mailPselection == "use custom subject")
				subject = mailP.fieldValues["custom subject"];
			mail.subject = subject;
		if(titleIsSubject == 1)
			mail.body = draft.processTemplate("[[body]]");
		} else
			mail.body = draft.content;
		var result = mail.send();
	} else if (selection == "WhatsApp") {
		if (device.model == "iPhone") {
			app.openURL("whatsapp://send?text=" + encodeURI(draft.content));
		} else {
			alert("WhatsApp is only possible on iPhone");"Share via WhatsApp is not possible on" + device.model + ".");

First off, this action is incredibly useful. Thanks!

So it was inevitable. An action this useful has to go meta and start getting used on code. I have pieces of code that I use a lot and it’s easier to do this quickly. But the following snippet gives unexpected results because it’s interacting with your code. If I break it on purpose, everything comes out just fine.

.split: |
// Quick line split
var text = editor.getText();
text = text.split("\n");
text = text.join(" \n");


Since .split is likely to appear in the code, I’d suggest a different shortcut string like $split or ,,split:

,,split: |
  // Quick line split
  var text = editor.getText();
  text = text.split("\n");
  text = text.join(" \n");
1 Like

:man_facepalming:t2: Of course that’s it! Fabulous. Thanks a ton!!