Skip to content

Instantly share code, notes, and snippets.

@SKaplanOfficial
Last active December 16, 2025 14:43
Show Gist options
  • Select an option

  • Save SKaplanOfficial/27aba5432c1a2539a776ff0cb89177e2 to your computer and use it in GitHub Desktop.

Select an option

Save SKaplanOfficial/27aba5432c1a2539a776ff0cb89177e2 to your computer and use it in GitHub Desktop.
Script to automate hiding tags from Finder's sidebar by scripting Finder's Settings → Sidebar → Tags configuration UI and unchecking all except for a predefined allowlist. Reports which tags were hidden. Both files are functionally equivalent.
--
-- clean-finder-tags.scpt
--
-- Author: Stephen Kaplan
-- Date: 2025-12-16
--
-- Description:
-- Automates hiding tags from Finder's sidebar by scripting Finder's
-- Settings → Sidebar → Tags configuration UI and unchecking all tags
-- except for a predefined allowlist. Reports which tags were hidden.
--
-- Notes:
-- This script can take a while to run if there are many tags.
-- The more tags you have, the longer it will take.
-- ~75 seconds to hide 10 tags out of 2000 total on M1 Pro MacBook Pro.
-- Still beats doing it manually.
--
-- Finder tags can get into odd states, so errors will get logged.
-- Manually hide any tags that the script fails to disable.
--
-- Keywords:
-- Finder, Tags, Sidebar, UI Scripting, System Events, Settings, Preferences
--
-- License: MIT
-- https://opensource.org/license/mit
--
use AppleScript version "2.4" -- Yosemite (10.10) or later
on displaySettingsWindow(theApplication)
(*
* Opens the settings window for an application via its "Settings..." menu item.
* Returns a reference to the front window of the corresponding application process.
*)
set appName to missing value
if class of theApplication is text then
set appName to theApplication
else if class of theApplication is application then
set appName to name of theApplication
else
error "Expected app name string or application object specifier, got " & (class of theApplication as text) & " instead." number -8080
end if
set appProcess to missing value
tell application "System Events"
try
set appProcess to first application process whose name is appName and background only is false
on error number -1719
error "Application '" & appName & "' not found." number 8081
end try
click menu item "Settings…" of menu appName of menu bar 1 of appProcess
end tell
tell application appName
-- Wait for the window to open.
-- If the window uses some other name, just assume it's open after ~3 seconds.
set loopTimeout to 30
repeat while name of window 1 is not appName & " Settings" and loopTimeout > 0
set loopTimeout to loopTimeout - 1
delay 0.1
end repeat
end tell
tell application "System Events"
return a reference to window 1 of appProcess
end tell
end displaySettingsWindow
on hideTags apart from allowlist
set removedFromSidebar to {}
tell application "System Events"
set finderSettingsWindow to my displaySettingsWindow("Finder")
click button "Tags" of toolbar 1 of finderSettingsWindow
set enabledTags to get UI element 1 of (rows of table 1 of scroll area 1 of finderSettingsWindow whose value of checkbox 1 of its UI element 1 is 1)
repeat with theTag in enabledTags
try
if name of theTag is not in allowlist then
click checkbox 1 of theTag
copy name of theTag to end of removedFromSidebar
end if
on error errorMessage
log errorMessage
end try
end repeat
return removedFromSidebar
end tell
end hideTags
hideTags apart from {"Red", "Orange", "Yellow", "Green", "Blue", "Purple", "Gray"}
/*
* clean-finder-tags_jxa.scpt
*
* Author: Stephen Kaplan
* Date: 2025-12-16
*
* Description:
* Automates hiding tags from Finder's sidebar by scripting Finder's
* Settings → Sidebar → Tags configuration UI and unchecking all tags
* except for a predefined allowlist. Reports which tags were hidden.
*
* Notes:
* This script can take a while to run if there are many tags.
* The more tags you have, the longer it will take.
* ~75 seconds to hide 10 tags out of 2000 total on M1 Pro MacBook Pro.
* Still beats doing it manually.
*
* Finder tags can get into odd states, so errors will get logged.
* Manually hide any tags that the script fails to disable.
*
* Keywords:
* Finder, Tags, Sidebar, UI Scripting, System Events, Settings, Preferences
*
* License: MIT
* https://opensource.org/license/mit
*
* Copyright (c) 2025 Stephen Kaplan
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
function displaySettingsWindow(theApplication) {
/*
* Opens the settings window for an application via its "Settings..." menu item.
* Returns a reference to the front window of the corresponding application process.
*/
let appName;
let appProcess;
if (typeof theApplication === "string") {
appName = theApplication;
} else {
try {
appName = theApplication.name();
} catch (error) {
const err = Error(`Expected app name string or application object specifier, got ${theApplication} instead.`);
err.errorNumber = -8080;
throw err;
}
}
const systemEvents = Application("System Events");
try {
appProcess = systemEvents.applicationProcesses.whose({'_and': [
{name: appName},
{backgroundOnly: false}
]})()[0];
} catch (error) {
const err = Error(`Application ${appName} not found.`);
err.errorNumber = -8081;
throw err;
}
if (appProcess != undefined) {
appProcess.menuBars.first.menus.byName(appName).menuItems.byName('Settings…').click();
}
// Wait for the window to open.
// If the window uses some other name, just assume it's open after ~3 seconds.
let loopTimeout = 30;
while (appProcess.windows.first.name() !== `${appName} Settings` && loopTimeout > 0) {
loopTimeout -= 1;
delay(0.1);
}
return appProcess.windows.first;
}
function setSidebarTags(allowlist) {
const removedFromSidebar = [];
const systemEvents = Application("System Events");
const finderSettingsWindow = displaySettingsWindow(Application("Finder"))
finderSettingsWindow.toolbars.first.buttons.byName("Tags").click();
const enabledTags = finderSettingsWindow.scrollAreas.first.tables.first.rows.whose({'_match': [ObjectSpecifier().uiElements[0].checkboxes[0].value, 1]}).uiElements.first();
enabledTags.forEach((tag) => {
try {
let tagName = tag.name();
if (!allowlist.includes(tagName)) {
tag.checkboxes.first.click();
removedFromSidebar.push(tagName);
delay(1);
}
} catch (error) {
console.log(error, tag);
}
});
return removedFromSidebar;
}
setSidebarTags(["Red", "Orange", "Yellow", "Green", "Blue", "Purple", "Gray"])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment