Script: Finder/New Plain Text File

  • Script: New Plain Text File
  • Application: Finder
  • Suggested key binding: ⌃⌘N

This script tackles a major oversight in the Finder UI; namely, the ability to create a new blank text file.

It behaves similarly to the Finder’s New Folder command: It defaults the name to “untitled.txt”, it enters rename mode immediately after creation, and it appends numbers to the name to avoid name clashes, so you can create many new files at once.


A TL;DR Interlude Spliced With Delicious Bits of Otherwise Irrelevant Code

require 'appscript'
require 'fileutils'
require 'pathname'

Now, there are many tools like this out there, but this one is mine, and mine is better. Here’s why:

A good chunk of such tools bury the option to create a new file deep within context menus, pretty much missing the point. If I have to do mouse gymnastics to get my file, I might well use the text editor’s menus instead. A particularly egregious manifestation of this burial is when this feature is implemented as a Service: the Finder does not make available the menu items for Services in the situation where one would need “New Plain Text File” most commonly: in the context menu for the blank area of folder window, where you trigger it without selecting any of its items.

TFF        = Appscript::app("Finder")
TFFProcess = Appscript::app("System Events").application_processes["Finder.app"]

More significantly, most tools try to do too much. The ability to create files of different types is king amongst them. This is definitely influenced by the way this feature exists on Windows. It’s also—unsurprisingly, given the source—terribly lame; I never ever need to create a file from the Finder that’s not a text file. I have a theory about that:

path_to_desktop             = Pathname.new "#{ENV['HOME']}/Desktop"
path_of_insertion_location  = Pathname.new TFF.insertion_location.get(:result_type => :file_ref).get(:result_type => :alias).path
path_of_first_finder_window = Pathname.new TFF.Finder_windows.first.target.get(:result_type => :alias).path rescue nil
is_desktop_the_active_view  = path_to_desktop == path_of_insertion_location && path_of_first_finder_window != path_to_desktop

Often the need for a text file arises while moving things around in the Finder. You’re organizing your files and you need to put down some notes along with them. In that case it’s great that you’re already in the folder where you want your new file. It makes more sense to create it right there and then than to open an editor and use the save dialog to navigate all over again to where you’re already at.

basename  = "untitled.txt".tap { |s| s.sub!(/( (\d+))?(?=\.txt\z)/) { " #{($2||1).to_i.succ}" } while path_of_insertion_location.join(s).exist? }
file_path = path_of_insertion_location.join(basename)
FileUtils.touch(file_path)

TFF.activate
TFF.insertion_location.update
sleep 0.3 # increase the chances that the \r keystroke that follows will hit the proper selection

Even when that’s not the case, text files crave to be named. I submit that the name of a text file is much more important, than, say, the name of a spreadsheet or a Photoshop document. With text files, it’s integral to the text. It’s often the case that it comes to me even before the text itself. Hence the workflow where I create it, name it, and then edit it makes a lot more sense. With a Photoshop comp, the image you want to draw comes to you first, so you go ahead and draw it. The file name is an afterthought. It is, truly, metadata.

# attempt to select the newly created file
is_desktop_the_active_view                      ?   # When you call `select` for an item on the Desktop, a new Finder window is opened and the
  TFFProcess.keystroke(file_path.basename.to_s) :   # file is selected in that window. We don't want that, so if the Desktop is active, we try
  TFF.select(MacTypes::Alias.path(file_path.to_s))  # to type out the file name to cause its selection directly on the Desktop. /hack

To be perfectly strict, there’s another case where I want to create a new, named file in the current Finder window, then open and edit it. When I need a new script. But what is a script if not a particular case of a text file, maybe with a different extension? So, as I trigger New Plain Text File and it enters rename mode, I just type ⌘A to include the extension in the selection, and type over the entire name.

# press return to enter rename mode
TFFProcess.keystroke("\r")

Recapitulating it, this is one is better because:

  • It’ll only create one type of file: empty plain text files. The UI indirection and the mental tax that come with having to pick a file type are blissfully nowhere to be found.
  • It’s goddamn keyboard driven. Even neurosurgeons and miniature artists get frustrated to death when trying to navigate menu trees. No so much with pressing key combinations.
  • I wrote it.

An Epilogue About the Officially Suggested Key Binding

While ⌃⌘N is nice because it follows the New Window / Folder / Smart Folder pattern of ⌘N / ⇧⌘N / ⌥⌘N, it actually sucks because you can’t uncontortedly trigger it with a single hand. If you’re like me and probably pretty much everyone else, you never invoke the New Smart Folder command, so you might well use ⌥⌘N for this script.


ATTN: Skip Here for the Goods

As usual: get the standalone script file, or git pull if you’re keeping a git clone of the scripts.

You may also check it it in all its colorful glory (and in a single piece) on github.


This post of part of series on the scripts I use with FastScripts.

Got comments? Use reddit and/or poke me on twitter.