Reveal multiple files in Finder

The Keyboard Maestro Action Reveal a File will show and select a single file in Finder if Keyboard Maestro has its path.

But it cannot reveal and select multiple files in Finder.

I have managed to make a Keyboard Maestro Macro using some AppleScript to reveal and highlight say, three files in Finder if I pass their paths to the AppleScript. But I have not been able to make this work with passing any number of files to the AppleScript. For example, if I have a Keyboard Maestro Macro that matches a few files in a folder I can get Keyboard Maestro to generate a list of these files and their paths but I cannot work out a way to pass this list to AppleScript...

In other words, I want to be able to generate a list of files (they are all in the same folder) in Keyboard Maestro and pass this list as a single Variable to AppleScript so I can reveal and highlight them all in the Finder. Any help appreciated!

In schematic form something like this:

And this is as far as I have got, with a Macro that successfully reveals three files:

Reveal Multiple Files in Finder 1.00.kmmacros (4.8 KB)

Click to Show Image of Macro

set kmInst to system attribute "KMINSTANCE"
tell application "Keyboard Maestro Engine"
  set Path1 to getvariable "LOCAL__Path1" instance kmInst
  set Path2 to getvariable "LOCAL__Path2" instance kmInst
  set Path3 to getvariable "LOCAL__Path3" instance kmInst
end tell

set MultipleFiles to {POSIX file Path1, POSIX file Path2, POSIX file Path3}

tell application "Finder" to reveal MultipleFiles

tell application "Finder"
  activate
end tell

One option would be using Javascript For Automation. If you have a JSON formatted array stored in a variable:

You can feed that into an Execute a JavaScript For Automation action. Let me know if you have any questions.

Download Macro(s): Reveal Finder file(s).kmmacros (4.2 KB)

Macro-Image

Macro-Notes
  • Macros are always disabled when imported into the Keyboard Maestro Editor.
    • The user must ensure the macro is enabled.
    • The user must also ensure the macro's parent macro-group is enabled.
System Information
  • macOS 14.3.1
  • Keyboard Maestro v11.0.2
Expand disclosure triangle to see "javascript" source
return (() => {
    "use strict";

    // Copyright (c) 2023 Gabriel Scalise
    // Twitter - @unlocked2412

    // jxaContext :: IO ()
    const jxaContext = () => {
        // main :: IO ()
        const main = () => {
            // KEYBOARD MAESTRO VARIABLES
            const
                fps = JSON.parse(
                    kmvar.localJSONPaths
                );

            // MAIN LOGIC
            const
                appFI = Application("Finder");

            return appFI.reveal(
                fps.map(x => Path(
                    filePath(x)
                ))
            )
        };

        // GENERIC FUNCTIONS --------------------------------------------
        // https://github.com/RobTrew/prelude-jxa
        // filePath :: String -> FilePath
        const filePath = s =>
            // The given file path with any tilde expanded
            // to the full user directory path.
            ObjC.unwrap(
                $(s).stringByStandardizingPath
            );

        // MAIN --
        return main();
    };

    return jxaContext();
})();
2 Likes

Hello Aurio (@Zabobon):wave:

In most cases KM Variables are just plaintext.

AppleScript treats lists as record where every item is quoted, every quoted item is is separated by a comma and the whole thing is then surrounded by curly braces.

You’ll need to convert every list item to exact this kind of thing before putting it into AppleScript…

I hope this helps

Greetings from Germany

Tobias

Great! This works really well and I can easily convert the list of file paths into the form needed. Thank you so much.

2 Likes

Thanks for replying. Yes, I tried that. But I just couldn't get anything in a form that AppleScript could use as a list of files to reveal. It worked great with a single file - just not with a list. I'm still sure there must be a way in AppleScript...

You are right - there is a way but I think it kind of depends on how you’ve set up your folders … this is kind of quirky UI Scripting in the Finder that is too much for my tired brain :brain:

