@@ -163,6 +163,27 @@ jobs:
163163 EXTRA=(--codesign-identity "$SIGN_IDENTITY"
164164 --osx-entitlements-file setup/macos/App.entitlements)
165165 fi
166+
167+ # Bundle enchant explicitly. PyInstaller's stock enchant hook does
168+ # NOT ship a working spell checker here: pyenchant is pip-installed
169+ # (so the hook's brew/macports collection branch is skipped), and
170+ # the enchant backend plugins are dlopen-ed at runtime, so Mach-O
171+ # dependency analysis never sees them. Without this the shipped app
172+ # has an empty dictionary list (see issue #2705). We add libenchant
173+ # and its backends from Homebrew, keeping the lib/ + lib/enchant-2/
174+ # sibling layout that relocatable enchant-2 uses to find backends.
175+ # The macOS applespell backend is what exposes the OS dictionaries.
176+ # brew --prefix is arch-agnostic (/opt/homebrew or /usr/local).
177+ ENCHANT_PREFIX="$(brew --prefix enchant)"
178+ LIBENCHANT="$(ls "$ENCHANT_PREFIX"/lib/libenchant-2.*.dylib | head -n1)"
179+ EXTRA+=(--add-binary "$LIBENCHANT:lib")
180+ for so in "$ENCHANT_PREFIX"/lib/enchant-2/*.so; do
181+ EXTRA+=(--add-binary "$so:lib/enchant-2")
182+ done
183+ # Runtime hook points pyenchant at the bundled libenchant (via
184+ # PYENCHANT_LIBRARY_PATH) before novelWriter lazily imports enchant.
185+ EXTRA+=(--runtime-hook setup/macos/pyinstaller_rthook_enchant.py)
186+
166187 # novelwriter itself is bundled by module-graph analysis of the
167188 # entry script (no dynamic imports), so --collect-all novelwriter
168189 # is unnecessary — and on case-insensitive macOS it resolves the
@@ -213,6 +234,13 @@ jobs:
213234 || { echo "ERROR: compiled .qm files not bundled"; exit 1; }
214235 test -n "$(find "$APP_FW/assets/icons" -name '*.icons' 2>/dev/null)" \
215236 || { echo "ERROR: icon themes not bundled"; exit 1; }
237+ # Guard against silently shipping a spell checker with no backend
238+ # (the empty-dropdown regression from #2705). libenchant and at
239+ # least one enchant-2 backend plugin must be present.
240+ test -n "$(ls "$APP_FW"/lib/libenchant-2.*.dylib 2>/dev/null)" \
241+ || { echo "ERROR: libenchant not bundled"; exit 1; }
242+ test -n "$(find "$APP_FW/lib/enchant-2" -name '*.so' 2>/dev/null)" \
243+ || { echo "ERROR: enchant backend plugins not bundled"; exit 1; }
216244 plutil -extract CFBundleIdentifier raw dist/novelWriter.app/Contents/Info.plist
217245 plutil -extract CFBundleShortVersionString raw dist/novelWriter.app/Contents/Info.plist
218246
0 commit comments