Is there any way to make Spotlight index .applescript files?

Well, it’s working partially.

To test I’d just been going to my main script folder and running a spotlight search in-folder for something widely used, like “set,” or “text item.”

I was getting no results from .applescript files. Then after the last Script Debugger update, and adding and removing my scripts folder in the Spotlight “privacy” pane, the same search in the same folder returned lots of results.

But yesterday, I had a library open, and a script that called a function in the library, and I needed to add a parameter to the library function. So I had to find all scripts calling it to update the calls.

So I thought “great! Spotlight is working again!”

I did the spotlight search for the function name inside my script folder… and it turned up some scripts, but I noticed it did NOT turn up the script I was working on! Which obviously had the call, and had for quite some time. So I tried several more searches for terms that I knew existed in several scripts, and it was hit or miss. I am definitely getting some hits for full text search of .applescript files, but can also find scripts that definitely should be turning up - that contain the searched term and are located in the searched directory - that do not turn up.

No idea if that can have anything to do with the plugin, or if it’s an Apple flaw in Spotlight. I’ll try forcing it to reindex everything and see if that helps… but adding and removing the file from the “Privacy” pane definitely forced at least a partial re-indexing, so that doesn’t seem likely.

I don’t have any prior versions of Script Debugger installed, just the latest.

Another developer told me that he uses Sublime Text to do full text search of his Applescripts, so I’ll give that a shot.

Thanks,

tspoon.

I am accustomed to store my scripts as .applescript files stored in subfolders of a dedicated folder so, when I need to search for a string in them I use the free Easyfind which return very quickly the list of files containing the searched string.
The only feature which is missing - from my point of view - is the fact that we can’t copy the returned list. When I copy it, the clipboard contain icons but say that it doesn’t contain text datas.

I use GUI scripting to extract the useful infos:

set targetFile to (path to desktop as text) & "filesFound.txt"
tell application "System Events" to tell process "EasyFind"
	set frontmost to true
	tell window 1
		--class of UI elements --> {button, button, button, scroll area, button, checkbox, checkbox, checkbox, radio group, radio group, checkbox, checkbox, static text, static text, static text, static text, text field, menu button, static text, list, toolbar, static text}
		select row 1 of table 1 of scroll area 1 # reveal the list of path components
		
		set folderName to name of menu button 1 --> "des scripts"
		--class of UI elements
		set theItems to value of attribute "AXChildren" of list 1
		set pathComponents to {}
		repeat with i from 1 to 1000 # a fake value
			set aComponent to value of item i of theItems
			set end of pathComponents to aComponent
			if aComponent = folderName then exit repeat
		end repeat
		set begOfPath to "/Users/" & my recolle(pathComponents, "/")
		
		# Here, begOfPath is:  "/Users/my user name/Documents/mon bureau/des scripts"
		
		my writeto(targetFile, begOfPath & linefeed, «class utf8», false) # create the report file
		
		tell scroll area 1
			--class of UI elements --> {table, scroll bar}
			tell table 1
				--class of UI elements --> {row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, row, column, column, column, column, column, column, group}
				set nbr to count rows
				set theInfos to {}
				repeat with i from 1 to nbr
					tell row i
						--class of UI elements --> {static text, static text, static text, text field, text field, static text}
						set fName to value of static text 1
						if fName ends with ".applescript" then my writeto(targetFile, fName & tab & value of static text -1 & linefeed, «class utf8», true)
					end tell
				end repeat
			end tell
		end tell
		
	end tell
end tell

#=====

on recolle(l, d)
	local oTIDs, t
	set {oTIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, d}
	set t to l as text
	set AppleScript's text item delimiters to oTIDs
	return t
end recolle

#=====
(*
Handler borrowed to Regulus6633 - http://macscripter.net/viewtopic.php?id=36861
*)
on writeto(targetFile, theData, dataType, apendData)
	-- targetFile is the path to the file you want to write
	-- theData is the data you want in the file.
	-- dataType is the data type of theData and it can be text, list, record etc.
	-- apendData is true to append theData to the end of the current contents of the file or false to overwrite it
	try
		set targetFile to targetFile as «class furl»
		set openFile to open for access targetFile with write permission
		if not apendData then set eof of openFile to 0
		write theData to openFile starting at eof as dataType
		close access openFile
		return true
	on error
		try
			close access file targetFile
		end try
		return false
	end try
end writeto

#=====

It’s slow but it return a file containing the list of the filenames and the partial path of these files in the target folder whose path is stored ain the first line of the document.

