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?
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.
(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.