Reveal settings and data dir for excluding from Spotlight

This commit is contained in:
windingwind 2026-06-29 18:26:06 +02:00
parent 45a4cb11a7
commit b3475ca5c6
6 changed files with 12 additions and 79 deletions

View file

@ -340,12 +340,11 @@
<groupbox id="spotlight-privacy-group">
<label><html:h2 data-l10n-id="preferences-spotlight-privacy-title"/></label>
<description data-l10n-id="preferences-spotlight-privacy-description"/>
<checkbox
id="spotlight-exclude-data-dir"
data-l10n-id="preferences-spotlight-exclude-data-dir"
preference="extensions.zotero.spotlight.excludeDataDir"
native="true"
/>
<hbox>
<button id="spotlight-exclude-data-dir"
data-l10n-id="preferences-spotlight-exclude-data-dir"
oncommand="Zotero_Preferences.Spotlight.excludeDataDir()"/>
</hbox>
</groupbox>
<groupbox id="spotlight-format-group">

View file

@ -131,6 +131,11 @@ Zotero_Preferences.Spotlight = {
}
},
excludeDataDir: function () {
Zotero.DataDirectory.reveal();
Zotero.launchURL('x-apple.systempreferences:com.apple.preference.spotlight');
},
_excludedLibraries: function () {
try {
let raw = Zotero.Prefs.get('spotlight.excludedLibraries');

View file

@ -90,8 +90,6 @@ Zotero.Spotlight = new function () {
_registerPrefObservers();
_enabled = !!Zotero.Prefs.get(PREF + 'enabled');
// Applied regardless of ownership
_applyDataDirExclusion().catch(e => Zotero.logError(e));
if (!_enabled) {
return;
}
@ -367,11 +365,6 @@ Zotero.Spotlight = new function () {
_prefObserverIDs.push(
Zotero.Prefs.registerObserver(PREF + 'enabled', _onEnabledChanged)
);
// excludeDataDir has an immediate filesystem effect, so apply on change.
_prefObserverIDs.push(
Zotero.Prefs.registerObserver(PREF + 'excludeDataDir',
() => _applyDataDirExclusion().catch(e => Zotero.logError(e)))
);
}
function _unregisterPrefObservers() {
@ -406,29 +399,6 @@ Zotero.Spotlight = new function () {
_isOwner = false;
}
}
await _applyDataDirExclusion();
}
// `.metadata_never_index` file excludes the data dir from Spotlight indexing.
async function _applyDataDirExclusion() {
if (!_dataDir) {
return;
}
let file = PathUtils.join(_dataDir, '.metadata_never_index');
let shouldExclude = _available && _enabled
&& !!Zotero.Prefs.get(PREF + 'excludeDataDir');
try {
let exists = await IOUtils.exists(file);
if (shouldExclude && !exists) {
await IOUtils.writeUTF8(file, '');
}
else if (!shouldExclude && exists) {
await IOUtils.remove(file);
}
}
catch (e) {
Zotero.logError(e);
}
}
this.getForeignOwner = async function () {

View file

@ -111,9 +111,9 @@ preferences-spotlight-take-ownership =
.label = Use This Profile Instead
preferences-spotlight-libraries-title = Indexed Libraries
preferences-spotlight-privacy-title = Avoiding Duplicate Indexing
preferences-spotlight-privacy-description = macOS may also index the attachment files in your { -app-name } data directory, showing them in Spotlight alongside your library items. Excluding the data directory keeps Spotlight showing only your { -app-name } items.
preferences-spotlight-privacy-description = macOS may also index the attachment files in your { -app-name } data directory, showing them in Spotlight alongside your library items. To prevent this, add the data directory to the list under Spotlight’s Privacy settings.
preferences-spotlight-exclude-data-dir =
.label = Exclude data directory from Spotlight
.label = Reveal Data Directory and Open Spotlight Settings…
preferences-spotlight-format-title = Display Format
preferences-spotlight-format-description = Customize how items appear in Spotlight. See the <label data-l10n-name="spotlight-format-help-link">documentation</label> for the full list.
preferences-spotlight-title-template =

View file

@ -166,7 +166,6 @@ pref("extensions.zotero.httpServer.localAPI.enabled", false);
pref("extensions.zotero.spotlight.enabled", true);
pref("extensions.zotero.spotlight.openOnConfirm", true); // true = open the item's attachment, false = show in library
pref("extensions.zotero.spotlight.indexFullText", true);
pref("extensions.zotero.spotlight.excludeDataDir", true);
pref("extensions.zotero.spotlight.titleTemplate", "{{ title }}");
pref("extensions.zotero.spotlight.descriptionTemplate", "{{ firstCreator }}{{ year prefix=\" (\" suffix=\")\" }}");
pref("extensions.zotero.spotlight.excludedLibraries", "[]"); // JSON array of libraryIDs to skip

View file

@ -9,7 +9,6 @@ describe("Zotero.Spotlight", function () {
'spotlight.enabled',
'spotlight.openOnConfirm',
'spotlight.indexFullText',
'spotlight.excludeDataDir',
'spotlight.titleTemplate',
'spotlight.descriptionTemplate',
'spotlight.excludedLibraries',
@ -24,10 +23,6 @@ describe("Zotero.Spotlight", function () {
);
}
function neverIndexPath() {
return PathUtils.join(Zotero.DataDirectory.dir, '.metadata_never_index');
}
// Unique lowercase-alnum token so a Core Spotlight wildcard query can find a
// specific item without colliding with anything else in the index.
function token() {
@ -51,17 +46,6 @@ describe("Zotero.Spotlight", function () {
return results;
}
async function waitForFileState(path, shouldExist, timeout = 5000) {
let start = Date.now();
while (Date.now() - start < timeout) {
if ((await IOUtils.exists(path)) === shouldExist) {
return true;
}
await Zotero.Promise.delay(100);
}
return false;
}
before(async function () {
if (!Zotero.isMac || !Zotero.Spotlight || !Zotero.Spotlight.available) {
Zotero.debug("Spotlight: bridge unavailable; skipping Spotlight tests");
@ -324,30 +308,6 @@ describe("Zotero.Spotlight", function () {
});
});
describe("data directory exclusion", function () {
before(function () {
// The exclusion only applies while the feature is enabled.
Zotero.Prefs.set('spotlight.enabled', true);
});
it("should write .metadata_never_index when the exclusion is on", async function () {
Zotero.Prefs.set('spotlight.excludeDataDir', false);
assert.isTrue(await waitForFileState(neverIndexPath(), false));
Zotero.Prefs.set('spotlight.excludeDataDir', true);
assert.isTrue(await waitForFileState(neverIndexPath(), true),
".metadata_never_index should be created");
});
it("should remove .metadata_never_index when the exclusion is off", async function () {
Zotero.Prefs.set('spotlight.excludeDataDir', true);
assert.isTrue(await waitForFileState(neverIndexPath(), true));
Zotero.Prefs.set('spotlight.excludeDataDir', false);
assert.isTrue(await waitForFileState(neverIndexPath(), false),
".metadata_never_index should be removed");
Zotero.Prefs.set('spotlight.excludeDataDir', true);
});
});
describe("indexing round-trip", function () {
before(async function () {
if (!Zotero.Spotlight.indexingAvailable()) {