Create New File

Making a Service/Context Menu and working around a bug

So in the macOS & iOS group on Facebook, someone was talking about how they miss the ability to just create new blank files of various kinds without needing the app. The replies were, sadly, about what you expect. Non-sequiters about iWork, “you can do this in shell with ease” without actually showing how, and one reference to an application that does make this easy.

So I got to thinking and was like, wait, this can’t be that hard. It turned out to be not that hard, once I realized there’s a bug in the Finder’s scripting implementation. (Shocking, right?). My first attempt at the code, which one would think would work was:

Tell application "Finder" to make new file with properties {file type:"TEXT", name extension:"txt"} at (the target of the front window) as alias) 

Great idea, but fails, because there’s a bug in the Finder scripting implementation where setting the name extension property like this is allowed, i.e., it’s not a syntax error, but it doesn’t actually do anything. Since I want to make sure the file type and the extension are okay, I thought “Okaaay, let me report this bug, but first, I’ll just add a line that sets the extension as a separate step, so we get:

tell application "Finder"

set theFile to (make new file with properties {file type:"TEXT", name extension:"txt"} at (the target of the front window) as alias)

set name extension of theFile to "txt"

end tell

This works, but sort of. Well, every other try. Here’s the folder contents you see to illustrate (not including the tell statements):

first line results: untitled

second line results untitled.txt

Second run:

first line results: untitled (second file)
untitled.txt (first file)

The second line fails because it’s trying to add “.txt” to the second file, which would create two files named “untitled.txt” which causes a -49 error, “already a file with that name”

If you change nothing, and run the script a THIRD time, you get:

first line results: untitled (second file)
untitled.txt (first file)
untitled 2 (third file)

If you run the script again, the cycle repeats. That’s annoying, but it also means if you add a static character to the end of the file name, you still have the problem when you have to add the extension.

So what I finally came up with was:

tell application "Finder"
set theTime to (time of (current date)) as text

set theFile to (make new file with properties {file type:"TEXT", name extension:"txt"} at (the target of the front window) as alias)

set theName to name of theFile & "_" & theTime & ".txt"
set name of theFile to theName
end tell

so first, we get theTime as a string, which is the string version of an integer that represents the number of seconds since midnight. Not intuitive, but, unless you run the script more than once a second, you’re pretty safe. Since this is designed to be a context menu item/service menu item, that’s unlikely.

Now we create the new blank file, unchanged, because hey, one day it might work, Apple might fix an AppleScript bug (just pretend it might happen), and so that line is set.

Next, we create a new string for the name, which includes the extension as part of the name. Playing with the name extension property is kind of fragile, this works more reliably and accomplishes the goal. We add theTime to the end of the name after an underscore, so the name is always unique

Next, set the file’s name to this name we just created, and we’re done!

To make this into a context menu item, usable when you ctrl-click on a folder, you create a new automator action for the Finder, set it to work with files and folders, and you’re set. But there’s a place where this won’t work well: the actual desktop. If you just ctrl-click on the Desktop, no love. If you open a Finder window, go to your home directory, then right-click on the desktop there, this script tends to fail with an error -1700 because it can’t use the Desktop the way we’re trying to use it.

I don’t know why, but I also don’t care, because the workaround is mostly simple. Here’s the code:

tell application “Finder”

set theTime to (time of (current date)) as text

try

set theFile to (make new file with properties {file type:"TEXT", name extension:"txt"} at (the target of the front window) as alias)

on error errMsg number errNum

if errNum is -1700 then

set theFile to (make new file with properties {file type:"TEXT", name extension:"txt"} at desktop as alias)

end if

end try

set theName to name of theFile & "_" & theTime & ".txt"
set name of theFile to theName
end tell

The new lines are the try/end try block. We try to create the new file in the “normal” location, if that fails, we assume this is because it’s the Desktop folder (the only folder I’ve hit that for), so if the errNum is -1700 (integer, not text), we then slightly modify the new file line to create it using the built-in “desktop” location that the Finder’s dictionary knows about. Once that’s done, we dump out of the try block and the last lines are just the same as the other version.

This service in automator is still a Finder action, but takes no inputs. So it never shows up in the context menu, but it is available via the “Services” menu in the Finder’s “Finder” menu. It’s not as great as I’d like, but it gets the job done, and you can create different versions of these for whatever file you want, word, excel, jpeg, whatever.

It’d be nice if Apple fixed this bug, because honestly, this should be one line to create the file. I’m undecided if the -1700 error issue is a bug or just something I dislike.