Will look into this tomorrow.. maybe I can help you with that :thinking:

  • but I make no promises

I now have to go to sleep :sleeping_bed: 23 hours awake with nearly 20 of them in front of my Mac is quite enough.

Greetings from Germany

Tobias

:rofl: :rofl:

FWIW this kind of thing seems to work here (tho I would personally go for some variant of the JS approach shown by @unlocked2412)

Paths selected in Finder through AppleScript.kmmacros (3.0 KB)

seems to work with

	tell application "Finder"
		reveal xs
	end tell

as well ...

Expand disclosure triangle to view AppleScript source
use framework "Foundation"
use scripting additions


on run
	set kmInst to system attribute "KMINSTANCE"
	tell application "Keyboard Maestro Engine"
		set pathLines to paragraphs of ¬
			(getvariable "local_Paths" instance (system attribute "KMINSTANCE"))
	end tell
	
	set xs to {}
	tell current application
		repeat with fp in pathLines
			set end of xs to ¬
				(my unwrap(my wrap(fp)'s stringByStandardizingPath)) as POSIX file
		end repeat
	end tell
	
	tell application "Finder"
		set selection to xs
	end tell
end run

------------------------- GENERIC ------------------------

-- wrap :: AS value -> NSObject
on wrap(v)
	set ca to current application
	ca's (NSArray's arrayWithObject:v)'s objectAtIndex:0
end wrap

-- unwrap :: NSObject -> AS value
on unwrap(objCValue)
	if objCValue is missing value then
		return missing value
	else
		set ca to current application
		return item 1 of ((ca's NSArray's arrayWithObject:objCValue) as list)
	end if
end unwrap
2 Likes

Thank you so much. This looks really good. In cases like this, It would be good to be able to mark multiple replies as the "solution" on the Forum... :grinning:

1 Like

At this stage (Keyboard Maestro version 11) its much easier to read KM variables through JavaScript actions than through AppleScript.

(Foundation class methods are more easily accessible from JS too)

( Also, this case is really a more natural fit for a .map than for a loop + mutation pattern )

2 Likes

Hello Aurio (@Zabobon):wave:

I’ve searched my stuff back and forth for a solution or something that I could help you with getting one

This Snippet is what I’ve found (originally posted by Ray Barber on MacScripter - clicking on these words brings you to the original post from 2005:


property thePath : "Macintosh HD:AppleScripts:"

tell application "Finder"
	activate
	select {¬
		alias (thePath & "1.pdf"), ¬
		alias (thePath & "2.pdf"), ¬
		alias (thePath & "3.pdf") ¬
			}
	open selection
end tell

Maybe this could work today as well … this is not tested … since you want it to have a dynamic length of the list - this is what it needs to look like (without the open selection of course ) - you will have to generate this kind of code using AppleScript with the quoted form syntax and compile into a file or build something like a routine into your Script that maybe builds a dynamically changing Script Object which you can run afterwards … but that is not a simple task …

Maybe this is the reason why I haven’t done that by myself until today :thinking: - I wanted to do that but I didn’t…

Three things to mention:

  • I am not sure if this code would work today (can not test until Friday because I am not at home)

  • Ray Barber posted another snippet in the same post that maybe gives you another way of using this kind of code

  • it only works in one folder but maybe - with additional love put into it and combination with the other snippet I mentioned it could be adapted to use with as many folders you like - but there is one caveat if you happen to have folders configured in list view mode using that one setting that shows the little triangle on the left side of Subfolders be sure that they are not revealing their contents. In this case you maybe will have to deal with the indexes of the rows in the window Layout of the Finder

I hope this information is clear and helpful

Greetings from Germany

Tobias

1 Like

Thank you very much for this. I will see where it leads!

For the moment I have two solutions provided in the posts above that I can make into Keyboard Maestro Subroutines to be called when I need to reveal several files in Finder.