Best way to make "Undo Last Finder Move Macro" macro?

I have a set of simple macros to move files in the Finder. Attached is one example. I'm looking for a way to undo a macro like this if necessary. Since the files I'm moving are almost always from my Desktop, simply moving files back to the Desktop would suffice.

This is simple enough when only working with one file—I can simply use the "SelectedFile" variable to move back to the desktop—but if I move multiple files at once, I'm stumped. Is that undoable?

What you would need to do is remember all the file paths.

Something like this:

  • Set Variable AllSelectedFiles to “”
  • For Each
    • Move File
    • Set Variable AllSelectedFiles to “%AllSelectedFiles%%SelectedFile%%Return%”

And then in your Undo Macro:

  • For Each Variable SelectedFile in Lines of Variable AllSelectedFiles
    • Move File

Hey Jack,

Most users do not realize that undo is one complicated beast. Developers routinely pull their hair out when dealing with undo routines.

The answer to your question is not with KM — not unless your write your own undo macro.

On the other hand if you use AppleScript to do the move the Finder will keep track and let you use Cmd-Z to undo the move.

--------------------------------------------------------
# Simple Move Files Script (undoable in the Finder)
--------------------------------------------------------
set moveDest to alias "Ryoko:Users:chris:test_directory:move_dest:"
tell application "Finder"
   set fSel to selection as alias list
   if fSel ≠ {} then
      set moveList to move fSel to moveDest
   end if
end tell
--------------------------------------------------------

If you want more persistence than the Finder's undo stack then you have to roll-your-own undo routine.

--------------------------------------------------------
# Move Files and Write Undo File
--------------------------------------------------------
set moveDest to alias "Ryoko:Users:chris:test_directory:move_dest:"
set undoFile to (path to temporary items folder from user domain as text) & "moveFilesUndo.dat"
tell application "Finder"
   set fSel to selection as alias list
   set moveFilesParent to (parent of (item 1 of fSel)) as alias
   if fSel ≠ {} then
      set moveList to move fSel to moveDest
      if class of moveList is not list then set moveList to {moveList}
      repeat with i in moveList
         set (contents of i) to (contents of i) as alias
      end repeat
   end if
end tell

set beginning of moveList to moveFilesParent
writeFile(moveList, undoFile, 0, list)

--------------------------------------------------------
on writeFile(srcData, targetFile, startPosition, dataType)
   try
      set fileRef to open for access targetFile with write permission
      if startPosition = 0 then
         set eof of fileRef to 0
      end if
      write srcData to fileRef as dataType starting at startPosition
      close access fileRef
   on error errMsg number errNum
      try
         close access fileRef
      end try
      error "Error in handler: writeFile()" & return & return & errMsg
   end try
end writeFile
--------------------------------------------------------

--------------------------------------------------------
# Restore Files
--------------------------------------------------------
set restoreList to read file undoFile as list
set restoreParent to item 1 of restoreList
set restoreList to rest of restoreList
tell application "Finder"
   move restoreList to restoreParent
end tell
--------------------------------------------------------

Note that if I was doing this for real I'd add stuff to the undo script to verify the files and the file destination still existed. I'd also probably put an "Are you sure you want to undo the last file move?" dialog in it.

You can do this with KM instead of AppleScript by keeping track of all of the file paths and creating a reverse-move (undo) macro, but I'll leave that as an exercise for the reader.

--
Best Regards,
Chris

Thanks, @peternlewis! That’s a great solution.

@ccstone, great tip about letting the Finder handle the undoing. Thanks.

(With Finder Undo Abilities) This AppleScript works well for moving single or multiple selected source files and/or directories to a destination directory on the same volume:

tell application "Finder"
	move selection to folder POSIX file "/Users/username/Desktop/DT PICS/"
end tell

When moving to a different destination volume you also need to delete the original selected source file(s) or directory(s) so add AppleScript command line "delete selection":

tell application "Finder"
	move selection to folder POSIX file "/Volumes/VolName/FolderA/FolderB/FolderC/"
	delete selection
end tell

Where:
Volumes = keep as is, do not change.
VolName = name of the drive your destination directory resides.
/FolderA/FolderB/FolderC/ = example names of your nested directories.
FolderC = example name of your destination directory.