MacOS – Is it possible for an AppleScript .scpt file to retain a custom icon, even after edits have been made to the code

applescriptcustomizationiconmacosscript

The file:

I created an AppleScript .scpt file in Script Debugger.app.

Here is how I assigned a custom icon to this .scpt file:

  • I downloaded a unique icon (in the "512px PNG" format) from IconArchive.com.

  • I opened the .png file with Preview.app. In Preview, I clicked EditCopy, to place this image on my clipboard.

  • I opened the .scpt file's Get Info window in Finder. I left-clicked on the default icon, found in the top-left corner of the Get Info window. A blue outline then appeared around the default icon, reflecting that the icon was selected.

  • Finally, I pasted the custom icon over the default icon via the keyboard shortcut, ⌘ command + V. The custom icon was set immediately. I closed out of the Get Info window.


The bug:

When I open the .scpt file in Script Debugger, to edit the code, and then resave the .scpt file, the custom icon disappears.

On save, the following icon immediately takes the place of the custom icon:

(This is OS X's default icon for .scpt files.)

Of course, having to go through the process of setting the custom icon every time that I save (i.e., edit) the file is an inconvenience.

But, there is also a second, corollary bug: Each time that I re-add the custom icon in the Get Info window, the file size of the .scpt file cumulatively increases. In other words, when Script Debugger deletes the custom file icon, the icon's file size is still included, somehow, as part of the overall .scpt file size.

Case in point: the file size of the .scpt file in question is 12.6 MB, at the moment. The file should not be larger than .5 MB.


The question:

I understand how to set a custom file icon to an AppleScript .app file, so that this custom icon remains in place after editing, but I am curious if the same can be done for an .scpt file.

Is there a way for my custom script icon to remain in place, even after the .scpt file has been modified in Script Debugger?

This is an .scpt file that is launched via the FastScripts.app menu bar drop-down menu. (The .scpt file is located in /Users/Me/Library/Scripts.) The FastScripts drop-down menu actually displays the file icons of the scripts, which is a nice feature. This is the reason why I want to set a custom icon to the .scpt file (i.e., so that I can observe an apposite icon in the FastScripts shortcut menu).

No, it is not a big deal to simply convert the AppleScript .scpt files that I want to have a custom file icon to AppleScript .app files. I ask this question just to see if there is something that I am missing or overlooking here.


What about Script Editor?

It appears that this bug is unique to Script Debugger.

When I follow the same steps in OS X's native AppleScript editing program, Script Editor.app, the .scpt file icon remains in tact, upon save. However, I could've sworn that I have, in fact, experienced this issue in Script Editor, in the past.

For example, I recall that, once, Script Editor refused to save a .scpt file that I had edited; a vague error dialog was presented on Save. To successfully save the file, I had to either delete the custom icon from Finder's Get Info window, or copy the code text and paste it into a new .scpt file (which, of course, would necessarily possess the default .scpt file icon).

But, at this time, I can no longer reproduce the error in Script Editor.

At any rate, I try to not use Script Editor to edit my AppleScripts anymore. This is because Script Editor is laggy, potentially crashes when using a third-party script library, and can be temperamental when it comes to opening and saving files.

In my experience, so far, Script Debugger has none of these issues.

Of course, Script Debugger does have at least one issue, though (i.e., the issue detailed in this post).


OS X El Capitan, version 10.11.6.


Best Answer

Generally speaking, when a User assigns a custom icon to a file by copying and pasting an image file into the icon, in the top left corner, on the file's Get Info sheet, the image file is stored as a com.apple.ResourceFork extended attribute of the file it's applied to, and can be seen in Terminal using ls -l@ filename.ext to show the file has extended attributes. To manipulate the extended attributes, use the xattr utility in Terminal. Note that the use of the term image file in this contact is any valid source copied on the Clipboard to then be pasted in the Get Info sheet.

Having to reapply the icon file after having saved the .scpt file in Script Debugger causes the com.apple.ResourceFork extended attribute to continue to grow in size, while possibly loosing access to the accumulated icon files, can't say for sure as I've not done enough testing. Unfortunately, while Script Editor keeps the custom icon file, nonetheless it appears to grow the size of the com.apple.ResourceFork extended attribute as well.

To reduce the size of file by removing specifically the com.apple.ResourceFork extended attributes, use the following command syntax in Terminal:

xattr -d com.apple.ResourceFork filename.ext

Then reapply the custom icon to the file.

Have a look at the man page for xattr in Terminal by typing, xattr and then right-click on it selecting Open man Page from the context-menu.

The issue with Script Debugger resetting to the default icon will probably have to be taken up with the Developer, or use the workaround suggested in wch1zpink's answer.

Since the com.apple.ResourceFork extended attribute grows regardless of which of the apps you use, Script Editor or Script Debugger, this is an issue that Apple need to address.

I know you're using OS X El Capitan 10.11.6, however I tested this under macOS Sierra 10.12.5 and the behavior apparently being the same, it probably doesn't matter that I tested this in a later OS release. I was using Script Debugger 6.0.4.

Because of the repetitiveness of what you're doing, a scripted solution is in order here to reduce the effort necessary to maintain both a small file size, inclusive of it extended attributes, and the custom icon.


Update:

Having gone down a similar road, under OS X 10.8.5, with programmatically setting a file's icon, and having tested almost every solution presented under How can I change a file or folder icon using the Terminal, I chose to use setfileicon from this answer, as it worded the best for my needs at the time.

The following AppleScript code is example code that can programmatically delete the com.apple.ResourceFork extended attribute of the target file to reduce it accumulative size and reset the target file's icon. It is written around the use of the workaround suggested in wch1zpink's answer, referencing locking the file to keep the icon intact during a save under Script Debugger.

The main purpose of this example code is to show how to delete the com.apple.ResourceFork extended attribute of the target file and reset its custom icon programmatically. I've thrown in the code to unlock/lock the target file if you choose to use that method of keeping the icon intact between saves, if not it can be removed. I guess it just depends on how often to want to reset the size of the target file's com.apple.ResourceFork extended attribute.

tell current application

    set theTargetFilename to "filename.scpt" as string
    set theHomeFolderPath to (path to home folder) as string
    set theScriptsFolder to (path to scripts folder) as string
    set theTargetFilePathname to theScriptsFolder & theTargetFilename as alias
    set theTargetIcon to quoted form of (POSIX path of (theHomeFolderPath & "bin:icon.icns") as string)
    set theTargetExecutable to quoted form of (POSIX path of (theHomeFolderPath & "bin:setfileicon") as string)

    tell application "Finder" to set locked of theTargetFilePathname to false
    do shell script "xattr -d com.apple.ResourceFork " & quoted form of (POSIX path of theTargetFilePathname) & "; exit 0"
    do shell script theTargetExecutable & " " & theTargetIcon & " " & quoted form of (POSIX path of theTargetFilePathname)
    tell application "Finder" to set locked of theTargetFilePathname to true

end tell

Notes:

For the purpose of this example code, I've placed the setfileicon command line utility and target icon.icns files in the bin folder within the root of my Home folder. The icon.icns file is the .icns file of the one linked in your question. You could use the PNG file, however I believe the .icns file produces a better image.

The script could be more hard coded and not as verbose, however I coded it this way for a few reasons of which I'm not going to get into the details of unless you need it explained. Feel free to utilize the example code to implement a working solution as needed/wanted in your environment.

This was tested this under macOS Sierra 10.12.5, however it should also work under OS X El Capitan 10.11.6.