Flaky Goodness

Paste as Code

October 11, 2018

2018-10-11-paste-as-code-demo.gif

Copying source code from a plain text editor and pasting it into Keynote, Pages, an Office document or some other rich text application often yields disappointing results. Where is the monospaced programming font? Where is the syntax highlighting? Why is the indentation all messed up?

This little Mac automation allows you to paste a copied code block as fully formatted, syntax highlighted code and works with many different languages. It leans on the Pygments project to do the heavy lifting. Many thanks to Brett Terpstra for pointing me in the right direction when I was getting started with this.

Step 1: Install Pygments

The required version of Python is already installed on macOS. You just need to:

pip install Pygments

Step 2: Choose how you want to invoke the automation

BetterTouchTool

Starting from version 3, it is possible to create this automation using BetterTouchTool.

2018-10-11-paste-as-code-1.png

I’m using ⌃⌥⌘ V as the shortcut trigger but you can use whatever you like. The shortcut has three actions:

  1. ⌘C (copy selected text to clipboard)
  2. Trigger predefined action: Controlling Applications > Execute terminal command (synchronous, blocking): see below
  3. ⌘V (paste processed text and replace current selection)

Step 2 (Trigger predefined action) is the important one.

2018-10-11-paste-as-code-2.png

The terminal command is:

pbpaste | awk '{ gsub(/\t/, " "); print }' | /usr/local/bin/pygmentize -f rtf | pbcopy

To try this out, select a block of unformatted code you’ve pasted into your rich text application, trigger the automation with ⌃⌥⌘ V, and watch as the code is first copied to the clipboard, run through the pygmentize command which converts it to nicely formatted RTF text, and then pasted back over your original selection.

Or, just copy some code from your editor, switch into your rich text application and (without selecting anything) invoke the trigger keystroke. The formatted code will be pasted in.

Quicksilver

I use Quicksilver and this is how I usually Paste as Code. I’ve added a custom trigger that uses the Run Text as an AppleScript action to run this code:

delay 0.5 tell application "System Events" to keystroke "c" using command down do shell script "/bin/bash -c \"pbpaste | awk '{ gsub(/ /, \\\" \\\"); print }' | /usr/local/bin/pygmentize -f rtf | pbcopy\"" delay 0.5 tell application "System Events" to keystroke "v" using command down

This works just like the BetterTouchTool automation.

TextExpander

If you already have the plain text on your clipboard you can use TextExpander to paste the formatted version at the insertion point. Here is the snippet. Be sure to set the Content type of the snippet to AppleScript.

do shell script "/bin/bash -c \"pbpaste | awk '{ gsub(/\t/, \\\"  \\\"); print }' | /usr/local/bin/pygmentize -f rtf | pbcopy\"" delay 0.5 tell application "System Events" to keystroke "v" using command down

My TextExpander abbreviation for this is ;code

Quick tips and final notes

You can put a whole (plain text) source file on your clipboard in a hurry, and you’re ready to Paste as Code.

cat my_source_file.js | pbcopy

If the snippet you copy is too short, semantically ambiguous, or in an unsupported language, pygmentize will not be able to apply correct syntax highlighting. In that case you’ll get monospaced text without the colors. If you often find yourself pasting short snippets of, say, bash scripts that pygmetize has trouble detecting you can create a bash-specific shortcut using this command-line:

pbpaste | awk '{ gsub(/\t/, " "); print }' | /usr/local/bin/pygmentize -l bash -f rtf | pbcopy

In this case the -l bash forces pygmentize to color the snippet as a bash shell script and skip auto-detection. Here is the list of supported lexers.

If you find Paste as Code useful and have any ideas for how to make it better please let me know.