These scripts temporarily exclude a group from search and include it afterwards. Think of them as kind of reverse of DEVONthink allowing multiple selection in the navigation sidebar: instead of choosing where exactly you want to search choose where you don’t want to. Multiple selection and exclusion can be used together which makes really nice fine tuning possible.
I made a simple version the other day, it relied on the group selector remembering the last chosen group. That’s fine as long as you want to exclude one group for a search but easily gets confusing when multiple groups were excluded. Solution to this is to write excluded groups to a record so we don’t have to keep track of them. This log record is created in a group in the global inbox so it’s always available. It gets deleted when its empty, there’s an option to also delete the created group, but if you leave this set to false you can directly see that the group is empty which means there are no groups excluded anymore (I’ve found I can faster find the group than figuring out where it would be if it wasn’t deleted).
There are two versions of the script(s): One uses separate scripts for exluding and including, the other version does both. The difference that makes usage of excluding and including in the latter reasonably practicable is that it opens the log record when a group is excluded so it’s easy to see what’s going on. The version that uses separate scripts got an option to open the log record but it can be easily used without it as there’s no chance of confusion; this version is handy if you want to exclude groups during the day without the log record getting in the way. Let’s say you’ve excluded a lot of groups, how to include all of them again? Doing it one by one is of course possible but there’s a faster way: choose the log record’s group in the group selector and all exclusions are reverted.
Three more options which are pretty self-explanatory: One that updates the search results after an exclusion or inclusion, one that restores the selection and one that tells the log record’s window where you want it to appear.
That’s it.
-- Exclude group from search / Include group in search
property updateSearchResults : true
property restoreSelection : true
property theLogGroup_Location : "/_Excluded"
property theLogRecord_Name : "Excluded from search"
property theLogRecord_WindowBounds : {} -- e.g. {2560, 280, 3160, 1092}
property deleteEmptyLogGroup : false
tell application id "DNtp"
try
set theGroup to display group selector "Exclude from / Include in search:"
set theRefURL to reference URL of theGroup
set theLogGroup to get record at theLogGroup_Location in inbox
if theLogGroup = missing value then set theLogGroup to create location theLogGroup_Location in inbox
set theLogRecord to get record at theLogGroup_Location & "/" & theLogRecord_Name & ".md"
if theLogRecord = missing value then set theLogRecord to create record with {name:theLogRecord_Name, type:markdown, plain text:""} in theLogGroup
set theText to plain text of theLogRecord
if theText = "" then
set theLine to name of database of theGroup & space & "[" & name of theGroup & "](" & theRefURL & ")" & space & space
set plain text of theLogRecord to theLine
set newWindow to open window for record theLogRecord
if theLogRecord_WindowBounds ≠ {} then set bounds of newWindow to theLogRecord_WindowBounds
tell application "System Events" to tell process "DEVONthink 3" to perform action "AXRaise" of window 2
set exclude from search of theGroup to true
display notification (name of theGroup as string) with title "Excluded from search"
else
set theSource to source of theLogRecord
if theLogGroup = theGroup then
repeat with thisRefURL in get links of theSource
set thisGroup to get record with uuid ((characters 21 thru -1 in thisRefURL) as string)
set exclude from search of thisGroup to false
end repeat
delete record theLogRecord
if deleteEmptyLogGroup = true then if (count (children of theLogGroup)) = 0 then delete record theLogGroup
display notification "All" with title "Included in search"
else if theText contains theRefURL then
set newText_list to {}
repeat with thisLine in paragraphs of theText
if thisLine as string does not contain theRefURL then set end of newText_list to thisLine as string
end repeat
set newText to my tid(newText_list, linefeed)
if newText ≠ "" then
set plain text of theLogRecord to newText
else
delete record theLogRecord
if deleteEmptyLogGroup = true then if (count (children of theLogGroup)) = 0 then delete record theLogGroup
end if
set exclude from search of theGroup to false
display notification (name of theGroup as string) with title "Included in search"
else
set theLine to name of database of theGroup & space & "[" & name of theGroup & "](" & theRefURL & ")" & space & space
set plain text of theLogRecord to theText & linefeed & theLine
if uuid of theLogRecord is not in (uuid of content record of think windows) then
set newWindow to open window for record theLogRecord
if theLogRecord_WindowBounds ≠ {} then set bounds of newWindow to theLogRecord_WindowBounds
tell application "System Events" to tell process "DEVONthink 3" to perform action "AXRaise" of window 2
end if
set exclude from search of theGroup to true
display notification (name of theGroup as string) with title "Excluded from search"
end if
end if
if updateSearchResults = true then
if (exists viewer window 1) then
set theQuery to (search query of viewer window 1) as string
if theQuery ≠ "" then
if restoreSelection = true then set theSelection to selection of viewer window 1
set search query of viewer window 1 to "_"
set search query of viewer window 1 to theQuery
if restoreSelection = true then set (selection of viewer window 1) to theSelection
end if
end if
end if
on error error_message number error_number
if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
end try
end tell
on tid(theList, theDelimiter)
set d to AppleScript's text item delimiters
set AppleScript's text item delimiters to theDelimiter
set theList_string to theList as text
set AppleScript's text item delimiters to d
return theList_string
end tid
Exclude
-- Exclude group from search
property updateSearchResults : true
property restoreSelection : true
property theLogGroup_Location : "/_Excluded"
property theLogRecord_Name : "Excluded from search"
property openLogRecord : true
property theLogRecord_WindowBounds : {} -- e.g. {2560, 280, 3160, 1092}
tell application id "DNtp"
try
set theGroup to display group selector "Exclude from search:"
set exclude from search of theGroup to true
display notification (name of theGroup as string) with title "Excluded from search"
set theRefURL to reference URL of theGroup
set theLogRecord to get record at theLogGroup_Location & "/" & theLogRecord_Name & ".md"
if theLogRecord = missing value then
set theLogGroup to create location theLogGroup_Location in inbox
set theLogRecord to create record with {name:theLogRecord_Name, type:markdown, plain text:""} in theLogGroup
end if
set theText to plain text of theLogRecord
if theText does not contain theRefURL then
set theLine to name of database of theGroup & space & "[" & name of theGroup & "](" & theRefURL & ")" & space & space
set plain text of theLogRecord to theText & linefeed & theLine
end if
if openLogRecord = true then
if uuid of theLogRecord is not in (uuid of content record of think windows) then
set newWindow to open window for record theLogRecord
if theLogRecord_WindowBounds ≠ {} then set bounds of newWindow to theLogRecord_WindowBounds
tell application "System Events" to tell process "DEVONthink 3" to perform action "AXRaise" of window 2
end if
end if
if updateSearchResults = true then
if (exists viewer window 1) then
set theQuery to (search query of viewer window 1) as string
if theQuery ≠ "" then
if restoreSelection = true then set theSelection to selection of viewer window 1
set search query of viewer window 1 to "_"
set search query of viewer window 1 to theQuery
if restoreSelection = true then set (selection of viewer window 1) to theSelection
end if
end if
end if
on error error_message number error_number
if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
end try
end tell
Include
-- Include group in search
property updateSearchResults : true
property restoreSelection : true
property theLogGroup_Location : "/_Excluded"
property theLogRecord_Name : "Excluded from search"
property deleteEmptyLogGroup : false
tell application id "DNtp"
try
set theGroup to display group selector "Include:"
set theLogGroup to get record at theLogGroup_Location in inbox
if theLogGroup = missing value then set theLogGroup to create location theLogGroup_Location in inbox
set theLogRecord to get record at theLogGroup_Location & "/" & theLogRecord_Name & ".md"
if theLogRecord = missing value then set theLogRecord to create record with {name:theLogRecord_Name, type:markdown, plain text:""} in theLogGroup
if theLogGroup = theGroup then
set theSource to source of theLogRecord
repeat with thisRefURL in get links of theSource
set thisGroup to get record with uuid ((characters 21 thru -1 in thisRefURL) as string)
set exclude from search of thisGroup to false
end repeat
delete record theLogRecord
if deleteEmptyLogGroup = true then if (count (children of theLogGroup)) = 0 then delete record theLogGroup
display notification "All" with title "Included in search"
else
set theRefURL to reference URL of theGroup
set theText to plain text of theLogRecord
set newText_list to {}
repeat with thisLine in paragraphs of theText
if thisLine as string does not contain theRefURL then set end of newText_list to thisLine as string
end repeat
set newText to my tid(newText_list, linefeed)
if newText ≠ "" then
set plain text of theLogRecord to newText
else
delete record theLogRecord
if deleteEmptyLogGroup = true then if (count (children of theLogGroup)) = 0 then delete record theLogGroup
end if
set exclude from search of theGroup to false
display notification (name of theGroup as string) with title "Included in search"
end if
if updateSearchResults = true then
if (exists viewer window 1) then
set theQuery to (search query of viewer window 1) as string
if theQuery ≠ "" then
if restoreSelection = true then set theSelection to selection of viewer window 1
set search query of viewer window 1 to "_"
set search query of viewer window 1 to theQuery
if restoreSelection = true then set (selection of viewer window 1) to theSelection
end if
end if
end if
on error error_message number error_number
if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
end try
end tell
on tid(theList, theDelimiter)
set d to AppleScript's text item delimiters
set AppleScript's text item delimiters to theDelimiter
set theList_string to theList as text
set AppleScript's text item delimiters to d
return theList_string
end tid