Maybe it may help others.

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) mercredi 13 novembre 2019 19:29:06

Thanks Yvan, I’ll give Easy Find a try.

Usually, I don’t need a log of what’s found.

If you do need a log, you might try my Applescript Find/Replace script here:

https://www.macscripter.net/viewtopic.php?id=47109

It is also slow, but it generates a nice spreadsheet showing the text of the line(s) in which the searched term was found, as well as the file path to the file.

Note that Nigel said he encountered an issue with the “replace” functionality in .scpt files. In my testing it had worked, but I’ll investigate further when I have time.

The plug-in just passes on the whole contents of a document to Spotlight. It’s a black box from then on.

Oops, driving EasyFind with GUIscripting was a bad idea.

Below is a script doing more job in a hurry.

----------------------------------------------------------------
use AppleScript version "2.5"
use framework "Foundation"
use script "FileManagerLib" version "2.2.2"
use scripting additions
----------------------------------------------------------------
script o
	property theURLs : {}
	property thePaths : {}
end script

my germaine()

on germaine()
	set targetDir to (path to documents folder as text) & "mon bureau:des scripts:" # Edit to fit your needs
	set startTime to time of (current date)
	
	my listFolder:(POSIX path of targetDir)
	
	set targetFile to (path to desktop as text) & "applescripts.txt"
	my writeto(targetFile, my concatList:(o's thePaths) usingString:linefeed, «class utf8», false)
	set executeTime to (time of (current date)) - startTime --> 8
end germaine

on listFolder:posixPath
	set theKey to "localized" # Edit to fit your needs
	# You may also define a replacement string
	
	set o's theURLs to objects of posixPath result type urls array with searching subfolders without include folders and include invisible items
	if o's theURLs is {} then error "Le dossier “" & posixPath & "” est vide."
	
	set o's thePaths to {} # useful if we run the script several times in a row
	repeat with aURL in o's theURLs
		set itsPath to (aURL's valueForKey:"path") as text
		
		
		if itsPath ends with ".applescript" then
			set theName to (aURL's lastPathComponent()) as text
			
			set itsText to read ((POSIX file itsPath) as «class furl»)
			if itsText contains theKey then
				set end of o's thePaths to itsPath
				
				# you may trigger the handler remplace2 if you want to apply the replacement
				# and write the modified text.
				
				repeat with aLine in paragraphs of itsText
					if aLine contains theKey then set end of o's thePaths to (aLine as text)
				end repeat
			end if
		end if # itsPath ends with ".applescript"
	end repeat
end listFolder:

#=====

on concatList:theList usingString:d1
	set anArray to current application's NSArray's arrayWithArray:theList
	return (anArray's componentsJoinedByString:d1) as string
end concatList:usingString:

#=====

on remplace2(t, d1, d2)
	set aString to (current application's NSString's stringWithString:t)
	-- Case insensitively replace any instances of d1 by d2
	set aString to aString's stringByReplacingOccurrencesOfString:d1 withString:d2 options:(current application's NSCaseInsensitiveSearch) range:{0, aString's |length|()}
	return aString as string
end remplace2

#=====
(*
Handler borrowed to Regulus6633 - http://macscripter.net/viewtopic.php?id=36861
*)
on writeto(targetFile, theData, dataType, apendData)
	-- targetFile is the path to the file you want to write
	-- theData is the data you want in the file.
	-- dataType is the data type of theData and it can be text, list, record etc.
	-- apendData is true to append theData to the end of the current contents of the file or false to overwrite it
	try
		set targetFile to targetFile as «class furl»
		set openFile to open for access targetFile with write permission
		if not apendData then set eof of openFile to 0
		write theData to openFile starting at eof as dataType
		close access openFile
		return true
	on error
		try
			close access targetFile
		end try
		return false
	end try
end writeto

#=====

Yvan KOENIG running High Sierra 10.13.6 in French (VALLAURIS, France) jeudi 14 novembre 2019 12:00:08

It is just me or spotlight does not search into .scpt files?
I do see the /Applications/Script Debugger.app/Contents/Library/Spotlight/SDImporter.mdimporter
But it is not present into: /Users/ldicroce/Library/Spotlight/

Should I manually copy it?
If that is the case, should I then re-build the all spotlight database?

Thanks
L.

There’s no need to move it. But it can only index files saved from Script Debugger (and not run-only). It relies on an extra copy of the source being saved asa file resource.

I only use SD. And very rarely I use Run-Only option. Yet if I trigger the System “Spotlight search” and search for (as example) a handler name (=recoverFirstDataStampFromLog), I don’t get any match.
Also, if I use the “Open Quickly” from SB, also no match.

Is this done automatically by SD? and where are stored?
I am asking since many of the scripts are shared among my 2 computers, either via DropBox or loaded on my Desktop (having “Desktop and Documents Folders” synch among the computers via iCloud).

Is there anything else I need to set in the Spotlight System Preference panel, or in SD Preferences?
Thanks!

PS: If I save the script as BBedit file, “Spotlight search” correctly identify the Bbedit file, but not the .scpt file.
My interpretation is that a newly generarte Bbedit file is properly indexed, but not any .scpt files

It’s saved automatically as a file resource. Unfortunately such resources aren’t synced by iCloud. (The format pre-dates iCloud – in fact, it pre-dates OS X.)

If the facility is important to you, consider using .scptd files instead.

Thanks Shane, I will explore the use of .scptd
… But at least on the same Mac (like today since I am at home), I should be able to use Spotlight search, and that it is not the case … it also fails on the laptop. Unless I am missing something.

How can I check if the resource data you mentioned are correctly associated/link/part of the .scpt file?
Thanks again.

PS2: I could move this discussion to the https://forum.latenightsw.com if you think it is better.
But I think that are many SD users here that might also benefit from this. Let me know.

Update: using .scptd works perfectly when new files are generated on my desktop. Does this means that the importer is not working for .scpt files ?

One potential issue is the existence of importers from older versions of SD. Do you have any older versions of SD installed? if so, you could try zipping and deleting them, and then forcing a re-index.

As @Shane Stanley recommends, try to share the scripts between the two computers as a script bundle (that is, a script library). I currently do not have the opportunity to test myself, but it is quite possible that you will also need to remove the quarantine from the script library from an unknown to Apple developer.


set userScriptLibraries to alias ("" & (path to library folder from user domain) & "Script Libraries")
set userScriptLibrary to choose file of type "scptd" default location userScriptLibraries

set appPosixPath to POSIX path of userScriptLibrary
set quotedPath to quoted form of appPosixPath
do shell script "xattr -rd com.apple.quarantine " & quotedPath with administrator privileges

I remove the SD 7 the same day I installed the v8.
It is a pity not tone able to use such powerful tool.

Thanks R.
But the problem is with all scripts. Meaning that none of script is indexed, including the new generated ones. If I use “scptd” then it works.
If I make. anew text or PDF file (using the content the AS code), then it is indexes.

Delete also the folder Script Debugger 7 inside the Application Support folder.

Also gone since long time …
I guess I am the only one that does not get scpt files indexed … frustrating

I have both .applescript and .scpt files indexed. :frowning:
I have not any excluded disk in the Spotlight search preferences. Also, I have not folder /home/user/Library/Spotlight

I had another problem - when I first started SD 8. I needed to give it full control of the computer. There, in the security settings, there was already an entry from SD 7. To solve the problem, I uninstalled both SD 7 and SD 8, deleted the old entry from the security settings, installed SD 8 back. Only after that did I manage to give SD 8 full control of the computer. Before that, the SD 7 record apparently interfered.

Thanks.
I will try to uninstall/reinstall SD8. I do not have any traces go SD7. Maybe this will solve the problem.
Although, I still doubt it since scptd files are properly indexed, meaning the the importer in working as expected.
Indeed if I do in the terminal: mdimport -L
I do see in the list:
“/Applications/Script Debugger.app/Contents/Library/Spotlight/SDImporter.mdimporter”

Even more strange is the fact that this append on both my MacBook Pro 2021, and iMac 2019.

Thanks again!

L.

PS: can I ask you to provide me with the output of:
mdimport -t -d3 path/to_AS_generatedByScriptDebugger.scpt

Below is what I get:

mdimport -t -d3 /Users/ldicroce/Desktop/test.scpt
Imported ‘/Users/ldicroce/Desktop/test.scpt’ of type ‘com.apple.applescript.script’ with plugIn /Applications/Script Debugger.app/Contents/Library/Spotlight/SDImporter.mdimporter.
30 attributes returned
{
“:EA:_kMDItemUserTags” = (
);
“:EA:kMDItemLastUsedDate” = “2021-09-21 14:51:59 +0000”;
“:MD:DeviceId” = 16777223;
“:MD:kMDItemPath” = “/Users/ldicroce/Desktop/test.scpt”;
“:PR:kMDItemUserCreatedDate” = (
“2021-09-21 08:49:22 +0000”
);
“:PR:kMDItemUserCreatedUserHandle” = (
501
);
“_kMDItemContentChangeDate” = “2021-09-21 08:49:22 +0000”;
“_kMDItemCreationDate” = “2021-09-21 08:49:22 +0000”;
“_kMDItemCreatorCode” = 1634944066;
“_kMDItemDisplayNameWithExtensions” = {
“” = “test.scpt”;
};
“_kMDItemFileName” = “test.scpt”;
“_kMDItemFinderFlags” = 0;
“_kMDItemFinderLabel” = 0;
“_kMDItemFromImporter” = 1;
“_kMDItemIsExtensionHidden” = 0;
“_kMDItemIsFromImporter” = 1;
“_kMDItemOwnerGroupID” = 20;
“_kMDItemOwnerUserID” = 501;
“_kMDItemTypeCode” = 1869832563;
“com_apple_metadata_modtime” = “653906962.8787711”;
kMDItemContentCreationDate = “2021-09-21 08:49:22 +0000”;
kMDItemContentModificationDate = “2021-09-21 08:49:22 +0000”;
kMDItemContentType = “com.apple.applescript.script”;
kMDItemContentTypeTree = (
“com.apple.applescript.script”,
“public.data”,
“public.item”,
“public.script”,
“public.source-code”,
“public.plain-text”,
“public.text”,
“public.content”
);
kMDItemDateAdded = “2021-09-21 08:49:22 +0000”;
kMDItemDisplayName = {
“” = “test.scpt”;
};
kMDItemDocumentIdentifier = 24242;
kMDItemKind = {
“” = script;
Base = script;
ar = “\U0628\U0631\U0646\U0627\U0645\U062c \U0646\U0635\U064a”;
ca = Script;
cs = Skript;
da = Instruks;
de = Skript;
el = “\U03a3\U03ba\U03c1\U03b9\U03c0\U03c4”;
en = Script;
“en_AU” = Script;
“en_GB” = Script;
es = Script;
“es_419” = Script;
fi = Skripti;
fr = Script;
“fr_CA” = Script;
he = “\U05ea\U05e1\U05e8\U05d9\U05d8”;
hi = “\U0938\U094d\U0915\U094d\U0930\U093f\U092a\U094d\U091f”;
hr = Skripta;
hu = Szkript;
id = Skrip;
it = Script;
ja = “\U30b9\U30af\U30ea\U30d7\U30c8”;
ko = “\Uc2a4\Ud06c\Ub9bd\Ud2b8”;
ms = Skrip;
nl = Script;
no = Prosedyre;
pl = skrypt;
pt = Script;
“pt_PT” = Script;
ro = Script;
ru = “\U0421\U043a\U0440\U0438\U043f\U0442”;
sk = Skript;
sv = Skript;
th = “\U0e2a\U0e04\U0e23\U0e34\U0e1b\U0e15\U0e4c”;
tr = Betik;
uk = “\U0421\U043a\U0440\U0438\U043f\U0442”;
vi = “T\U1eadp l\U1ec7nh”;
“zh_CN” = “\U811a\U672c”;
“zh_HK” = “\U7a0b\U5f0f\U78bc”;
“zh_TW” = “\U5de5\U5e8f\U6307\U4ee4”;
};
kMDItemLogicalSize = 5283;
kMDItemPhysicalSize = 12288;
}

Have you checked to see if there’s a copy of the importer in /Library/Spotlight/ ?

Any other third-party importers?

There was EndNote importer
/Users/ldicroce/Library/Spotlight/EndNote.mdimporter
So I tried adding SDImporter into the Library, then restarting, didn’t worked.
The I deleted the all contents (leaving the folder empty), then restarting, also didn’t worked.
The I add only SDImporter, then restarting, same result.

When I make this set of files on my desktop:
TestBBedit.txt
Test.scpt
Test.applescript
TestAsBoundle.scptd

all containing the same simple code:

use AppleScript version "2.4" -- Yosemite (10.10) or later
runThisScriptLux()

on runThisScriptLux()
	beep
end runThisScriptLux

and I search for “runThisScriptLux” using Spotlight, I retrive all of then except the the scpt version (“Test.scpt”)

I wonder if:

  1. the indexing of scptd files uses a different tools than scpt? Since indexing scptd works without any problem without any delay …
  2. Should I try to copy the SDimporter into the:
    /System/Library/Spotlight rather than at user level?
    Thanks Shane for your help !