Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package emacs-jinx for openSUSE:Factory 
checked in at 2026-02-04 21:08:37
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/emacs-jinx (Old)
 and      /work/SRC/openSUSE:Factory/.emacs-jinx.new.1670 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "emacs-jinx"

Wed Feb  4 21:08:37 2026 rev:11 rq:1330832 version:2.6

Changes:
--------
--- /work/SRC/openSUSE:Factory/emacs-jinx/emacs-jinx.changes    2025-04-20 
19:51:36.203962089 +0200
+++ /work/SRC/openSUSE:Factory/.emacs-jinx.new.1670/emacs-jinx.changes  
2026-02-04 21:08:52.871595189 +0100
@@ -1,0 +2,32 @@
+Tue Feb 03 20:15:06 UTC 2026 - BjΓΆrn Kettunen <[email protected]>
+
+- Rebase 0001-Only-export-necessary-symbols.-Fixes-105.patch
+  against version 2.1
+ 
+- Update to version 2.6:
+  * jinx-next/jinx-previous: Make argument optional
+  * Add link to proposed file-local language variable bug svg#80071
+  
+- Changes from version 2.5
+  * Drop annotation-function,
+    We provide an affixation-function supported since Emacs 28.
+  * Actions can now be triggered via digit keys
+  * Remove C-u C-u C-u M-$ keybind
+  
+- Changes from version 2.4
+  * Use eager-display for the default completion UI, on Emacs 31.
+  * Update bundled emacs-module.h
+  * Use globalized minor mode predicate, require Emacs 29
+  * jinx-exclude-properties: Exclude propertized text
+  * jinx-exclude-regexps: Expand docstring
+  
+- Changes from version 2.3
+  * jinx-correct-all: Show message when ONLY-CHECK is non-nil
+  
+- Changes from ersion 2.2
+  * Stop using enchant_dict_get_extra_word_characters.
+    Instead rely on the jinx--syntax-table for tokenization.
+    See also ghub#rrthomas/enchant#244.
+  * jinx--save-dir: Do not switch to .dir-locals.el (Fix gh#minad/jinx#236)
+
+-------------------------------------------------------------------

Old:
----
  jinx-2.1.obscpio

New:
----
  jinx-2.6.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ emacs-jinx.spec ++++++
--- /var/tmp/diff_new_pack.bA7GUJ/_old  2026-02-04 21:08:53.955640589 +0100
+++ /var/tmp/diff_new_pack.bA7GUJ/_new  2026-02-04 21:08:53.959640757 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package emacs-jinx
 #
-# Copyright (c) 2025 SUSE LLC
+# Copyright (c) 2026 SUSE LLC and contributors
 # Copyright (c) 2023 BjΓΆrn Bidar
 #
 # All modifications and additions to the file contributed by third parties
@@ -20,7 +20,7 @@
 %global _name    jinx
 
 Name:           emacs-%{_name}
-Version:        2.1
+Version:        2.6
 Release:        0
 Summary:        Enchanted Spell Checker for Emacs
 License:        GPL-3.0-or-later

++++++ 0001-Only-export-necessary-symbols.-Fixes-105.patch ++++++
--- /var/tmp/diff_new_pack.bA7GUJ/_old  2026-02-04 21:08:53.987641929 +0100
+++ /var/tmp/diff_new_pack.bA7GUJ/_new  2026-02-04 21:08:53.995642264 +0100
@@ -16,7 +16,7 @@
  2 files changed, 18 insertions(+), 3 deletions(-)
 
 diff --git a/jinx-mod.c b/jinx-mod.c
-index 
33e080d34bc0f53a2e7bc5ff0c3d9ee5bb70eb39..476b8c105985514d2f2870fb50b9bcfe3923abba
 100644
+index 
b28ddf67001b4f78d024352473f6e312b1b731bc..d71b3f1ba7a2cefc0b8970e2d0061258f960eb29
 100644
 --- a/jinx-mod.c
 +++ b/jinx-mod.c
 @@ -20,10 +20,25 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
@@ -46,7 +46,7 @@
  
  static EnchantBroker* broker = 0;
  static emacs_value Qt, Qnil, Qcons;
-@@ -173,7 +188,7 @@ static emacs_value jinx_suggest(emacs_env* env, ptrdiff_t 
jinx_unused(nargs),
+@@ -160,7 +175,7 @@ static emacs_value jinx_suggest(emacs_env* env, ptrdiff_t 
jinx_unused(nargs),
      return list;
  }
  
@@ -56,10 +56,10 @@
      if ((size_t)runtime->size < sizeof (*runtime))
          return 1;
 diff --git a/jinx.el b/jinx.el
-index 
5561f3996a1a2fe5eeb85532ac1c89621f7ea1da..3beec38a32ea830d33d28d03b342ee2e944b399b
 100644
+index 
9da85d2bf236570ea2e656637353b1b37dc57446..a53d0096485dd08532c6694c4b25d2f6982f9a3f
 100644
 --- a/jinx.el
 +++ b/jinx.el
-@@ -269,7 +269,7 @@ (easy-menu-define jinx-mode-menu jinx-mode-map
+@@ -282,7 +282,7 @@ (easy-menu-define jinx-mode-menu jinx-mode-map
  ;;;; Internal variables
  
  (defvar jinx--compile-flags

++++++ jinx-2.1.obscpio -> jinx-2.6.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jinx-2.1/.elpaignore new/jinx-2.6/.elpaignore
--- old/jinx-2.1/.elpaignore    1970-01-01 01:00:00.000000000 +0100
+++ new/jinx-2.6/.elpaignore    2026-01-17 17:50:00.000000000 +0100
@@ -0,0 +1,3 @@
+LICENSE
+.elpaignore
+.github
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jinx-2.1/.github/ISSUE_TEMPLATE/bug_report.md 
new/jinx-2.6/.github/ISSUE_TEMPLATE/bug_report.md
--- old/jinx-2.1/.github/ISSUE_TEMPLATE/bug_report.md   1970-01-01 
01:00:00.000000000 +0100
+++ new/jinx-2.6/.github/ISSUE_TEMPLATE/bug_report.md   2026-01-17 
17:50:00.000000000 +0100
@@ -0,0 +1,22 @@
+---
+title:
+name: 🐞 Bug report
+about: Report a bug. Do not use this for questions, support or feature 
requests.
+---
+Thank you for reporting a bug.
+
+Please use the latest stable release of Emacs 30.1 and start with `emacs -Q` or
+`package-isolate` in order to only load a minimal set of packages. This way 
your
+Emacs configuration is not loaded.
+
+Make sure that you install the newest versions of the involved packages. Please
+also reinstall and recompile the involved packages, ideally remove all and
+reinstall all packages, to exclude compilation issues due to outdated
+dependencies.
+
+Please provide precise information, stack traces and the exact steps to
+reproduce the issue. This is important to ensure that your problem can be
+reproduced on a different machine.
+
+If you are not really sure if your issue is a bug, please open a discussion
+instead.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jinx-2.1/.github/ISSUE_TEMPLATE/config.yml 
new/jinx-2.6/.github/ISSUE_TEMPLATE/config.yml
--- old/jinx-2.1/.github/ISSUE_TEMPLATE/config.yml      1970-01-01 
01:00:00.000000000 +0100
+++ new/jinx-2.6/.github/ISSUE_TEMPLATE/config.yml      2026-01-17 
17:50:00.000000000 +0100
@@ -0,0 +1,23 @@
+blank_issues_enabled: false
+contact_links:
+  - name: "πŸ™ Please support my work on Jinx and my other Emacs packages"
+    url: https://github.com/sponsors/minad
+    about: Thanks! Your support helps dedicating time to project maintenance 
and development.
+  - name: "πŸ’‘ Suggest a feature ➞ Please create a discussion"
+    url: https://github.com/minad/jinx/discussions/categories/ideas
+    about: Start a new discussion suggesting an improvement or a feature.
+  - name: "πŸ§‘β€πŸ€β€πŸ§‘ Ask the community for support"
+    url: https://www.reddit.com/r/emacs
+    about: Please be kind and support others.
+  - name: "πŸ€“ Ask the maintainer for support ➞ Please create a discussion"
+    url: https://github.com/minad/jinx/discussions/categories/q-a
+    about: Please keep in mind that my bandwidth is limited.
+  - name: "πŸ” Search through old issues or discussions"
+    url: https://github.com/search?q=repo%3Aminad%2Fjinx&type=issues
+    about: The same question may have been asked before.
+  - name: "πŸ“ Jinx wiki"
+    url: https://github.com/minad/jinx/wiki
+    about: Additional configuration tips are covered there. Feel free to edit!
+  - name: "πŸ“– Jinx manual"
+    url: https://github.com/minad/jinx/blob/main/README.org
+    about: The manual covers the basic setup and workflow.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jinx-2.1/CHANGELOG.org new/jinx-2.6/CHANGELOG.org
--- old/jinx-2.1/CHANGELOG.org  2025-04-04 13:23:21.000000000 +0200
+++ new/jinx-2.6/CHANGELOG.org  2026-01-17 17:50:00.000000000 +0100
@@ -2,6 +2,32 @@
 #+author: Daniel Mendler
 #+language: en
 
+* Version 2.6 (2026-01-17)
+
+- Use =when-let*= instead of =when-let=.
+- =jinx-next/previous=: Make argument optional.
+
+* Version 2.5 (2025-11-29)
+
+- Actions can be triggered via digit keys now.
+- Drop legacy =annotation-function=.
+
+* Version 2.4 (2025-10-13)
+
+- =jinx-exclude-properties=: New variable to exclude propertized text from
+  checking. Exclude =read-only= text by default.
+- Use =eager-display= for the default completion UI.
+- Require Emacs 29.
+
+* Version 2.3 (2025-07-28)
+
+- ~jinx-correct-all~: Show message if ~ONLY-CHECK~ is non-nil.
+
+* Version 2.2 (2025-05-26)
+
+- Stop using =enchant_dict_get_extra_word_characters=. Instead rely on the
+  =jinx--syntax-table= for tokenization.
+
 * Version 2.1 (2025-04-04)
 
 - ~jinx-correct~: For capitalized words, offer lower case variants to save in
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jinx-2.1/README.org new/jinx-2.6/README.org
--- old/jinx-2.1/README.org     2025-04-04 13:23:21.000000000 +0200
+++ new/jinx-2.6/README.org     2026-01-17 17:50:00.000000000 +0100
@@ -20,14 +20,15 @@
 corrected from a list of dictionary words presented as a completion menu.
 
 Installing Jinx is straight-forward and configuring should not need much
-intervention. Jinx can be used completely on its own, but can also safely
-co-exist with Emacs's built-in spell-checker Ispell.
+intervention. Jinx can be used completely on its own, and is designed as a full
+replacement for Emacs's built-in spell-checker Ispell, but it can also safely
+co-exist with it.
 
 Jinx's high performance and low resource usage comes from directly calling the
 API of the [[https://rrthomas.github.io/enchant/][Enchant library]]. Jinx 
automatically compiles =jinx-mod.c= and loads the
 dynamic module at startup. By binding directly to the native Enchant API, Jinx
 avoids slower inter-process communication. Enchant is used by other text 
editors
-and supports multiple backends like [[https://nuspell.github.io/][Nuspell]], 
[[http://hunspell.github.io/][Hunspell]] and [[http://aspell.net/][Aspell]].
+and supports multiple backends like [[https://nuspell.github.io/][Nuspell]], 
[[https://hunspell.github.io/][Hunspell]] and [[http://aspell.net/][Aspell]].
 
 Jinx supports spell-checking multiple languages in the same buffer. See the
 =jinx-languages= variable to customize for multiple languages. Jinx can 
flexibly
@@ -43,18 +44,20 @@
 
 Jinx can be installed from GNU ELPA or MELPA directly with =package-install=.
 
-Most importantly your Emacs must be compiled with dynamic module support. Jinx
-requires =libenchant=, which is needed to compile the native module at install
-time. If =pkgconf= or =pkg-config= is available, Jinx will use it to locate
-=libenchant= during installation. Depending on your BSD or Linux distribution 
you
-have to install different packages:
+Your Emacs must be compiled with dynamic module support. Furthermore a C
+compiler must be available on your system (=gcc= or =clang=). Jinx requires
+=libenchant=, which is needed to compile the native module at install time. If
+=pkgconf= or =pkg-config= is available, Jinx will use it to locate 
=libenchant= during
+installation. Depending on your BSD or Linux distribution you have to install
+different packages:
 
 - Debian, Ubuntu: =libenchant-2-dev=, =pkgconf=
 - Arch, Gentoo: =enchant=, =pkgconf=
 - Guix: =emacs-jinx= defined in =emacs-xyz.scm=
 - Nix: =jinx= defined in =elpa-packages.nix=
-- Void, Fedora: =enchant2-devel=, =pkgconf=
-- OpenSUSE: =emacs-jinx= or =enchant=, =pkgconf=
+- Void: =enchant2-devel=, =pkgconf=
+- Fedora: =emacs-jinx= or =enchant2-devel=, =pkgconf-pkg-config=
+- OpenSUSE: =emacs-jinx= or =enchant-devel=, =pkgconf-pkg-config=
 - FreeBSD, OpenBSD, Mac: =enchant2=, =pkgconf=
 
 On Windows the installation of the native module may require manual
@@ -85,9 +88,9 @@
 #+end_src
 
 - =M-$= triggers correction for the misspelled word before point.
-- =C-u M-$= triggers correction for the entire buffer.
-- =C-u C-u M-$= forces correction of the word at point, even if it is not
-  misspelled.
+- =C-u M-$= or =M-x jinx-correct-all= spell-checks the entire buffer.
+- =C-u C-u M-$= or =M-x jinx-correct-word= forces correction of the word at 
point,
+  even if it is not misspelled.
 
 A sample configuration with the popular =use-package= macro is shown here:
 
@@ -109,11 +112,13 @@
 from suggestions.
 
 If you prefer to use the keyboard, invoke the command =jinx-correct=. The
-recommended binding is =M-$=, see the configuration section. Suggested 
corrections
-will be displayed as a completion menu. You can press the displayed digit keys
-to quickly select a suggestion. Furthermore the menu offers options to save the
-word temporarily for the current session, in the personal dictionary or in the
-file-local or directory-local variables.
+recommended binding is =M-$=, see the configuration section. In order to check 
the
+entire buffer press the keys =C-u M-$= or use =M-x jinx-correct-all=.
+
+Suggested corrections will be displayed as a completion menu. You can press the
+displayed digit keys to quickly select a suggestion. Furthermore the menu 
offers
+options to save the word temporarily for the current session, in the personal
+dictionary or in the file-local or directory-local variables.
 
 You can enter arbitrary input at the correction prompt in order to make the
 correction or to store a modified word in the personal dictionary. For example
@@ -134,7 +139,7 @@
 #+begin_src emacs-lisp
 (add-to-list 'vertico-multiform-categories
              '(jinx grid (vertico-grid-annotate . 20) (vertico-count . 4)))
-(vertico-multiform-mode 1)
+(vertico-multiform-mode)
 #+end_src
 
 * Navigating between misspellings
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jinx-2.1/emacs-module.h new/jinx-2.6/emacs-module.h
--- old/jinx-2.1/emacs-module.h 2025-04-04 13:23:21.000000000 +0200
+++ new/jinx-2.6/emacs-module.h 2026-01-17 17:50:00.000000000 +0100
@@ -1,6 +1,6 @@
 /* emacs-module.h - GNU Emacs module API.
 
-Copyright (C) 2015-2021 Free Software Foundation, Inc.
+Copyright (C) 2015-2023 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -30,11 +30,12 @@
 #include <stdint.h>
 #include <time.h>
 
-#ifndef __cplusplus
+#if ((defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 202311 \
+     && !defined __bool_true_false_are_defined && !defined __cplusplus)
 #include <stdbool.h>
 #endif
 
-#define EMACS_MAJOR_VERSION 28
+#define EMACS_MAJOR_VERSION 29
 
 #if defined __cplusplus && __cplusplus >= 201103L
 # define EMACS_NOEXCEPT noexcept
@@ -53,7 +54,7 @@
    __attribute__ ((__nonnull__ (__VA_ARGS__)))
 #elif (defined __has_attribute \
        && (!defined __clang_minor__ \
-          || 3 < __clang_major__ + (5 <= __clang_minor__)))
+           || 3 < __clang_major__ + (5 <= __clang_minor__)))
 # if __has_attribute (__nonnull__)
 #  define EMACS_ATTRIBUTE_NONNULL(...) \
     __attribute__ ((__nonnull__ (__VA_ARGS__)))
@@ -68,7 +69,7 @@
 #endif
 
 /* Current environment.  */
-typedef struct emacs_env_28 emacs_env;
+typedef struct emacs_env_29 emacs_env;
 
 /* Opaque pointer representing an Emacs Lisp value.
    BEWARE: Do not assume NULL is a valid value!  */
@@ -115,7 +116,7 @@
   /* Function has signaled an error using `signal'.  */
   emacs_funcall_exit_signal = 1,
 
-  /* Function has exit using `throw'.  */
+  /* Function has exited using `throw'.  */
   emacs_funcall_exit_throw = 2
 };
 
@@ -166,26 +167,26 @@
     EMACS_ATTRIBUTE_NONNULL(1, 2, 3);
 
   void (*non_local_exit_signal) (emacs_env *env,
-                                emacs_value symbol, emacs_value data)
+                                 emacs_value symbol, emacs_value data)
     EMACS_ATTRIBUTE_NONNULL(1);
 
   void (*non_local_exit_throw) (emacs_env *env,
-                               emacs_value tag, emacs_value value)
+                                emacs_value tag, emacs_value value)
     EMACS_ATTRIBUTE_NONNULL(1);
 
   /* Function registration.  */
 
   emacs_value (*make_function) (emacs_env *env,
-                               ptrdiff_t min_arity,
-                               ptrdiff_t max_arity,
-                               emacs_value (*func) (emacs_env *env,
+                                ptrdiff_t min_arity,
+                                ptrdiff_t max_arity,
+                                emacs_value (*func) (emacs_env *env,
                                                      ptrdiff_t nargs,
                                                      emacs_value* args,
                                                      void *data)
-                                 EMACS_NOEXCEPT
+                                  EMACS_NOEXCEPT
                                   EMACS_ATTRIBUTE_NONNULL(1),
-                               const char *docstring,
-                               void *data)
+                                const char *docstring,
+                                void *data)
     EMACS_ATTRIBUTE_NONNULL(1, 4);
 
   emacs_value (*funcall) (emacs_env *env,
@@ -240,13 +241,13 @@
 
   /* Create a Lisp string from a utf8 encoded string.  */
   emacs_value (*make_string) (emacs_env *env,
-                             const char *str, ptrdiff_t len)
+                              const char *str, ptrdiff_t len)
     EMACS_ATTRIBUTE_NONNULL(1, 2);
 
   /* Embedded pointer type.  */
   emacs_value (*make_user_ptr) (emacs_env *env,
-                               void (*fin) (void *) EMACS_NOEXCEPT,
-                               void *ptr)
+                                void (*fin) (void *) EMACS_NOEXCEPT,
+                                void *ptr)
     EMACS_ATTRIBUTE_NONNULL(1);
 
   void *(*get_user_ptr) (emacs_env *env, emacs_value arg)
@@ -257,7 +258,7 @@
   void (*(*get_user_finalizer) (emacs_env *env, emacs_value uptr))
     (void *) EMACS_NOEXCEPT EMACS_ATTRIBUTE_NONNULL(1);
   void (*set_user_finalizer) (emacs_env *env, emacs_value arg,
-                             void (*fin) (void *) EMACS_NOEXCEPT)
+                              void (*fin) (void *) EMACS_NOEXCEPT)
     EMACS_ATTRIBUTE_NONNULL(1);
 
   /* Vector functions.  */
@@ -265,7 +266,7 @@
     EMACS_ATTRIBUTE_NONNULL(1);
 
   void (*vec_set) (emacs_env *env, emacs_value vector, ptrdiff_t index,
-                  emacs_value value)
+                   emacs_value value)
     EMACS_ATTRIBUTE_NONNULL(1);
 
   ptrdiff_t (*vec_size) (emacs_env *env, emacs_value vector)
@@ -301,26 +302,26 @@
     EMACS_ATTRIBUTE_NONNULL(1, 2, 3);
 
   void (*non_local_exit_signal) (emacs_env *env,
-                                emacs_value symbol, emacs_value data)
+                                 emacs_value symbol, emacs_value data)
     EMACS_ATTRIBUTE_NONNULL(1);
 
   void (*non_local_exit_throw) (emacs_env *env,
-                               emacs_value tag, emacs_value value)
+                                emacs_value tag, emacs_value value)
     EMACS_ATTRIBUTE_NONNULL(1);
 
   /* Function registration.  */
 
   emacs_value (*make_function) (emacs_env *env,
-                               ptrdiff_t min_arity,
-                               ptrdiff_t max_arity,
-                               emacs_value (*func) (emacs_env *env,
+                                ptrdiff_t min_arity,
+                                ptrdiff_t max_arity,
+                                emacs_value (*func) (emacs_env *env,
                                                      ptrdiff_t nargs,
                                                      emacs_value* args,
                                                      void *data)
-                                 EMACS_NOEXCEPT
+                                  EMACS_NOEXCEPT
                                   EMACS_ATTRIBUTE_NONNULL(1),
-                               const char *docstring,
-                               void *data)
+                                const char *docstring,
+                                void *data)
     EMACS_ATTRIBUTE_NONNULL(1, 4);
 
   emacs_value (*funcall) (emacs_env *env,
@@ -375,13 +376,13 @@
 
   /* Create a Lisp string from a utf8 encoded string.  */
   emacs_value (*make_string) (emacs_env *env,
-                             const char *str, ptrdiff_t len)
+                              const char *str, ptrdiff_t len)
     EMACS_ATTRIBUTE_NONNULL(1, 2);
 
   /* Embedded pointer type.  */
   emacs_value (*make_user_ptr) (emacs_env *env,
-                               void (*fin) (void *) EMACS_NOEXCEPT,
-                               void *ptr)
+                                void (*fin) (void *) EMACS_NOEXCEPT,
+                                void *ptr)
     EMACS_ATTRIBUTE_NONNULL(1);
 
   void *(*get_user_ptr) (emacs_env *env, emacs_value arg)
@@ -392,7 +393,7 @@
   void (*(*get_user_finalizer) (emacs_env *env, emacs_value uptr))
     (void *) EMACS_NOEXCEPT EMACS_ATTRIBUTE_NONNULL(1);
   void (*set_user_finalizer) (emacs_env *env, emacs_value arg,
-                             void (*fin) (void *) EMACS_NOEXCEPT)
+                              void (*fin) (void *) EMACS_NOEXCEPT)
     EMACS_ATTRIBUTE_NONNULL(1);
 
   /* Vector functions.  */
@@ -400,7 +401,7 @@
     EMACS_ATTRIBUTE_NONNULL(1);
 
   void (*vec_set) (emacs_env *env, emacs_value vector, ptrdiff_t index,
-                  emacs_value value)
+                   emacs_value value)
     EMACS_ATTRIBUTE_NONNULL(1);
 
   ptrdiff_t (*vec_size) (emacs_env *env, emacs_value vector)
@@ -440,26 +441,26 @@
     EMACS_ATTRIBUTE_NONNULL(1, 2, 3);
 
   void (*non_local_exit_signal) (emacs_env *env,
-                                emacs_value symbol, emacs_value data)
+                                 emacs_value symbol, emacs_value data)
     EMACS_ATTRIBUTE_NONNULL(1);
 
   void (*non_local_exit_throw) (emacs_env *env,
-                               emacs_value tag, emacs_value value)
+                                emacs_value tag, emacs_value value)
     EMACS_ATTRIBUTE_NONNULL(1);
 
   /* Function registration.  */
 
   emacs_value (*make_function) (emacs_env *env,
-                               ptrdiff_t min_arity,
-                               ptrdiff_t max_arity,
-                               emacs_value (*func) (emacs_env *env,
+                                ptrdiff_t min_arity,
+                                ptrdiff_t max_arity,
+                                emacs_value (*func) (emacs_env *env,
                                                      ptrdiff_t nargs,
                                                      emacs_value* args,
                                                      void *data)
-                                 EMACS_NOEXCEPT
+                                  EMACS_NOEXCEPT
                                   EMACS_ATTRIBUTE_NONNULL(1),
-                               const char *docstring,
-                               void *data)
+                                const char *docstring,
+                                void *data)
     EMACS_ATTRIBUTE_NONNULL(1, 4);
 
   emacs_value (*funcall) (emacs_env *env,
@@ -514,13 +515,13 @@
 
   /* Create a Lisp string from a utf8 encoded string.  */
   emacs_value (*make_string) (emacs_env *env,
-                             const char *str, ptrdiff_t len)
+                              const char *str, ptrdiff_t len)
     EMACS_ATTRIBUTE_NONNULL(1, 2);
 
   /* Embedded pointer type.  */
   emacs_value (*make_user_ptr) (emacs_env *env,
-                               void (*fin) (void *) EMACS_NOEXCEPT,
-                               void *ptr)
+                                void (*fin) (void *) EMACS_NOEXCEPT,
+                                void *ptr)
     EMACS_ATTRIBUTE_NONNULL(1);
 
   void *(*get_user_ptr) (emacs_env *env, emacs_value arg)
@@ -531,7 +532,7 @@
   void (*(*get_user_finalizer) (emacs_env *env, emacs_value uptr))
     (void *) EMACS_NOEXCEPT EMACS_ATTRIBUTE_NONNULL(1);
   void (*set_user_finalizer) (emacs_env *env, emacs_value arg,
-                             void (*fin) (void *) EMACS_NOEXCEPT)
+                              void (*fin) (void *) EMACS_NOEXCEPT)
     EMACS_ATTRIBUTE_NONNULL(1);
 
   /* Vector functions.  */
@@ -539,7 +540,7 @@
     EMACS_ATTRIBUTE_NONNULL(1);
 
   void (*vec_set) (emacs_env *env, emacs_value vector, ptrdiff_t index,
-                  emacs_value value)
+                   emacs_value value)
     EMACS_ATTRIBUTE_NONNULL(1);
 
   ptrdiff_t (*vec_size) (emacs_env *env, emacs_value vector)
