Instantly share code, notes, and snippets.
Last active
December 16, 2025 14:43
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| -- | |
| -- 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"} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| * 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