I'll try!
You're bang on with the "For Each". But I'd add that the Local__fileToMove
variable is what "holds" each item and lets you refer to it in the loop -- and in the case of Finder selections that's the path to the item. So if you selected 1.jpg
, 2.jpg
, and 3.jpg
on your Desktop, in loop 1 Local__fileToMove
would be /Users/bernsh/Desktop/1.jpg
, on loop 2 ``/Users/bernsh/Desktop/2.jpg`, etc.
Second box: An item's path is the complete reference to the item, starting at the "root" level of the file system and ending with the item's name -- you can see this if you right-click a file or folder in the Finder, hold down the Option key, select "Copy... as Pathname" and then paste into TextEdit or similar. And that's what we have in Local__fileToMove
so yes, to get the bits we want later we use the "Split Path" action -- note that the "Extension is:" value does not include the period! (Using the explicit %Variable%
form is good practice, for the reasons you state, and while it's more verbose I find it makes it easier to spot what is or isn't a variable.)
Third box: Yep. Also, i
is traditional for this sort of counter -- I've always assumed that's because it's used to iterate through an array, a series of numbers, or similar.
Fourth box: Only way I know to make the box expand is to make the window bigger! But what you can do is copy all the text and paste it into either a "Display Dialog" action or even into TextEdit etc, edit it there, and paste it back into the action.
Local__destinationFolder
is the path to the folder we chose in the first action of the macro, "Prompt for Folder". We're back to talking paths, as above, and we're joining bits of text together to make a full path to test.
Say you choose "Test Folder" on your Desktop as your destination, the file to move is picture.jpg
, your destination already has file of that name and this is our first loop so i = 1
. Putting each bit on its own line to make it clearer:
%Variable%Local__destinationFolder% /Users/berhsh/Desktop/Test Folder
/ /
%Variable%Local__basename% picture
%CalculateFormat%Local__i%-000% -001
. .
%Variable%Local__extension% jpg
...and because we are just joining together ("concatenating") those bits of text we get
/Users/berhsh/Desktop/Test Folder/picture-001.jpg
So yes, the order is significant!
Fifth box: Hopefully the above has explained that we add the /
and .
because the path we get from the prompt and the extension we get from "Split Path" don't include those characters, so we have to add them back in when we build the path.
%CalculateFormat%
is a tricksy step -- well spotted! You'd normally use it for things like "give me the result of 4 / 3
to one decimal place":
%CalculateFormat% 4 / 3 % .#%
...which returns 1.3
. And the "calculation" of any number is simply itself. So what we're doing here is "calculate Local__i
and format the answer with as many leading 0
s as are needed to make it three digits long, then prepend a -
". So when Local__i
is 1
we get -001
, when it's 11
we get -011
, and so on.
Sixth box: I think you're answering your own question here! The "While" loop keeps repeating until the condition is no longer met -- in this case, until there isn't already a file with the path we are creating. If there is a file the loop continues, 1
is added to Local__i
, and we're back to testing the new file path.
It's an inelegant, brute force, approach -- keep trying file names with an ever-increasing suffix until you find one that doesn't conflict.
Seventh (I think!) box: Another tricksy concept. On the first "While" test of every run of this macro, the variable Local__suffix
does not exist. Except it looks like we've already used it -- we tested our path with %Variable%Local__destinationFolder%/%Variable%Local__basename%%Variable%Local__suffix%.%Variable%Local__extension%
. WTF!
Some languages would throw an error at this point because we've asked for the value of Local__suffix
but there is no Local__suffix
at that point. KM is much more forgiving and returns an empty string instead. So on the first test, before we've set Local__suffix
to a value, we are checking for a file named "picture
and <an empty string>
and .
and jpg
" -- picture.jpg
. If that exists then we enter the "While" loop, increment Local__i
, and set Local__suffix
to -001
so the next test is for "picture
and -001
and .
and jpg
" -- picture-001.jpg
. And so on, until there is no file match and we can do the copy.
Do notice the difference between the two versions of the macro. In the first we try and move the file, and if that fails we start testing suffixes. In the second we test names until there's no clash then move the file.
You can certainly "hard-code" your destination folder so the macro always puts files in the same place. It's still better practice to use a variable though, setting the path at the beginning of the macro -- if you ever want to change the destination it's easier to edit that one field and let the variable do the work than it is to go through every action looking for the path you want to change.
Or you could go one step better and make your macro work with either a default or chosen destination! For example, give it two triggers -- maybe ⌃M and ⌃⌥M -- and start with (pseudocode):
if %TriggerValue% contains ⌥ then
set destinationFolder to "Prompt for Folder"
else
set destinationFolder to "/Users/bernsh/Desktop/Destination"
end if
...so that triggering the macro with ⌃M will use your default location while ⌃⌥M will let you choose.
And I've probably blathered enough. Hopefully that's explained a few bits, and not made things even worse!