@@ -598,26 +599,26 @@
     EMACS_ATTRIBUTE_NONNULL(1, 2, 3);
 
   void (*non_local_exit_signal) (emacs_env *env,
-                                emacs_value symbol, emacs_value data)
+                                 emacs_value symbol, emacs_value data)
     EMACS_ATTRIBUTE_NONNULL(1);
 
   void (*non_local_exit_throw) (emacs_env *env,
-                               emacs_value tag, emacs_value value)
+                                emacs_value tag, emacs_value value)
     EMACS_ATTRIBUTE_NONNULL(1);
 
   /* Function registration.  */
 
   emacs_value (*make_function) (emacs_env *env,
-                               ptrdiff_t min_arity,
-                               ptrdiff_t max_arity,
-                               emacs_value (*func) (emacs_env *env,
+                                ptrdiff_t min_arity,
+                                ptrdiff_t max_arity,
+                                emacs_value (*func) (emacs_env *env,
                                                      ptrdiff_t nargs,
                                                      emacs_value* args,
                                                      void *data)
-                                 EMACS_NOEXCEPT
+                                  EMACS_NOEXCEPT
                                   EMACS_ATTRIBUTE_NONNULL(1),
-                               const char *docstring,
-                               void *data)
+                                const char *docstring,
+                                void *data)
     EMACS_ATTRIBUTE_NONNULL(1, 4);
 
   emacs_value (*funcall) (emacs_env *env,
@@ -672,13 +673,13 @@
 
   /* Create a Lisp string from a utf8 encoded string.  */
   emacs_value (*make_string) (emacs_env *env,
-                             const char *str, ptrdiff_t len)
+                              const char *str, ptrdiff_t len)
     EMACS_ATTRIBUTE_NONNULL(1, 2);
 
   /* Embedded pointer type.  */
   emacs_value (*make_user_ptr) (emacs_env *env,
-                               void (*fin) (void *) EMACS_NOEXCEPT,
-                               void *ptr)
+                                void (*fin) (void *) EMACS_NOEXCEPT,
+                                void *ptr)
     EMACS_ATTRIBUTE_NONNULL(1);
 
   void *(*get_user_ptr) (emacs_env *env, emacs_value arg)
