Tag Open File(s)/Document(s) w/o Interacting w/Finder - UPDATED v.1.3

TAG OPEN DOCUMENT(S) - v1.3.kmmacros (49.3 KB)
(uploaded in disabled state)

So, it turns out that even if a document is open, it can be tagged in MacOS. This makes me happy, and it can make our lives a little bit easier.

Sometimes when I am working with an open document or a batch of open documents - usually a PDF or Word or TextEdit document or documents - I want to quickly tag it/them for later quick retrieval via Spotlight. But to do this, I would typically leave the work I am doing in an open document, locate the document in Finder, and tag the item there, then go back to the open document. That's a pain. For multiple open documents, often from different file locations, it becomes maddeningly tedious, when all I want to do is quickly tag my open document or documents right when it occurs to me to do so, and then get right back to work.

This UPDATED macro leverages scripts by @ccstone and @Nige_S to retrieve the filepath(s) of almost any kind of open file(s)/document(s), then it prompts the user for comma-separated tags, then it tags the open document or all open documents in a given app, accordingly, without having to interact with Finder. I have tested this with Preview, Word, Excel, Powerpoint, and TextEdit. It works even with unsaved, in-progress Office documents (although the documents must have been saved at least once so that they have a file location). It should work with most any item that has a file location and can be tagged in MacOS.

One aspect of the UPDATED macro that may seem tedious is that for file types other than Preview, TextEdit, Word, Powerpoint, and Excel, and probably other apps, if you choose to tag all your open documents (in a given app), the macro must bring each open document to the front briefly in order to get the filepath using @ccstone's most useful script. I personally can live with this, because the overall time save is worth it. (See further discussion below regarding scripting solutions for different apps.)

This UPDATED macro prompts the user to ADD or REPLACE tags. The macro will throw up a self-dismissing dialog briefly showing you the tags set to the file. Obviously, that element can be omitted if you don't care about that.

What I love about KM is that it so powerfully engages the most laudable utility of the computer, which is to enable human users to quickly and intuitively organize and retrieve information. I offer this macro in that spirit!

Cheers!

1 Like

AppleScript isn't available in every app, and even when it is there's no standard way to ask an app for the path to a document -- eg TextEdit and Preview return the document name in the path, but for Word you have to ask for path and name then concatenate them.

So while you could write a script that would do the appropriate thing for each of the apps you want to use it for, falling back on "System Events" and window-flashing if the app isn't scriptable, doing similar for distribution would be a nightmare. Kudos to @ccstone for finding a method that's so generally applicable!

1 Like

Agree. Window-flashing in this context may be tedious, but what it's replacing is the user having to manually, and even more tediously, cycle through each document to repeat a "reveal in Finder" action, tag document, etc.

Sorry @BKammer, I didn't explain myself well. For those apps with an AppleScript dictionary you could avoid the window-flashing, but there's no consistency in how an app return the path of an open document so you have to keep track yourself. For example:

tell application "System Events"
	set activeApp to first process whose frontmost is true
	set activeAppName to name of activeApp
end tell

if activeAppName = "TextEdit" then
	tell application "TextEdit" to set docList to path of every document
	repeat with eachItem in docList
		set contents of eachItem to (contents of eachItem) as POSIX file as alias
	end repeat
else if activeAppName is "Microsoft Word" then
	tell application "Microsoft Word"
		set docList to every document
		repeat with eachItem in docList
			set contents of eachItem to (path of contents of eachItem & ":" & name of contents of eachItem) as alias
		end repeat
	end tell
else
	-- do ccstone's GUI method
end if

-- do stuff with labels/tags to the files in docList

Not so bad if you've only a couple of apps that you know about, but making the KM macro as widely usable as @ccstone managed would be a nightmare!

2 Likes

Wow, I reckon this would work in most of my use case scenarios -- thank you! I'll try integrating this into the macro.

I can't get this to work, unfortunately. Seems like Applescript throws an error when it tries to get the path of "every" document. If it's "front document", it works ... for the front document. I'm probably screwing it up.

@BKammer, you'll need to post (or DM me) the script/macro, say what application was frontmost, what version of macOS your running, etc, etc. Otherwise all I can say is "It works for me..."

