I'm trying to create a macro that checks to see whether zero, one, or several text files with filenames matching a certain pattern exist in a specific folder. If one such file exists, the macro should open it; if several exist, the macro should offer me the choice of which one to open; and if no such file exists, the macro should alert me and either quit, or open another text file (which is a template for me to create the desired file). But I'm a bit tangled up. Details below.
I travel a certain amount, and often have a text file going that lists everything I need to do to prep for the trip. The file is always titled "before leaving for X," where X might be "DC" or "Finland" or whatever. Currently I have a macro that checks to see whether a global variable called BeforeLeavingFile already exists and has a valid file path in it; if so it opens that file for me, and if not it used a Prompt for File action to ask me what file I want, assigns its path to the variable, and opens it. If I haven't created the file yet, I just quit the macro instead of selecting a file, manually open a preexisting template off of which I create the file I want, and then select that one on next run.
But right now I'm prepping for multiple trips. So I want to ditch the global-variable strategy (probably?) and instead have a macro that checks to see whether zero, one, or several files exist with filenames beginning "before leaving for" exist in the relevant folder. If one exists, the macro should open it; if several exist, it should offer me the option of which to open; and if none exists, it could either alert me and quit or, better, open the template file. (If there are several such files, ideally I'd just have to hit a single key that distinguishes them, such as D or F in the "DC and Finland" example; I'm used to working with conflict palettes that offer multiple options that way.)
I think I should be gathering the relevant filenames somehow and then putting them into a Prompt with List action? But I don't know how and am feeling confused about how to figure it out. Grateful for help!
The two green boxes contain values you'll have to change. The first is the path to the folder that holds your travel files. You could replace this with a Prompt for Folder action if you wanted, so you could choose a different folder each run.
The second green box is the path to your template file.
You might also have to change the "Find all files matching the name pattern in the folder" action, as I named the files "Before leaving." If yours are "before leaving," then change the text to match.
The way this works is that it uses the find command to find all matching files in the specified folder. If none are found, it opens the template file.
If matches are found, it uses a regular expression to change the full path (returned from the find command) into a format suitable for Prompt With List. So if a file is here:
/Users/you/Desktop/TravelFolder/Before leaving for DC.txt
The regular expression converts that into this:
/Users/you/Desktop/TravelFolder/Before leaving for DC.txt__Before leaving for DC.txt
This way, you see only the filename in the Prompt With List, but the full path is returned when you select a file. The last step then just opens the file. Note that if you have any double underscores in your path, this will break, and they'd need to be converted first ... so hopefully you don't have any :).
I think this does what you want, but let me know if you have questions/problems.
That works, and I could not have written that line of script at all, so thank you! I am definitely learning things from your construction of the regex, and am pleased with myself that I figured out how to tweak it to so as not to bother displaying the filename extension. And I will never have a double underscore in a file name.
(I added a Cancel This Macro action after the "If No Matches" check; otherwise the Prompt with List action tries to run with an empty file list; and I put the complete folder path in so that I could take out the tilde-path correction.)
One question if you feel like being even more helpful: Because all the filenames begin with the same fairly long string, if the one I want isn't alphabetically first I have to type one or more down arrows and then hit enter. Unfortunately the Prompt with List action won't look ahead to the first difference in the options, the way a conflict palette will. Can you think of any way to make the list work like a conflict palette, so that only one distinguishing keystroke is required?
Now you can type just the number to select the item of interest. The other option would be do to more name arranging: Grab the name of the city from the filename, and just display that for selecting:
Oh, that second one is gold. I mean, it's all great, but since I already have the destination in mind when I trigger the macro, somehow the cognitive load of just hitting the first letter is noticeably less than that of matching it to a number or tracking down-arrow keystrokes. Thank you so much for your help! (I'm good with KM and Applescript and can manage basic regex though I hadn't thought through how to do so in this case, but I haven't formally studied programming since before perl was developed...)
Here's a variation that avoids (for no other reason than "because" ) the shell and regex that @griffman used.
It'll prompt you for the folder to check, or you can replace that with a "Set Variable" and a hard-coded path. As with @griffman's you'll have to set the path to your template file.
Using "vanilla" KM actions makes it longer, but it shows what you can do with a "For Each" and pseudo arrays. And while it does needlessly check all the files that are alphabetically before "Before..." it won't process any starting with "Bg" or later.
I knew someone would post this version :). Mine is definitely less readable, but I decided to see if I could write it without using a For-Each loop, hence the shell and regex.
Is there anything more fun than starting a one-upmanship war between helpful coders? Thanks, Nige! When I was trying to do this with KM-native actions I figured an array was probably the answer, but I've never actually used them in KM -- and wow, that trick you did with the custom delimiter, very cool! (I've been perusing the wiki page to figure out just what you were doing there. Today I learned!)