Save clipboard text to the current folder
One scripting option that is often overlooked on the Mac is the Finder toolbar. You can drag any application into the toolbar and it will then be available for clicking in any open Finder window—or for dragging and dropping files from an open Finder window onto the icon.
You can use this as a simple shortcut for items that would normally go under the Services menu, but it is especially useful for doing file-related things that don’t involve selecting files. There is no Services menu in Finder windows if nothing’s selected, but there is a toolbar.
I often have text in the clipboard that I want to save to a file. Very often I can see the folder I want that file in, open in the Finder. It’s annoying to see it right there and still have to go into Terminal to type pbpaste
then into the Finder to drag the folder’s drag icon onto the Terminal then back into Terminal to press return. Or, in the case of iA Writer, to have to create the document, paste it in, rename it, drag the title bar icon of the correct location to the Move dialog1 and then approve a move out of iCloud.
It would be a lot easier to have an icon in the Finder toolbar that would automatically dump clipboard text to a text file right there.
Often the text I’ve copied is a subset of a Markdown file. I’ve decided to make one collection of subthoughts in a post be, instead, the main thought in another post. It would be great if this hypothetical script could shift headlines to the left as necessary to make the top line be a top-level headline.
This script will do both of those tasks. It will prompt for a filename to save the clipboard text to, using the folder displayed in the current Finder window as the default location; and it will modify Markdown headlines, shifting them left appropriately to make the first paragraph be a top-level headline.
Open Script Editor on your Mac, and paste this in:
[toggle code]
-
on run
- --get the clipboard text
- set clipboardText to the clipboard as text
- --take a wild guess at an appropriate filename
- set defaultFilename to the first paragraph of clipboardText
- --if this is markdown, shift headlines to the left as appropriate
-
if defaultFilename starts with "#" then
- --remove extra pounds from the filename, keeping track of each
- copy defaultFilename to markdownCheck
- copy "" to headlineShift
-
repeat while markdownCheck starts with "##"
- set headlineShift to headlineShift & "#"
- set markdownCheck to the rest of the characters of markdownCheck as string
- end repeat
- --if the line begins with a pound, a space, and some text, it is probably Markdown
-
if markdownCheck starts with "# " and the length of markdownCheck is greater than 3 then
- --first, clear the headline marker from the default filename
- copy characters 3 thru -1 of markdownCheck as string to defaultFilename
- --then, shift all headlines left so that the top headline is a top-level headline
- copy markdownCheck & linefeed to newText
- copy the (length of headlineShift) + 1 to poundsToShift
-
repeat with rawParagraph in the rest of the paragraphs of clipboardText
- --this makes it easier to work with the characters of the paragraph
- set rawParagraph to rawParagraph as string
-
if rawParagraph starts with headlineShift then
- copy characters poundsToShift thru -1 of rawParagraph as string to newParagraph
- set newText to newText & newParagraph & linefeed
-
else
- set newText to newText & rawParagraph & linefeed
- end if
- end repeat
- set clipboardText to newText
- end if
- end if
- --ensure a reasonable filename length
-
if the number of characters of defaultFilename is greater than 32 then
- set defaultFilename to characters 1 thru 32 of defaultFilename as string
- end if
- --make sure the default filename ends with .txt
-
if defaultFilename ends with "." then
- set defaultFilename to defaultFilename & "txt"
-
else if defaultFilename does not end with ".txt" then
- set defaultFilename to defaultFilename & ".txt"
- end if
- --get the current folder
-
tell application "Finder"
- set currentPath to (POSIX path of (target of front window as alias))
- end tell
- --ask for a filename, defaulting to the current folder
- set theFile to choose file name default name defaultFilename default location currentPath
- --write the clipboard to the file
- set destination to open for access theFile with write permission
- write clipboardText to destination as "utf8"
- close access destination
- end run
Save it as an Application. I named it “Save Clipboard”. You can save it wherever you want, since you'll be putting it in the toolbar. If you don’t have a place yet, make a folder called “AppleScripts” in your Documents folder.
Put Save Clipboard in the toolbar by holding down the COMMAND key and dragging the application into the toolbar on any open Finder window.
The script uses the first paragraph of the clipboard to create the suggested filename, adding .txt
if, as is likely, the first paragraph doesn’t already end in .txt
. This suggested filename is almost never exactly correct, but it does often contain appropriate words for the filename. This is especially true if the first paragraph is a Markdown headline.
Since I’ve put this into the Finder’s toolbar the front window
is always the folder I want—it’s the folder on whose toolbar I clicked Save Clipboard
. All I have to do is click “Save Clipboard” in the Finder’s toolbar, and up pops the query about the filename, defaulting to the folder that was open when I clicked the button (and is still open). Of course, I can change the folder from that dialog if I want to; the script won’t care.
And, boom! Whatever text is in the clipboard is saved in a text file in the current folder.
If you change your mind about saving, you can cancel the request for a filename; AppleScript automatically closes the application if the user cancels a display dialog
or choose filename
request.
There are a couple of tricks in here that you don’t normally see in AppleScripts. Both involve making sure that the text file is a generally useful text file in OS X. The first is that instead of using return
as the line delimiter, it uses linefeed
. The return character (ASCII 13) is the classic MacOS line feed, but nowadays macOS uses the linefeed character (ASCII 10).
The second is that the file must be saved as UTF-8. If you leave off the as "utf8"
text editors such as Textastic and iA Writer won’t read it correctly. Textastic sees it as Mac Roman, but the characters are messed up. It’s possible that it’s saved as UTF-8 but marked as Mac Roman.
In any case, by saving as UTF-8 with linefeeds for breaking lines, it will be a normal macOS text file.
There are a couple of assumptions in the script that work for me but may or may not work for you. If the first paragraph indicates that this is Markdown text because it’s a Markdown headline, and the headline is marked by two or more pound signs, the script will attempt to shift all headlines left by the same amount that the first paragraph had to be shifted to make it a first-level Markdown headline.
Because AppleScript doesn’t have regular expressions, however, the easiest way to do this is to check whether each paragraph begins with at least as many pound signs as we’re shifting left. If it does, it removes those pound signs. It does not check that the pound signs are succeeded by a space, which is of course required for a Markdown headline.
The easiest way to do this would be with a regular expression, but AppleScript doesn’t have regular expressions built in. The next easiest would be one of three options:
- Use
do shell script
to call a scripting language that does have regular expressions. - Check after shifting that the paragraph now starts with a succession of pound signs followed by a space.
- Write the app in Automator using various subscripts in each action.
- Or, more likely, look at using Foundation and NSString with AppleScript. This would allow the use of all of the methods included with NSString, including replace by regular expression.2
Any of these might end up being the best solution; my plan is to wait until I need the functionality—which may never happen—before trying to implement it.
Similarly, I make the assumption that I’m copying a valid outline-like set of Markdown headlines. Not only does it not check to see if there is a space after the remaining pound signs, it doesn’t even check that there are pound signs left over. If the first headline has, say, two pound signs, and there is another headline with only one pound sign later on, the script will remove all of the latter’s pound signs, making it no longer a headline at all. If this ever becomes a problem, I’ll need to look at what I would expect the script to do on that text. Right now, I can’t see why I would ever copy unbalanced headlines.
I could change if rawParagraph starts with headlineShift then
to if rawParagraph starts with headlineShift and character (poundsToShift+1) of rawParagraph is "#" then
and it would not remove the pound signs—but then any subsequent headlines would still be shifted. What I would probably have to do is stop at that point and not shift any more headlines. But since I can’t see why I’d be copying such text, I can’t be sure if that assumption is true.
There is an issue which doesn’t happen often, in which the Save dialog displays the wrong folder for saving to. I’ve verified that the default folder given to the dialog is the correct one, so this is likely some sort of residual memory in AppleScript’s call to the Finder. But it doesn’t happen often, and even when it does saving clipboard text this way is still faster than the alternative.
An action which itself has become more time consuming in Big Sur, since there’s now a wait between moving the mouse to the title of a Finder window and seeing the folder icon for dragging.
↑This would make it easier to really clean up the first line for use as a filename, such as by removing any HTML tags or Markup that happen to be in the text.
↑
- ia Writer for iOS and Mac OS
- You have to enjoy using asterisks and/or underscores for emphasis, and hashes for headlines, but if you do, ia Writer is a great app for writing and note-taking on Mac OS and iOS.
- Using version control with AppleScripts
- AppleScripts aren’t stored as text, which makes it impossible to track changes in AppleScript files using version control software such as Mercurial or Git.
More AppleScript
- Find all parent mailboxes in macOS Mail
- The macOS Mail app seems to want to hide the existence of mailboxes and any sense of hierarchical storage. These two AppleScripts will help you find the full path to a selected message and open the message’s mailbox.
- JXA and AppleScript compared via HyperCard
- How does JXA compare to the AppleScript solution for screenshotting every card in HyperCardPreview?
- Using version control with AppleScripts
- AppleScripts aren’t stored as text, which makes it impossible to track changes in AppleScript files using version control software such as Mercurial or Git.
- Adding parenthetical asides to photograph titles on macOS
- Use Applescript to append a parenthetical to the titles of all selected photographs in Photos on macOS.
- AppleScript, variables, and dropped filenames in Automator
- Automator is a simple workflow system for Mac OS X. By its nature it is very procedural: one task follows another; workflows don’t loop and they don’t store variables for later. However, this is possible in Automator and while it adds complexities it can also solve problems such as wanting to save dropped filenames for later use.
- 17 more pages with the topic AppleScript, and other related pages
More macOS tricks
- 42 Astoundingly Useful Scripts and Automations for the Macintosh
- MacOS uses Perl, Python, AppleScript, and Automator and you can write scripts in all of these. Build a talking alarm. Roll dice. Preflight your social media comments. Play music and create ASCII art. Get your retro on and bring your Macintosh into the world of tomorrow with 42 Astoundingly Useful Scripts and Automations for the Macintosh!
- Avoiding lockFocus when drawing images in Swift on macOS
- Apple’s recommendation is to avoid lockFocus if you’re not creating images directly for the screen. Here are some examples from my own Swift scripts. You can use this to draw text into an image, and to resize images.
- What app keeps stealing focus?
- I’ve been having a problem on Mac OS X with something stealing focus. Here’s how to at least find out what that something is.
- Enable AirPrint for all connected Mac printers
- I have an iPad and an old workhorse of a printer, an HP 1012 LaserJet, connected to my iMac. I almost never need to print from the iPad, but when I do, handyPrint works.
- AppleScript Preview in Snow Leopard and Lion
- Preview supports AppleScript, but the support is turned off by default. You can enable it with three terminal commands.
- 14 more pages with the topic macOS tricks, and other related pages