You are right, sorry. Running 12.3.1

So, to test this, I isolated the TextEdit script and integrated it into a test macro:
image

I opened a few TE documents and ran the macro.

Gets this error:

image

Here's the macro:

OPEN DOCS - TAG copy copy.kmmacros (22.9 KB)

My bad -- I should have looked at how the AppleScript step integrated with KM in the original macro. That would be a lot easier if I actually owned KM :wink:

  1. An AppleScript list is in the form
{item1, item2,...}

...while a KM list (I believe) is

item1
item2
...

Then, later, we're passing alias references to KM when it wants file paths -- I see from the visible comments section that @ccstone's script is returning one POSIX path at a time.

Both are solvable in my script. You could either generate the list as POSIX paths then change the "list format" at the end, or generate as aliases and then convert to POSIX and change "list format" as a final step before setting the KM variable. Since the latter is the least work for me try putting this just above the "tell application "Keyboard Maestro Engine"" line:

repeat with eachItem in docList
	set contents of eachItem to POSIX path of eachItem
end repeat

set {oldTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, return}
set docList to docList as text
set AppleScript's text item delimiters to oldTIDs

And I'll see if I can find something to test on, rather than relying on your good grace and problem reports...

Bewildering...

Nevertheless, thank you!

Your solution works for TextEdit and Preview, but not for Word. I modified the script as follows:

image

For Word documents I get this error, whose complete message I can't access:

image

I have updated the macro (see main post) to incorporate @Nige_S's scripting suggestions. This eliminates flashing each window in Preview or TextEdit to the front to get the frontmost document filepath using @ccstone's script. Probably this will work for other native Mac apps, and the macro can be edited accordingly to incorporate those apps. Otherwise, @ccstone's script works fine for all other apps I have tried; it just has to flash through the windows to gather the filepaths.

Because you missed out the "special case" stuff for Word, posted earlier. For completeness:

else if activeAppName is "Microsoft Word" then
	tell application "Microsoft Word"
		set docList to every document
		repeat with eachItem in docList
			set contents of eachItem to (path of contents of eachItem & ":" & name of contents of eachItem) as alias
		end repeat
	end tell

But I'm not sure if this is the best way to do this...

If any of the KM gurus have read this far -- when you've a choice of where to do your conditional branching, which is the "KM Way"? Is it better to do the branching in the AppleScript step, as we are here, or use KM's conditional actions with separate subscripts for each?

You are right. When I added back in the missing script lines for Word, it still wouldn't work, but I was able to remedy it by swapping out colons for backslashes in the path format in KM post-processing. I also had to strip out "Macintosh HD" from the returned path(s). This led me to tinker with Excel and Powerpoint. I was able to get Excel working. It returns a POSIX path with backslashes. Could not get Powerpoint to work.

Here is the script that is doing the work for open documents in Preview, TextEdit, Word, and Excel, based on your suggestions:

image

If the script fails to run because the frontmost app isn't one of those four apps, then it defaults to @ccstone's script, which needs to have each individual open doc at the front briefly to gather its path.

Thanks for your continued attention to this. The macro is getting better and faster.

Yep -- in true Microsoft style each of Word, Excel, and Powerpoint do things differently. I've been playing around with using lists of apps, members of each list being processed the same way (like Preview and TextEdit are in your script), to make maintenance easier -- but including the Office apps leads to so many exceptions it's easier to do an "if" per app!

If you want to include PowerPoint you need to use "every presentation", and you can use "full name" to get the full POSIX path (including file name). If you want to save your script some work (since we're working in POSIX paths) you can also change Word to use "posix full name" to get the full, name included, POSIX path, and Excel to "full name" for the same.

Three apps, two different ways to get the open documents, two different ways to get the full path of a document -- and they didn't even get the matching ways into the same apps!

1 Like

Fantastic. I have updated the script as you suggested and it works brilliantly. Powerpoint is now one of five apps that work with the script, and the Word script has been altered as you suggested.

Here is the most recent, updated version of the macro, also in main post above:

TAG OPEN DOCUMENT(S) - v1.3.kmmacros (49.3 KB)