@@ -689,7 +690,7 @@
   void (*(*get_user_finalizer) (emacs_env *env, emacs_value uptr))
     (void *) EMACS_NOEXCEPT EMACS_ATTRIBUTE_NONNULL(1);
   void (*set_user_finalizer) (emacs_env *env, emacs_value arg,
-                             void (*fin) (void *) EMACS_NOEXCEPT)
+                              void (*fin) (void *) EMACS_NOEXCEPT)
     EMACS_ATTRIBUTE_NONNULL(1);
 
   /* Vector functions.  */
@@ -697,7 +698,7 @@
     EMACS_ATTRIBUTE_NONNULL(1);
 
   void (*vec_set) (emacs_env *env, emacs_value vector, ptrdiff_t index,
-                  emacs_value value)
+                   emacs_value value)
     EMACS_ATTRIBUTE_NONNULL(1);
 
   ptrdiff_t (*vec_size) (emacs_env *env, emacs_value vector)
@@ -726,9 +727,183 @@
                                    const emacs_limb_t *magnitude)
     EMACS_ATTRIBUTE_NONNULL (1);
 
-  /* Add module environment functions newly added in Emacs 28 here.
-     Before Emacs 28 is released, remove this comment and start
-     module-env-29.h on the master branch.  */
+  void (*(*EMACS_ATTRIBUTE_NONNULL (1)
+            get_function_finalizer) (emacs_env *env,
+                                     emacs_value arg)) (void *) EMACS_NOEXCEPT;
+
+  void (*set_function_finalizer) (emacs_env *env, emacs_value arg,
+                                  void (*fin) (void *) EMACS_NOEXCEPT)
+    EMACS_ATTRIBUTE_NONNULL (1);
+
+  int (*open_channel) (emacs_env *env, emacs_value pipe_process)
+    EMACS_ATTRIBUTE_NONNULL (1);
+
+  void (*make_interactive) (emacs_env *env, emacs_value function,
+                            emacs_value spec)
+    EMACS_ATTRIBUTE_NONNULL (1);
+
+  /* Create a unibyte Lisp string from a string.  */
+  emacs_value (*make_unibyte_string) (emacs_env *env,
+                                      const char *str, ptrdiff_t len)
+    EMACS_ATTRIBUTE_NONNULL(1, 2);
+};
+
+struct emacs_env_29
+{
+  /* Structure size (for version checking).  */
+  ptrdiff_t size;
+
+  /* Private data; users should not touch this.  */
+  struct emacs_env_private *private_members;
+
+  /* Memory management.  */
+
+  emacs_value (*make_global_ref) (emacs_env *env, emacs_value value)
+    EMACS_ATTRIBUTE_NONNULL(1);
+
+  void (*free_global_ref) (emacs_env *env, emacs_value global_value)
+    EMACS_ATTRIBUTE_NONNULL(1);
+
+  /* Non-local exit handling.  */
+
+  enum emacs_funcall_exit (*non_local_exit_check) (emacs_env *env)
+    EMACS_ATTRIBUTE_NONNULL(1);
+
+  void (*non_local_exit_clear) (emacs_env *env)
+    EMACS_ATTRIBUTE_NONNULL(1);
+
+  enum emacs_funcall_exit (*non_local_exit_get)
+    (emacs_env *env, emacs_value *symbol, emacs_value *data)
+    EMACS_ATTRIBUTE_NONNULL(1, 2, 3);
+
+  void (*non_local_exit_signal) (emacs_env *env,
+                                 emacs_value symbol, emacs_value data)
+    EMACS_ATTRIBUTE_NONNULL(1);
+
+  void (*non_local_exit_throw) (emacs_env *env,
+                                emacs_value tag, emacs_value value)
+    EMACS_ATTRIBUTE_NONNULL(1);
+
+  /* Function registration.  */
+
+  emacs_value (*make_function) (emacs_env *env,
+                                ptrdiff_t min_arity,
+                                ptrdiff_t max_arity,
+                                emacs_value (*func) (emacs_env *env,
+                                                     ptrdiff_t nargs,
+                                                     emacs_value* args,
+                                                     void *data)
+                                  EMACS_NOEXCEPT
+                                  EMACS_ATTRIBUTE_NONNULL(1),
+                                const char *docstring,
+                                void *data)
+    EMACS_ATTRIBUTE_NONNULL(1, 4);
+
+  emacs_value (*funcall) (emacs_env *env,
+                          emacs_value func,
+                          ptrdiff_t nargs,
+                          emacs_value* args)
+    EMACS_ATTRIBUTE_NONNULL(1);
+
+  emacs_value (*intern) (emacs_env *env, const char *name)
+    EMACS_ATTRIBUTE_NONNULL(1, 2);
+
+  /* Type conversion.  */
+
+  emacs_value (*type_of) (emacs_env *env, emacs_value arg)
+    EMACS_ATTRIBUTE_NONNULL(1);
+
+  bool (*is_not_nil) (emacs_env *env, emacs_value arg)
+    EMACS_ATTRIBUTE_NONNULL(1);
+
+  bool (*eq) (emacs_env *env, emacs_value a, emacs_value b)
+    EMACS_ATTRIBUTE_NONNULL(1);
+
+  intmax_t (*extract_integer) (emacs_env *env, emacs_value arg)
+    EMACS_ATTRIBUTE_NONNULL(1);
+
+  emacs_value (*make_integer) (emacs_env *env, intmax_t n)
+    EMACS_ATTRIBUTE_NONNULL(1);
+
+  double (*extract_float) (emacs_env *env, emacs_value arg)
+    EMACS_ATTRIBUTE_NONNULL(1);
+
+  emacs_value (*make_float) (emacs_env *env, double d)
+    EMACS_ATTRIBUTE_NONNULL(1);
+
+  /* Copy the content of the Lisp string VALUE to BUFFER as an utf8
+     null-terminated string.
+
+     SIZE must point to the total size of the buffer.  If BUFFER is
+     NULL or if SIZE is not big enough, write the required buffer size
+     to SIZE and return true.
+
+     Note that SIZE must include the last null byte (e.g. "abc" needs
+     a buffer of size 4).
+
+     Return true if the string was successfully copied.  */
+
+  bool (*copy_string_contents) (emacs_env *env,
+                                emacs_value value,
+                                char *buf,
+                                ptrdiff_t *len)
+    EMACS_ATTRIBUTE_NONNULL(1, 4);
+
+  /* Create a Lisp string from a utf8 encoded string.  */
+  emacs_value (*make_string) (emacs_env *env,
+                              const char *str, ptrdiff_t len)
+    EMACS_ATTRIBUTE_NONNULL(1, 2);
+
+  /* Embedded pointer type.  */
+  emacs_value (*make_user_ptr) (emacs_env *env,
+                                void (*fin) (void *) EMACS_NOEXCEPT,
+                                void *ptr)
+    EMACS_ATTRIBUTE_NONNULL(1);
+
+  void *(*get_user_ptr) (emacs_env *env, emacs_value arg)
+    EMACS_ATTRIBUTE_NONNULL(1);
+  void (*set_user_ptr) (emacs_env *env, emacs_value arg, void *ptr)
+    EMACS_ATTRIBUTE_NONNULL(1);
+
+  void (*(*get_user_finalizer) (emacs_env *env, emacs_value uptr))
+    (void *) EMACS_NOEXCEPT EMACS_ATTRIBUTE_NONNULL(1);
+  void (*set_user_finalizer) (emacs_env *env, emacs_value arg,
+                              void (*fin) (void *) EMACS_NOEXCEPT)
+    EMACS_ATTRIBUTE_NONNULL(1);
+
+  /* Vector functions.  */
+  emacs_value (*vec_get) (emacs_env *env, emacs_value vector, ptrdiff_t index)
+    EMACS_ATTRIBUTE_NONNULL(1);
+
+  void (*vec_set) (emacs_env *env, emacs_value vector, ptrdiff_t index,
+                   emacs_value value)
+    EMACS_ATTRIBUTE_NONNULL(1);
+
+  ptrdiff_t (*vec_size) (emacs_env *env, emacs_value vector)
+    EMACS_ATTRIBUTE_NONNULL(1);
+
+  /* Returns whether a quit is pending.  */
+  bool (*should_quit) (emacs_env *env)
+    EMACS_ATTRIBUTE_NONNULL(1);
+
+  /* Processes pending input events and returns whether the module
+     function should quit.  */
+  enum emacs_process_input_result (*process_input) (emacs_env *env)
+    EMACS_ATTRIBUTE_NONNULL (1);
+
+  struct timespec (*extract_time) (emacs_env *env, emacs_value arg)
+    EMACS_ATTRIBUTE_NONNULL (1);
+
+  emacs_value (*make_time) (emacs_env *env, struct timespec time)
+    EMACS_ATTRIBUTE_NONNULL (1);
+
+  bool (*extract_big_integer) (emacs_env *env, emacs_value arg, int *sign,
+                               ptrdiff_t *count, emacs_limb_t *magnitude)
+    EMACS_ATTRIBUTE_NONNULL (1);
+
+  emacs_value (*make_big_integer) (emacs_env *env, int sign, ptrdiff_t count,
+                                   const emacs_limb_t *magnitude)
+    EMACS_ATTRIBUTE_NONNULL (1);
 
   void (*(*EMACS_ATTRIBUTE_NONNULL (1)
             get_function_finalizer) (emacs_env *env,
@@ -747,8 +922,12 @@
 
   /* Create a unibyte Lisp string from a string.  */
   emacs_value (*make_unibyte_string) (emacs_env *env,
-                                     const char *str, ptrdiff_t len)
+                                      const char *str, ptrdiff_t len)
     EMACS_ATTRIBUTE_NONNULL(1, 2);
+
+  /* Add module environment functions newly added in Emacs 29 here.
+     Before Emacs 29 is released, remove this comment and start
+     module-env-30.h on the master branch.  */
 };
 
 /* Every module should define a function as follows.  */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jinx-2.1/jinx-mod.c new/jinx-2.6/jinx-mod.c
--- old/jinx-2.1/jinx-mod.c     2025-04-04 13:23:21.000000000 +0200
+++ new/jinx-2.6/jinx-mod.c     2026-01-17 17:50:00.000000000 +0100
@@ -1,6 +1,6 @@
 /* Jinx bindings to libenchant
 
-Copyright (C) 2023-2025 Free Software Foundation, Inc.
+Copyright (C) 2023-2026 Free Software Foundation, Inc.
 
 GNU Emacs is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -145,19 +145,6 @@
     return Qnil;
 }
 
-static emacs_value jinx_wordchars(emacs_env* env, ptrdiff_t jinx_unused(nargs),
-                                  emacs_value args[], void* jinx_unused(data)) 
{
-    EnchantDict* dict = env->get_user_ptr(env, args[0]);
-    if (dict) {
-        // Enchant older than 2.3.1 does not enforce UTF-8 
<gh:rrthomas/enchant#278>
-        emacs_value str = jinx_str(env, 
enchant_dict_get_extra_word_characters(dict));
-        if (env->non_local_exit_check(env) == emacs_funcall_exit_return)
-            return str;
-        env->non_local_exit_clear(env);
-    }
-    return Qnil;
-}
-
 static emacs_value jinx_suggest(emacs_env* env, ptrdiff_t jinx_unused(nargs),
                                 emacs_value args[], void* jinx_unused(data)) {
     EnchantDict* dict = env->get_user_ptr(env, args[0]);
@@ -189,6 +176,5 @@
     jinx_defun(env, "jinx--mod-dict", 1, 1, jinx_dict);
     jinx_defun(env, "jinx--mod-langs", 0, 0, jinx_langs);
     jinx_defun(env, "jinx--mod-describe", 1, 1, jinx_describe);
-    jinx_defun(env, "jinx--mod-wordchars", 1, 1, jinx_wordchars);
     return 0;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/jinx-2.1/jinx.el new/jinx-2.6/jinx.el
--- old/jinx-2.1/jinx.el        2025-04-04 13:23:21.000000000 +0200
+++ new/jinx-2.6/jinx.el        2026-01-17 17:50:00.000000000 +0100
@@ -1,12 +1,12 @@
 ;;; jinx.el --- Enchanted Spell Checker -*- lexical-binding: t -*-
 
-;; Copyright (C) 2023-2025 Free Software Foundation, Inc.
+;; Copyright (C) 2023-2026 Free Software Foundation, Inc.
 
 ;; Author: Daniel Mendler <[email protected]>
 ;; Maintainer: Daniel Mendler <[email protected]>
 ;; Created: 2023
-;; Version: 2.1
-;; Package-Requires: ((emacs "28.1") (compat "30"))
+;; Version: 2.6
+;; Package-Requires: ((emacs "29.1") (compat "30"))
 ;; URL: https://github.com/minad/jinx
 ;; Keywords: convenience, text
 
@@ -71,6 +71,7 @@
   "Idle timer delay."
   :type 'float)
 
+;; TODO Replace with a universal variable in Emacs bug#80071
 (defcustom jinx-languages
   (replace-regexp-in-string
    "\\..*\\'" ""
@@ -154,6 +155,13 @@
 checking."
   :type '(alist :key-type symbol :value-type (choice symbol (repeat face))))
 
+(defcustom jinx-exclude-properties
+  '((t read-only))
+  "Alist of properties per major mode.
+These properties mark regions which should be excluded in spell
+checking."
+  :type '(alist :key-type symbol :value-type (choice symbol (repeat symbol))))
+
 (defcustom jinx-exclude-regexps
   '((emacs-lisp-mode "Package-Requires:.*$")
     (t "[A-Z]+\\>"         ;; Uppercase words
@@ -163,7 +171,10 @@
        "<?[-+_.~a-zA-Z][-+_.~:a-zA-Z0-9]*@[-.a-zA-Z0-9]+>?" ;; Email
        "\\(?:Local Variables\\|End\\):\\s-*$" ;; Local variable indicator
        "jinx-\\(?:languages\\|local-words\\):\\s-+.*$")) ;; Local variables
-  "List of excluded regexps per major mode."
+  "List of excluded regexps per major mode.
+The regexp must match at the beginning of the spell-checked word.
+Therefore `jinx-exclude-regexps' cannot be used to exclude larger parts
+of a buffer.  Write a custom predicate instead, see `jinx--predicates'."
   :type '(alist :key-type symbol :value-type (choice symbol (repeat regexp))))
 
 (defcustom jinx-suggestion-distance 3
@@ -174,9 +185,11 @@
   "Maximal number of suggestions shown in the context menu."
   :type 'natnum)
 
+;; TODO Replace with a universal variable in Emacs bug#80071
 (defvar-local jinx-local-words ""
   "File-local words, as a string separated by whitespace.")
 
+;; TODO Replace with a universal variable in Emacs bug#80071
 (defvar-local jinx-dir-local-words ""
   "Directory-local words, as a string separated by whitespace.")
 
@@ -278,8 +291,9 @@
   "Hooks which reschedule the spell checking timer, see `jinx--reschedule'.")
 
 (defvar jinx--predicates
-  (list #'jinx--face-ignored-p
-        #'jinx--regexp-ignored-p
+  (list #'jinx--face-excluded-p
+        #'jinx--regexp-excluded-p
+        #'jinx--property-excluded-p
         #'jinx--word-valid-p)
   "Predicate functions called at point with argument START.
 Predicate should return t if the word before point is valid.
@@ -288,8 +302,10 @@
 (defvar jinx--timer (timer-create)
   "Global timer to check pending regions.")
 
-(defvar jinx--base-syntax-table
+(defvar jinx--syntax-table
   (let ((st (make-syntax-table)))
+    (modify-syntax-entry ?' "w" st)
+    (modify-syntax-entry ?’ "w" st)
     (modify-syntax-entry ?$ "_" st)
     (modify-syntax-entry ?% "_" st)
     (modify-syntax-entry '(#xe000 . #xf8ff) "_" st)    ;; Priv. use area
@@ -301,13 +317,7 @@
     (modify-syntax-entry '(#x1cf00 . #x1d7ff) "_" st)  ;; Znamenny Musical - 
Math. Alpha.
     (modify-syntax-entry '(#x1ee00 . #x1fbff) "_" st)  ;; Arabic Math. - 
Legacy Computing
     st)
-  "Parent syntax table of `jinx--syntax-table'.")
-
-(defvar jinx--syntax-overrides
-  '((?' . "w")
-    (?’ . "w")
-    (?. . "."))
-  "Syntax table overrides used for `jinx--syntax-table'.")
+  "Syntax table used during checking.")
 
 (defvar jinx--select-keys
   "123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
@@ -323,6 +333,9 @@
 (defvar-local jinx--exclude-faces nil
   "List of excluded faces.")
 
+(defvar-local jinx--exclude-properties nil
+  "List of excluded properties.")
+
 (defvar-local jinx--include-faces nil
   "List of included faces.")
 
@@ -338,12 +351,6 @@
 (defvar jinx--dicts-hash (make-hash-table :test #'equal :weakness 'value)
   "Weak hash table of all loaded dictionaries.")
 
-(defvar-local jinx--syntax-table nil
-  "Syntax table used during checking.
-The table inherits from `jinx--base-syntax-table'.  The table is
-configured according to the word characters defined by the local
-dictionaries.  Afterwards `jinx--syntax-overrides' are applied.")
-
 (defvar-local jinx--session-words nil
   "List of words accepted in this session.")
 
@@ -351,13 +358,12 @@
 
 (defvar repeat-mode)
 (defvar jinx-mode)
-(declare-function jinx--mod-check nil)
-(declare-function jinx--mod-add nil)
-(declare-function jinx--mod-suggest nil)
-(declare-function jinx--mod-dict nil)
-(declare-function jinx--mod-describe nil)
-(declare-function jinx--mod-langs nil)
-(declare-function jinx--mod-wordchars nil)
+(declare-function jinx--mod-check "ext:jinx-mod.c")
+(declare-function jinx--mod-add "ext:jinx-mod.c")
+(declare-function jinx--mod-suggest "ext:jinx-mod.c")
+(declare-function jinx--mod-dict "ext:jinx-mod.c")
+(declare-function jinx--mod-describe "ext:jinx-mod.c")
+(declare-function jinx--mod-langs "ext:jinx-mod.c")
 
 ;;;; Overlay properties
 
@@ -372,18 +378,18 @@
 
 ;;;; Predicates
 
-(defun jinx--regexp-ignored-p (start)
-  "Return non-nil if word at START matches ignore regexps."
+(defun jinx--regexp-excluded-p (pos)
+  "Return non-nil if word at POS matches a regexp from `jinx-exclude-regexps'."
   (save-excursion
-    (goto-char start)
+    (goto-char pos)
     (when (and jinx--exclude-regexp (looking-at-p jinx--exclude-regexp))
       (save-match-data
         (looking-at jinx--exclude-regexp)
         (match-end 0)))))
 
-(defun jinx--face-ignored-p (start)
-  "Return non-nil if face at START of word is ignored."
-  (let ((face (get-text-property start 'face)))
+(defun jinx--face-excluded-p (pos)
+  "Return non-nil if face at POS is excluded via `jinx-exclude-faces'."
+  (let ((face (get-text-property pos 'face)))
     (or
      (and jinx--include-faces
           (if (listp face)
@@ -394,9 +400,18 @@
               (cl-loop for f in face thereis (memq f jinx--exclude-faces))
             (memq face jinx--exclude-faces))))))
 
+(defun jinx--property-excluded-p (pos)
+  "Return non-nil if property at POS is excluded via 
`jinx-exclude-properties'."
+  (cl-loop for prop in jinx--exclude-properties
+           thereis (get-char-property pos prop)))
+
+(defun jinx--read-only-p (pos)
+  "Return non-nil if POS is read-only."
+  (get-text-property pos 'read-only))
+
 (defun jinx--word-valid-p (word)
   "Return non-nil if WORD is valid.
-WORD can also be a start position."
+WORD can also be a position."
   (unless (stringp word)
     (setq word (buffer-substring-no-properties word (point))))
   (or (member word jinx--session-words)
@@ -532,8 +547,8 @@
         (with-delayed-message (1 "Checking...")
           (jinx--check-region start end))
         (jinx--get-overlays start end visible))
-      (user-error (if visible "No misspelled word in visible text"
-                    "No misspelled word in whole buffer"))))
+      (user-error "No misspelled word in %s"
+                  (if visible "visible text" (format "buffer `%s'" 
(buffer-name))))))
 
 (defun jinx--delete-overlays (start end)
   "Delete overlays between START and END."
@@ -577,8 +592,8 @@
   (timer-set-function jinx--timer nil)
   (dolist (frame (frame-list))
     (dolist (win (window-list frame 'no-miniwindow))
-      (when-let ((buffer (window-buffer win))
-                 ((buffer-local-value 'jinx-mode buffer)))
+      (when-let* ((buffer (window-buffer win))
+                  ((buffer-local-value 'jinx-mode buffer)))
         (with-current-buffer buffer
           (jinx--check-pending (window-start win) (window-end win)))))))
 
@@ -613,23 +628,27 @@
                (default-directory (file-name-directory
                                    (or (locate-library c-name t)
                                        (error "Jinx: %s not found" c-name))))
-               (command
-                `(,cc ,@jinx--compile-flags "-o" ,mod-name ,c-name
-                  ,@(split-string-and-unquote
-                     (condition-case nil
-                         (car (process-lines "pkg-config" "--cflags" "--libs" 
"enchant-2"))
-                       (error "-I/usr/include/enchant-2 
-I/usr/local/include/enchant-2 -L/usr/local/lib -lenchant-2"))))))
+               (command nil)
+               (inhibit-read-only t))
           (with-current-buffer (get-buffer-create "*jinx module compilation*")
-            (let ((inhibit-read-only t))
-              (erase-buffer)
-              (compilation-mode)
-              (insert (string-join command " ") "\n")
-              (if (equal 0 (apply #'call-process (car command) nil 
(current-buffer) t (cdr command)))
-                  (insert (message "Jinx: %s compiled successfully" mod-name))
-                (let ((msg (format "Jinx: Compilation of %s failed" mod-name)))
-                  (insert msg)
-                  (pop-to-buffer (current-buffer))
-                  (error msg)))))
+            (erase-buffer)
+            (compilation-mode)
+            (insert (format "Jinx: Compiling %s\n" mod-name))
+            (setq command
+                  `(,cc ,@jinx--compile-flags "-o" ,mod-name ,c-name
+                        ,@(split-string-and-unquote
+                           (condition-case nil
+                               (car (process-lines "pkg-config" "--cflags" 
"--libs" "enchant-2"))
+                             (error
+                              (insert "Jinx: pkgconf or pkg-config not 
found\n")
+                              "-I/usr/include/enchant-2 
-I/usr/local/include/enchant-2 -L/usr/local/lib -lenchant-2")))))
+            (insert (string-join command " ") "\n")
+            (if (equal 0 (apply #'call-process (car command) nil 
(current-buffer) t (cdr command)))
+                (insert (message "Jinx: %s compiled successfully" mod-name))
+              (let ((msg (format "Jinx: Compilation of %s failed" mod-name)))
+                (insert msg)
+                (pop-to-buffer (current-buffer))
+                (error msg))))
           (setq mod-file (expand-file-name mod-name))))
       ;; Initialize Mac spell checker to avoid dead lock (gh:minad/jinx#91).
       (when (and (eq window-system 'mac) (fboundp 'mac-do-applescript))
@@ -642,7 +661,7 @@
   "Guard BODY during correction loop."
   `(cl-letf (((symbol-function #'jinx--timer-handler) #'ignore) ;; Inhibit
              (repeat-mode nil)) ;; No repeating of jinx-next and jinx-previous
-     (unless jinx-mode (jinx-mode 1))
+     (unless jinx-mode (jinx-mode))
      ,@body))
 
 (defun jinx--invisible-open-temporarily ()
@@ -652,7 +671,7 @@
     (dolist (ov (overlays-in (pos-bol) (pos-eol)) restore)
       (let ((inv (overlay-get ov 'invisible)))
         (when (and (invisible-p inv) (overlay-get ov 'isearch-open-invisible))
-          (push (if-let ((fun (overlay-get ov 
'isearch-open-invisible-temporary)))
+          (push (if-let* ((fun (overlay-get ov 
'isearch-open-invisible-temporary)))
                     (progn
                       (funcall fun ov nil)
                       (lambda () (funcall fun ov t)))
@@ -664,9 +683,9 @@
   "Open overlays which hide the current line.
 See `isearch-open-necessary-overlays' and `isearch-open-overlay-temporary'."
   (dolist (ov (overlays-in (pos-bol) (pos-eol)))
-    (when-let (fun (overlay-get ov 'isearch-open-invisible))
-      (when (invisible-p (overlay-get ov 'invisible))
-        (funcall fun ov)))))
+    (when-let* ((fun (overlay-get ov 'isearch-open-invisible))
+                ((invisible-p (overlay-get ov 'invisible))))
+      (funcall fun ov))))
 
 (defun jinx--correct-highlight (overlay fun)
   "Highlight and show OVERLAY during FUN."
@@ -694,35 +713,29 @@
 
 (defun jinx--correct-setup ()
   "Setup minibuffer for correction."
-  (use-local-map (make-composed-keymap (list jinx-correct-map) 
(current-local-map)))
-  ;; TODO Use `eager-display' on Emacs 31
-  (when (and (eq completing-read-function #'completing-read-default)
-             (not (bound-and-true-p vertico-mode))
-             (not (bound-and-true-p icomplete-mode)))
-    (let ((message-log-max nil)
-          (inhibit-message t))
-      (minibuffer-completion-help))))
+  (use-local-map
+   (make-composed-keymap (list jinx-correct-map) (current-local-map))))
 
-(defun jinx--add-suggestion (list ht word group)
+(defun jinx--add-suggestion (list ht word group &optional suffix)
   "Add suggestion WORD to LIST and HT.
-The word will be associated with GROUP and get a prefix key."
+The suggestion will get a prefix key.  A GROUP and a SUFFIX property are
+optionally added."
   (unless (gethash word ht)
     (add-text-properties
      0 (length word)
-     (list 'jinx--group group
-           'jinx--prefix
-           (let ((idx (1+ (hash-table-count ht))))
-             (cond
-              ((< idx 10)
-               (format #("%d " 0 3 (face jinx-key))
-                       idx))
-              ((< (- idx 10) (length jinx--select-keys))
-               (format #("0%c " 0 4 (face jinx-key))
-                       (aref jinx--select-keys (- idx 10)))))))
+     `( jinx--group ,group
+        jinx--prefix ,(let ((idx (1+ (hash-table-count ht))))
+                        (cond
+                         ((< idx 10)
+                          (format #("%d " 0 3 (face jinx-key))
+                                  idx))
+                         ((< (- idx 10) (length jinx--select-keys))
+                          (format #("0%c " 0 4 (face jinx-key))
+                                  (aref jinx--select-keys (- idx 10))))))
+        jinx--suffix ,suffix)
      word)
-    (push word list)
-    (puthash word t ht))
-  list)
+    (push word (car list))
+    (puthash word t ht)))
 
 (defun jinx--session-suggestions (word)
   "Retrieve suggestions for WORD from session."
@@ -736,15 +749,15 @@
 (defun jinx--correct-suggestions (word)
   "Retrieve suggestions for WORD from all dictionaries."
   (let ((ht (make-hash-table :test #'equal))
-        (list nil))
+        (list (cons nil nil)))
     (dolist (dict jinx--dicts)
       (let* ((desc (jinx--mod-describe dict))
              (group (format "Suggestions from dictionary β€˜%s’ - %s"
                             (car desc) (cdr desc))))
         (dolist (w (jinx--mod-suggest dict word))
-          (setq list (jinx--add-suggestion list ht w group)))))
+          (jinx--add-suggestion list ht w group))))
     (dolist (w (jinx--session-suggestions word))
-      (setq list (jinx--add-suggestion list ht w "Suggestions from session")))
+      (jinx--add-suggestion list ht w "Suggestions from session"))
     (cl-loop
      for (key . fun) in jinx--save-keys
      for actions = (funcall fun nil key word) do
@@ -756,12 +769,9 @@
                            'face 'jinx-save 'rear-nonsticky t)
       for a2 = (format #(" [%s]" 0 5 (face jinx-annotation)) a)
       do (cl-loop
-          for w2 in (delete-consecutive-dups (list w (downcase w))) do
-          (push (propertize (concat k2 w2)
-                            'jinx--group "Accept and save"
-                            'jinx--suffix a2)
-                list))))
-    (nreverse list)))
+          for w2 in (list w (downcase w)) do
+          (jinx--add-suggestion list ht (concat k2 w2) "Accept and save" a2))))
+    (nreverse (car list))))
 
 (defun jinx--correct-affixation (cands)
   "Affixate CANDS during completion."
@@ -770,12 +780,6 @@
                  (or (get-text-property 0 'jinx--prefix cand) "")
                  (or (get-text-property 0 'jinx--suffix cand) ""))))
 
-(defun jinx--correct-annotation (cand)
-  "Annotate CAND during completion."
-  (if-let ((prefix (get-text-property 0 'jinx--prefix cand)))
-      (format #(" (%s)" 0 5 (face jinx-key)) (string-trim prefix))
-    (get-text-property 0 'jinx--suffix cand)))
-
 (defun jinx--group (word transform)
   "Group WORD during completion, TRANSFORM candidate if non-nil."
   (if transform
@@ -808,11 +812,11 @@
                        (jinx--table-with-metadata
                         (jinx--correct-suggestions word)
                         `((category . jinx)
+                          (eager-display . t)
                           (display-sort-function . ,#'identity)
                           (cycle-sort-function . ,#'identity)
                           (group-function . ,#'jinx--group)
-                          (affixation-function . ,#'jinx--correct-affixation)
-                          (annotation-function . ,#'jinx--correct-annotation)))
+                          (affixation-function . ,#'jinx--correct-affixation)))
                        nil nil initial t word)
                       word)))))
            (len (length choice)))
@@ -827,8 +831,8 @@
 
 (defun jinx--correct-replace (overlay word)
   "Replace OVERLAY with WORD."
-  (when-let ((start (overlay-start overlay))
-             (end (overlay-end overlay)))
+  (when-let* ((start (overlay-start overlay))
+              (end (overlay-end overlay)))
     (undo-boundary)
     (delete-overlay overlay)
     (goto-char end)
@@ -837,19 +841,19 @@
 
 (defun jinx--correct-menu (&rest _)
   "Return popup mouse menu to correct misspelling."
-  (when-let ((posn (event-start last-input-event))
-             (pt (posn-point posn))
-             (ov (car (jinx--get-overlays pt pt t))))
+  (when-let* ((posn (event-start last-input-event))
+              (pt (posn-point posn))
+              (ov (car (jinx--get-overlays pt pt t))))
     (let ((menu nil)
           (word (buffer-substring-no-properties
                  (overlay-start ov) (overlay-end ov))))
       (dolist (dict jinx--dicts)
-        (when-let ((desc (jinx--mod-describe dict))
-                   (suggestions (jinx--mod-suggest dict word)))
+        (when-let* ((desc (jinx--mod-describe dict))
+                    (suggestions (jinx--mod-suggest dict word)))
           (push `[,(concat "── " (car desc) " ─ " (cdr desc) " ──") :active 
nil] menu)
           (cl-loop for w in suggestions repeat jinx-menu-suggestions do
                    (push `[,w (jinx--correct-replace ,ov ,w)] menu))))
-      (when-let ((suggestions (jinx--session-suggestions word)))
+      (when-let* ((suggestions (jinx--session-suggestions word)))
         (push ["── Session ──" :active nil] menu)
         (cl-loop for w in suggestions repeat jinx-menu-suggestions do
           (push `[,w (jinx--correct-replace ,ov ,w)] menu)))
@@ -867,20 +871,14 @@
 
 (defun jinx--load-dicts ()
   "Load dictionaries and setup syntax table."
-  (setq jinx--dicts (cl-loop for lang in (split-string jinx-languages)
-                             ;; Keep a weak reference to loaded dictionaries.
-                             ;; See <gh:rrthomas/enchant#402>.
-                             for dict = (with-memoization (gethash lang 
jinx--dicts-hash)
-                                          (jinx--mod-dict lang))
-                             if dict collect dict)
-        jinx--syntax-table (make-syntax-table jinx--base-syntax-table))
-  (unless jinx--dicts
-    (message "Jinx: No dictionaries available for %S" jinx-languages))
-  (dolist (dict jinx--dicts)
-    (cl-loop for c across (jinx--mod-wordchars dict) do
-             (modify-syntax-entry c "w" jinx--syntax-table)))
-  (cl-loop for (k . v) in jinx--syntax-overrides do
-           (modify-syntax-entry k v jinx--syntax-table)))
+  (unless (setq jinx--dicts
+                (cl-loop for lang in (split-string jinx-languages)
+                         ;; Keep a weak reference to loaded dictionaries.
+                         ;; See <gh:rrthomas/enchant#402>.
+                         for dict = (with-memoization (gethash lang 
jinx--dicts-hash)
+                                      (jinx--mod-dict lang))
+                         if dict collect dict))
+    (message "Jinx: No dictionaries available for %S" jinx-languages)))
 
 (defun jinx--bounds-of-word ()
   "Return bounds of word at point using `jinx--syntax-table'."
@@ -953,11 +951,12 @@
         (jinx--add-local-word 'jinx-dir-local-words word)
         (let ((default-directory
                (or (locate-dominating-file default-directory ".dir-locals.el")
-                   (when-let (proj (project-current))
+                   (when-let* ((proj (project-current)))
                      (declare-function project-root "project")
                      (project-root proj))
                    default-directory)))
-          (add-dir-local-variable nil 'jinx-dir-local-words 
jinx-dir-local-words)))
+          (save-window-excursion
+            (add-dir-local-variable nil 'jinx-dir-local-words 
jinx-dir-local-words))))
     (list key word "Directory")))
 
 (defun jinx--save-session (save key word)
@@ -978,7 +977,7 @@
 GLOBAL is non-nil, the languages are changed globally for all
 buffers.  See also the variable `jinx-languages'."
   (interactive (list (jinx--read-languages) current-prefix-arg))
-  (unless jinx-mode (jinx-mode 1))
+  (unless jinx-mode (jinx-mode))
   (cond
    (global
     (kill-local-variable 'jinx-languages)
@@ -999,7 +998,7 @@
 (defun jinx-correct-all (&optional only-check)
   "Correct all misspelled words in the buffer.
 With prefix argument ONLY-CHECK, only check the buffer and highlight all
-misspellings, but do not open the correction UI."
+misspelled words, but do not open the correction UI."
   (interactive "*P")
   (jinx--correct-guard
    (let* ((overlays (jinx--force-overlays (or (use-region-beginning) 
(point-min))
@@ -1007,12 +1006,14 @@
                                           :check t))
           (count (length overlays))
           (idx 0))
-     (unless only-check
+     (if only-check
+         (message "%d misspelled word%s in buffer `%s'"
+                  count (if (= count 1) "" "s") (buffer-name))
        (deactivate-mark)
        (push-mark)
        (while-let ((ov (nth idx overlays)))
-         (if-let (((overlay-buffer ov))
-                  (skip (jinx--correct-overlay ov :info (format " (%d of %d)" 
(1+ idx) count))))
+         (if-let* (((overlay-buffer ov))
+                   (skip (jinx--correct-overlay ov :info (format " (%d of %d)" 
(1+ idx) count))))
              (setq idx (mod (+ idx skip) count))
            (cl-incf idx)))))))
 
@@ -1026,9 +1027,9 @@
             (count (length overlays))
             (idx 0))
        ;; Not using `while-let' is intentional here.
-       (while (when-let ((ov (nth idx overlays)))
+       (while (when-let* ((ov (nth idx overlays)))
                 (if (overlay-buffer ov)
-                    (when-let ((skip (jinx--correct-overlay ov)))
+                    (when-let* ((skip (jinx--correct-overlay ov)))
                       (setq idx (mod (+ idx skip) count)))
                   (cl-incf idx)))))))) ;; Skip deleted overlay
 
@@ -1048,7 +1049,7 @@
                              (jinx--correct-overlay ov :initial initial)
                          (delete-overlay ov)))))
        (forward-to-word skip)
-       (when-let ((bounds (jinx--bounds-of-word)))
+       (when-let* ((bounds (jinx--bounds-of-word)))
          (setf (cons start end) bounds
                initial nil))))))
 
@@ -1062,15 +1063,11 @@
     is 4, corresponding to \\[universal-argument] pressed once,
     correct all misspelled words.
   - `jinx-correct-word': If prefix ARG is 16, corresponding to
-    \\[universal-argument] pressed twice, correct word before point.
-  - If prefix ARG is 64, corresponding to \\[universal-argument] pressed
-    three times, check the whole buffer, but do not open the correction
-    UI."
+    \\[universal-argument] pressed twice, correct word before point."
   (interactive "*P")
   (pcase arg
     ('nil (if (use-region-p) (jinx-correct-all) (jinx-correct-nearest)))
     ('(16) (jinx-correct-word))
-    ('(64) (jinx-correct-all t))
     (_ (jinx-correct-all))))
 
 (defun jinx-correct-select ()
@@ -1088,9 +1085,10 @@
     (insert word)
     (exit-minibuffer)))
 
-(defun jinx-next (n)
+(defun jinx-next (&optional n)
   "Go to to Nth next misspelled word."
   (interactive "p" jinx-mode)
+  (unless n (setq n 1))
   (unless (= n 0)
     (if (minibufferp)
         (throw 'jinx--goto n)
@@ -1100,10 +1098,10 @@
         (goto-char (overlay-end (nth (mod n (length ov)) ov)))
         (jinx--invisible-open-permanently)))))
 
-(defun jinx-previous (n)
+(defun jinx-previous (&optional n)
   "Go to to Nth previous misspelled word."
   (interactive "p" jinx-mode)
-  (jinx-next (- n)))
+  (jinx-next (- (or n 1))))
 
 ;;;###autoload
 (define-minor-mode jinx-mode
@@ -1124,11 +1122,12 @@
       (hack-local-variables 'ignore-mode))
     (jinx--get-org-language)
     (setq jinx--exclude-regexp
-          (when-let ((regexps (jinx--mode-list jinx-exclude-regexps)))
+          (when-let* ((regexps (jinx--mode-list jinx-exclude-regexps)))
             (mapconcat (lambda (r) (format "\\(?:%s\\)" r))
                        regexps "\\|"))
           jinx--include-faces (jinx--mode-list jinx-include-faces)
           jinx--exclude-faces (jinx--mode-list jinx-exclude-faces)
+          jinx--exclude-properties (jinx--mode-list jinx-exclude-properties)
           jinx--camel (or (eq jinx-camel-modes t)
                           (seq-some #'derived-mode-p jinx-camel-modes))
           jinx--session-words (nconc (split-string jinx-dir-local-words)
@@ -1147,33 +1146,19 @@
     (jit-lock-unregister #'jinx--mark-pending)
     (jinx--cleanup))))
 
-;; TODO use `:predicate' on Emacs 29
-(defcustom global-jinx-modes '(text-mode prog-mode conf-mode)
-  "List of modes where Jinx should be enabled.
-The variable can either be t, nil or a list of t, nil, mode
-symbols or elements of the form (not modes)."
-  :type '(repeat sexp))
-
 ;;;###autoload
 (define-globalized-minor-mode global-jinx-mode
   jinx-mode jinx--on
-  :group 'jinx)
+  :group 'jinx
+  :predicate '(text-mode prog-mode conf-mode))
 
 (defun jinx--on ()
   "Turn `jinx-mode' on."
-  (when (and (not (or noninteractive
-                      buffer-read-only
-                      (buffer-base-buffer) ;; Do not enable in indirect buffers
-                      (eq (aref (buffer-name) 0) ?\s)))
-             ;; TODO use `:predicate' on Emacs 29
-             (or (eq t global-jinx-modes)
-                 (eq t (cl-loop for p in global-jinx-modes thereis
-                                (pcase-exhaustive p
-                                  ('t t)
-                                  ('nil 0)
-                                  ((pred symbolp) (and (derived-mode-p p) t))
-                                  (`(not . ,m) (and (seq-some #'derived-mode-p 
m) 0)))))))
-    (jinx-mode 1)))
+  (unless (or noninteractive
+              buffer-read-only
+              (buffer-base-buffer) ;; Do not enable in indirect buffers
+              (eq (aref (buffer-name) 0) ?\s))
+    (jinx-mode)))
 
 (provide 'jinx)
 ;;; jinx.el ends here

++++++ jinx.obsinfo ++++++
--- /var/tmp/diff_new_pack.bA7GUJ/_old  2026-02-04 21:08:54.239652483 +0100
+++ /var/tmp/diff_new_pack.bA7GUJ/_new  2026-02-04 21:08:54.255653153 +0100
@@ -1,5 +1,5 @@
 name: jinx
-version: 2.1
-mtime: 1743765801
-commit: 84fc35aedddfbf24de144245fe9d1c8a61852f7a
+version: 2.6
+mtime: 1768668600
+commit: b412673dec759131fe0abb346998b55225fbe771
 

Reply via email to