I would like to be able to quickly invoke Spotlight to search among the contents of a specific folder. Would it be easy for any of you to create an AppleScript that will:
Open a window with an input field for search terms and two buttons - Cancel and Search.
Upon click of “Search”, will instruct Spotlight to search using the terms but with this restriction: -onlyin “/Users/USER/Library/Application Support/VoodooPad/Spotlight Index/”
I plan to assign this script to a hotkey so I can easily execute searches.
Thank you!
Erik
Model: PowerBook G4
AppleScript: 2.1.1
Browser: Firefox 2.0.0.3
Operating System: Mac OS X (10.4)
something like this, but how do you want the search results to be displayed?
display dialog "Enter search string" default answer "" buttons {"Cancel", "Search"} default button 2
set {text returned:t, button returned:b} to result
if b is "Search" then
set d to quoted form of (POSIX path of ((path to home folder as Unicode text) & "Library:Application Support:VoodooPad:Spotlight Index:"))
end if
set found to paragraphs of (do shell script "mdfind -onlyin " & d & space & quoted form of t)
Thank you Stefan. I suppose that ideally the results would be displayed in a Spotlight window so I can just click on the appropriate result to open the appropriate page. Would that be hard to do?
Thank you,
Erik
Hmmm. Would it be difficult to have the script display the resulting files (and only the resulting files) in a single Finder window? Then perhaps I could just double-click on the one I want to open.
display dialog "Enter search string" default answer "" buttons {"Cancel", "Search"} default button 2
set {text returned:t, button returned:b} to result
if b is "Search" then
set d to quoted form of (POSIX path of ((path to home folder as Unicode text) & "Library:Application Support:VoodooPad:Spotlight Index:"))
end if
set found to paragraphs of (do shell script "mdfind -onlyin " & d & space & quoted form of t)
set nameList to {}
set {TID, text item delimiters} to {text item delimiters, "/"}
repeat with i in found
set end of nameList to last text item of contents of i
end repeat
set text item delimiters to TID
set FilesToOpen to choose from list nameList with multiple selections allowed
if result is false then return
set FilesToOpenList to {}
repeat with i in FilesToOpen
repeat with j from 1 to (count nameList)
if contents of i is item j of nameList then
set end of FilesToOpenList to item j of found
exit repeat
end if
end repeat
end repeat
repeat with i in FilesToOpenList
set o to POSIX file i
tell application "Finder" to open o
end repeat
Well here is what I came up with. simple, but it works
set {text returned:t, button returned:b} to (display dialog "Enter search string" default answer "" buttons {"Cancel", "Search"} default button 2)
set d to quoted form of (POSIX path of ((path to home folder as Unicode text) & "Library:Application Support:VoodooPad:Spotlight Index:"))
try
tell application "Finder" to open (item 1 of (choose from list (paragraphs of (do shell script "mdfind -onlyin " & d & space & quoted form of t))) as POSIX file)
end try
Of course in the mean time Mr. S came up with a more eloquent and robust example.
I noticed that both does last script, throw up a empty result dialog if no results are found.
Hope you do not mind …
mad an edit, so it will ask’s you if you want to search again if no results are found
set rezult to ""
global rezult
my find_it()
on find_it()
set {text returned:t, button returned:b} to (display dialog "Enter search string" default answer "" buttons {"Cancel", "Search"} default button 2)
set d to quoted form of (POSIX path of ((path to home folder as Unicode text) & "Library:Application Support:VoodooPad:Spotlight Index:"))
try
tell application "Finder" to set rezult to (do shell script "mdfind -onlyin " & d & space & quoted form of t)
end try
if rezult is not "" then
tell application "Finder" to open (item 1 of (choose from list (paragraphs of rezult)) as POSIX file)
else
display dialog " No Items found " buttons {"Cancel", "Search Again"} default button 2
if the button returned of the result is "Search Again" then
my find_it()
end if
end if
end find_it
Stefan’s script currently seems the best for me because it just displays the filename without the path. However, each filename ends in “.vpspotlight” and the redundancy and length of that obscures the results. Is there any way to eliminate the filename extension?
One other question: how are the results sorted? By some sort of % match? If I wanted to (although I’m not sure if I do), could I change something so the sorting is alphabetical?
There is no sorting, the order of mdfind is the “order of appearance”
A sorting routine is possible also to strip the name extension,
but it rather slows down the script.
set t to text returned of (display dialog "Enter search string" default answer "" buttons {"Cancel", "Search"} default button 2)
set d to quoted form of (POSIX path of ((path to home folder as Unicode text) & "Library:Application Support:VoodooPad:Spotlight Index:"))
set found to paragraphs of (do shell script "mdfind -onlyin " & d & space & quoted form of t)
if found is {""} then display dialog "No matches found" buttons {"Cancel"} default button 1
set nameList to {}
repeat with i in found
set {name:Nm, name extension:Ex} to info for POSIX file i as alias
if Ex is missing value then set Ex to ""
if Ex is not "" then set Nm to text 1 thru ((count Nm) - (count Ex) - 1) of Nm
set end of nameList to Nm
end repeat
sort_items(nameList, found)
set FilesToOpen to choose from list nameList with multiple selections allowed
if result is false then return
set FilesToOpenList to {}
repeat with i in FilesToOpen
repeat with j from 1 to (count nameList)
if contents of i is item j of nameList then
set end of FilesToOpenList to item j of found
exit repeat
end if
end repeat
end repeat
repeat with i in FilesToOpenList
set o to POSIX file i
tell application "Finder" to open o
end repeat
to sort_items(sortList, SecondList)
script l
property srt : sortList
property sec : SecondList
end script
tell (count l's srt) to repeat with i from (it - 1) to 1 by -1
set s to (l's srt)'s item i
set r to (l's sec)'s item i
repeat with i from (i + 1) to it
tell (l's srt)'s item i to if s > it then
set (l's srt)'s item (i - 1) to it
set (l's sec)'s item (i - 1) to (l's sec)'s item i
else
set (l's srt)'s item (i - 1) to s
set (l's sec)'s item (i - 1) to r
exit repeat
end if
end repeat
if it is i and s > (l's srt)'s end then
set (l's srt)'s item it to s
set (l's sec)'s item it to r
end if
end repeat
end sort_items
Awesome, thank you Stefan. The speed hit is unfortunate, but the script works great otherwise.
I know I asked for a lot and I appreciated your help! The next script question I’m going to post is likely way too challenging for folks to volunteer their expertise on.
BTW - I just made a small donation to MacScripter on behalf of StefanK, James Nierodzik, Mark Hunte as a token of appreciation.
Oops - one more question about this script: when I use iKey to call the script the cursor does not appear in the search term input box. Is there any way to make the cursor move there automatically so I don’t have to take additional steps to select the input box before I start typing in my search terms?
Thank you,
Erik
Very cool script… is there any chance you could comment the following?
repeat with i in found
set {name:Nm, name extension:Ex} to info for POSIX file i as alias
if Ex is missing value then set Ex to ""
if Ex is not "" then set Nm to text 1 thru ((count Nm) - (count Ex) - 1) of Nm
set end of nameList to Nm
end repeat
I’d actually like to modify this so the name includes the parent directory, and I’m not quite
understanding what exactly is happening in the above.
the code strips the name from the whole name with name extension
-- found is s list of POSIX paths
repeat with i in found
-- gets name und name extension of the list item i (e.g. Nm:"foo.pdf", Ex:"pdf")
set {name:Nm, name extension:Ex} to info for POSIX file i as alias
-- if there is no name extension (indicated as missing value), set it to an empty string
if Ex is missing value then set Ex to ""
-- strip the name from the name extension (e.g. Nm:"foo", Ex:"pdf")
if Ex is not "" then set Nm to text 1 thru ((count Nm) - (count Ex) - 1) of Nm
-- add the name to the list nameList
set end of nameList to Nm
end repeat