From 8a20b1712feaf7e3db7fc2ce04bb89c6fb171e32 Mon Sep 17 00:00:00 2001 From: Bob Yantosca Date: Thu, 30 Apr 2026 11:34:27 -0400 Subject: [PATCH 1/8] Fixed emacs font-lock issues in site-lisp/kpp.el site-lisp/kpp.el - Linted this file with Claude AI and resolved several issues that were preventing proper font-lock rendering on newer versions of emacs. CHANGELOG.md - Updated accordingly Signed-off-by: Bob Yantosca --- CHANGELOG.md | 4 + site-lisp/kpp.el | 363 ++++++++++++++++++++++++++++++++++------------- 2 files changed, 266 insertions(+), 101 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aef3332..87502f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] - TBD +### Fixed +- Fixed several emacs font-lock issues in `site-lisp/kpp.el` + ## [3.4.0] - 2026-04-29 ### Added - Added `Rodas3_1` integration method (with updated coefficents by @msl3v) to `rosenbrock_autoreduce.f90`, `rosenbrock.{c,f90,m}`, `rosenbrock_adj.{c,f90}`, `rosenbrock_tlm.f90` diff --git a/site-lisp/kpp.el b/site-lisp/kpp.el index c7afc45..8e8c066 100644 --- a/site-lisp/kpp.el +++ b/site-lisp/kpp.el @@ -1,130 +1,291 @@ -;; kpp.el --- kpp mode for GNU Emacs -;; (c) Rolf Sander +;;; kpp.el --- Major mode for KPP (Kinetic PreProcessor) files -*- lexical-binding: t; -*- -;; To activate it, copy kpp.el to a place where emacs can find it and -;; then add "(require 'kpp)" to your .emacs startup file. +;; Copyright (C) 2005 Rolf Sander -;; Known problem: -;; ":" inside comments between reaction products confuses font-lock +;; Author: Rolf Sander +;; Maintainer: Rolf Sander +;; Version: 1.2 +;; Keywords: languages, kpp, chemistry ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2 of the License, or ;; (at your option) any later version. +;; ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. -;; auto-start kpp-mode when loading a *.def, *.eqn, *.kpp, or *.spc file -(setq auto-mode-alist - (cons '("\\.def\\'" . kpp-mode) auto-mode-alist)) -(setq auto-mode-alist - (cons '("\\.eqn\\'" . kpp-mode) auto-mode-alist)) -(setq auto-mode-alist - (cons '("\\.kpp\\'" . kpp-mode) auto-mode-alist)) -(setq auto-mode-alist - (cons '("\\.spc\\'" . kpp-mode) auto-mode-alist)) - -;; Turn on font-lock-mode for KPP -(add-hook 'kpp-mode-hook 'font-lock-mode) - -(setq kpp-font-lock-keywords - (list - '("^\\([^=\n]*=[^:\n]*\\):[^;\n]*;" 1 font-lock-constant-face) ; reaction - ;; alternatively, use another color for rate constant: - ;; '("^\\([^=\n]*=[^:\n]*\\):\\([^;\n]*\\);" - ;; (1 font-lock-constant-face) (2 font-lock-keyword-face)) - '("<[A-z0-9_#]+>" 0 font-lock-variable-name-face t) ; equation tag - '("{[^}\n]*}" 0 font-lock-comment-face t) ; comment - '("!.*" 0 font-lock-comment-face t) ; f90 comment - '("{@[^}]+}" 0 font-lock-doc-face t) ; alternative LaTeX text - '("{$[^}]+}" 0 font-lock-string-face t) ; alternative LaTeX text - '("{&[^}]+}" 0 font-lock-builtin-face t) ; BibTeX reference - '("{%[A-z0-9#]+}" 0 font-lock-type-face t) ; marker - ;; KPP sections (Tab. 3 in thesis), commands (Tab. 13 in thesis), and - ;; fragments (Tab. 17 in thesis) - (cons (concat - "\\(#ATOMS\\|#AUTOREDUCE\\|#CHECKALL\\|#CHECK\\|#DECLARE" - "\\|#DEFFIX\\|#DEFVAR\\|#DOUBLE\\|#DRIVER\\|#DUMMYINDEX" - "\\|#ENDINLINE\\|#EQNTAGS\\|#EQUATIONS\\|#FAMILIES\\|#FUNCTION" - "\\|#GRAPH\\|#HESSIAN\\|#INCLUDE\\|#INITVALUES\\|#INLINE\\|#INTEGRATOR" - "\\|#INTFILE\\|#JACOBIAN\\|#LANGUAGE\\|#LOOKATALL\\|#LOOKAT" - "\\|#MEX\\|#MINVERSION\\|#MODEL\\|#MONITOR\\|#REORDER" - "\\|#SETFIX\\|#SETVAR\\|#STOCHASTIC\\|#STOICMAT\\|#UPPERCASEF90" - "\\|#WRITE_ATM\\|#WRITE_MAT\\|#WRITE_SPC" - ) 'font-lock-keyword-face) - '("^//.*" 0 font-lock-comment-face t) ; comment - ) -) - -; comment a region (adopted from wave-comment-region) - -(defvar kpp-comment-region "// " - "*String inserted by \\[kpp-comment-region] at start of each line in region.") +;;; Commentary: +;; +;; This package provides a major mode for editing KPP (Kinetic PreProcessor) +;; files. KPP is a software tool that assists in developing and solving +;; chemical kinetics problems. +;; +;; Installation: +;; Copy kpp.el to a directory in `load-path' and add +;; (require 'kpp) +;; to your Emacs init file (~/.emacs or ~/.emacs.d/init.el). +;; +;; File extensions automatically associated with kpp-mode: .kpp, .eqn +;; +;; Note on .def and .spc extensions: +;; These are intentionally NOT registered by default because they are used +;; by many other file types (C preprocessor, Win32 module definitions, +;; SPICE netlists, R packages, etc.). Uncomment the relevant lines near +;; the bottom of this file if you want them. +;; +;; Known issue: +;; ":" inside KPP inline comments (between reaction products and the rate +;; constant) may confuse font-lock. + +;;; Code: + +;; --------------------------------------------------------------------------- +;; Customization group +;; --------------------------------------------------------------------------- + +(defgroup kpp nil + "Major mode for editing KPP (Kinetic PreProcessor) files." + :group 'languages + :prefix "kpp-") + +;; --------------------------------------------------------------------------- +;; User-configurable variables +;; --------------------------------------------------------------------------- + +(defcustom kpp-comment-prefix "// " + ;; Fix #10: renamed from `kpp-comment-region' to avoid collision with the + ;; function of the same name. + ;; Fix #13: changed from `defvar' with leading `*' to `defcustom'. + "String inserted by \\[kpp-comment-region] at the start of each line." + :type 'string + :group 'kpp) + +;; --------------------------------------------------------------------------- +;; Faces +;; --------------------------------------------------------------------------- + +(defface kpp-doc-face + ;; Fix #6: `font-lock-doc-face' was introduced in Emacs 22. Defining our + ;; own face that *inherits* from it gives graceful degradation on older + ;; Emacs versions while using the correct face on modern ones. + '((t (:inherit font-lock-doc-face))) + "Face for KPP LaTeX documentation strings, e.g. {@...}. +Inherits from `font-lock-doc-face'; compatible with Emacs 21+." + :group 'kpp) + +;; --------------------------------------------------------------------------- +;; Syntax table (defined once at load time; shared by all kpp buffers) +;; --------------------------------------------------------------------------- + +(defvar kpp-mode-syntax-table + ;; Fix #11: was recreated (and re-allocated) inside `kpp-mode' on every + ;; buffer visit. + (let ((st (copy-syntax-table))) + (modify-syntax-entry ?_ "w" st) ; underscore is part of a word + st) + "Syntax table for `kpp-mode'.") + +;; --------------------------------------------------------------------------- +;; Font-lock keyword specification +;; --------------------------------------------------------------------------- + +(defconst kpp-font-lock-keywords + ;; Fix #9: was a bare `setq' on an unbound symbol; `defconst' documents + ;; intent and prevents inadvertent modification. + (list + ;; Reaction: "species = products : rate_constant ;" + ;; Highlight the LHS + products (group 1) as a constant. + '("^\\([^=\n]*=[^:\n]*\\):[^;\n]*;" 1 font-lock-constant-face) + + ;; Equation tag, e.g. or + ;; Fix #2: [A-z] spans ASCII 65-122 and accidentally includes the + ;; characters [\]^_` (91-96). Use [A-Za-z] instead. + '("<[A-Za-z0-9_#]+>" 0 font-lock-variable-name-face t) + + ;; Curly-brace block comment: {comment text} + '("{[^}\n]*}" 0 font-lock-comment-face t) + + ;; Fortran-90 / KPP inline comment: ! comment to end of line + '("!.*" 0 font-lock-comment-face t) + + ;; {@...} – alternative LaTeX text (documentation) + ;; Uses kpp-doc-face rather than font-lock-doc-face directly; see Fix #6. + '("{@[^}]+}" 0 kpp-doc-face t) + + ;; {$...} – alternative LaTeX math text + ;; Fix: the original "{$[^}]+}" relied on $ being treated as literal + ;; when not at end of regexp. Using \\$ is explicit and unambiguous. + '("{\\$[^}]+}" 0 font-lock-string-face t) + + ;; {&...} – BibTeX reference + '("{&[^}]+}" 0 font-lock-builtin-face t) + + ;; {%...} – marker tag, e.g. {%TrG} + ;; Fix #2: same [A-z] → [A-Za-z] correction as above. + '("{%[A-Za-z0-9#]+}" 0 font-lock-type-face t) + + ;; KPP sections, commands, and fragments + ;; (Tables 3, 13, and 17 in the KPP manual / thesis) + ;; + ;; ORDERING RULE: in Emacs regex alternation (\|) the leftmost match + ;; wins. Any keyword that is a strict prefix of another must therefore + ;; appear AFTER the longer form: + ;; + ;; Pair Original order Fixed order + ;; #CHECK / #CHECKALL CHECKALL first ✓ already correct + ;; #LOOKAT / #LOOKATALL LOOKATALL first ✓ already correct + ;; #TRANSPORT / …ALL …ALL first ✓ already correct + ;; #USE / #USES USE first ✗ BUG → fixed below (#Fix 3) + ;; + ;; \> (end-of-word boundary) prevents a short keyword from matching + ;; as a prefix of an unknown longer token. + (cons (concat + "\\(" + "#ATOMS\\|#AUTOREDUCE" + "\\|#CHECKALL\\|#CHECK" + "\\|#DEFFIX\\|#DEFRAD\\|#DEFVAR" + "\\|#DOUBLE\\|#DRIVER\\|#DUMMYINDEX" + "\\|#ENDINLINE\\|#EQNTAGS\\|#EQUATIONS" + "\\|#FAMILIES\\|#FUNCTION\\|#GRAPH" + "\\|#HESSIAN" + "\\|#INCLUDE\\|#INITVALUES\\|#INITIALIZE\\|#INLINE" + "\\|#INTEGRATOR\\|#INTFILE" + "\\|#JACOBIAN" + "\\|#LANGUAGE" + "\\|#LOOKATALL\\|#LOOKAT\\|#LUMP" + "\\|#MEX\\|#MINVERSION\\|#MODEL\\|#MONITOR" + "\\|#REORDER\\|#RUN" + "\\|#SETFIX\\|#SETRAD\\|#SETVAR" + "\\|#SPARSEDATA\\|#STOCHASTIC\\|#STOICMAT" + "\\|#TRANSPORTALL\\|#TRANSPORT" + "\\|#UPPERCASEF90" + "\\|#USES\\|#USE" ; Fix #3: #USES before #USE + "\\|#WRITE_ATM\\|#WRITE_MAT\\|#WRITE_OPT\\|#WRITE_SPC" + "\\|#XGRID\\|#YGRID\\|#ZGRID" + "\\)\\>") + 'font-lock-keyword-face) + + ;; C++-style line comment: // comment + '("^//.*" 0 font-lock-comment-face t)) + "Font-lock keyword specification for `kpp-mode'.") + +;; --------------------------------------------------------------------------- +;; Keymap +;; (defined before `define-derived-mode'; the macro detects and reuses it) +;; --------------------------------------------------------------------------- + +(defvar kpp-mode-map + (let ((map (make-sparse-keymap))) + ;; C-c ; → comment / uncomment region + (define-key map "\C-c;" #'kpp-comment-region) + ;; Fix #14: original hard-coded 8 spaces and had no docstring. + ;; Using `tab-width' respects the user/project preference and updates + ;; automatically when `tab-width' is changed locally. + (define-key map (kbd "TAB") + (lambda () + "Insert `tab-width' spaces (never a literal TAB character)." + (interactive) + (insert-char ?\s tab-width))) + map) + "Keymap for `kpp-mode'.") + +;; --------------------------------------------------------------------------- +;; Comment / uncomment a region (adapted from wave-comment-region) +;; --------------------------------------------------------------------------- (defun kpp-comment-region (beg-region end-region arg) - "Comments every line in the region. -Puts kpp-comment-region at the beginning of every line in the region. -BEG-REGION and END-REGION are args which specify the region boundaries. -With non-nil ARG, uncomments the region." + ;; Fix #10: the variable formerly named `kpp-comment-region' clashed with + ;; this function name. The variable is now `kpp-comment-prefix'. + "Comment every line in the region. +Inserts `kpp-comment-prefix' at the start of every line between +BEG-REGION and END-REGION. With non-nil ARG, uncomment instead." (interactive "*r\nP") - (let ((end-region-mark (make-marker)) (save-point (point-marker))) + (let ((end-region-mark (make-marker)) + (save-point (point-marker))) (set-marker end-region-mark end-region) (goto-char beg-region) (beginning-of-line) - (if (not arg) ;comment the region - (progn (insert kpp-comment-region) - (while (and (= (forward-line 1) 0) - (< (point) end-region-mark)) - (insert kpp-comment-region))) - (let ((com (regexp-quote kpp-comment-region))) ;uncomment the region - (if (looking-at com) - (delete-region (point) (match-end 0))) - (while (and (= (forward-line 1) 0) - (< (point) end-region-mark)) - (if (looking-at com) - (delete-region (point) (match-end 0)))))) + (if (not arg) + ;; --- comment the region --- + (progn + (insert kpp-comment-prefix) + (while (and (= (forward-line 1) 0) + (< (point) end-region-mark)) + (insert kpp-comment-prefix))) + ;; --- uncomment the region --- + (let ((com (regexp-quote kpp-comment-prefix))) + (when (looking-at com) + (delete-region (point) (match-end 0))) + (while (and (= (forward-line 1) 0) + (< (point) end-region-mark)) + (when (looking-at com) + (delete-region (point) (match-end 0)))))) (goto-char save-point) (set-marker end-region-mark nil) (set-marker save-point nil))) -(defvar kpp-mode-map () - "Keymap used in kpp mode.") +;; --------------------------------------------------------------------------- +;; Major mode definition +;; --------------------------------------------------------------------------- -(if kpp-mode-map - () - (setq kpp-mode-map (make-sparse-keymap)) - (define-key kpp-mode-map "\C-c;" 'kpp-comment-region) - ;; TAB inserts 8 spaces, not the TAB character - (define-key kpp-mode-map (kbd "TAB") - (lambda () (interactive) (insert " "))) -) +;;;###autoload +(define-derived-mode kpp-mode fundamental-mode "KPP" + ;; Fix #8: `define-derived-mode' replaces the manual boilerplate that + ;; was in the original: + ;; • calls `kill-all-local-variables' (Fix #4) + ;; • sets `major-mode' and `mode-name' + ;; • calls `use-local-map' with kpp-mode-map + ;; • calls `run-mode-hooks' + ;; • installs :syntax-table automatically + "Major mode for editing KPP (Kinetic PreProcessor) files. -(defun kpp-mode () - "Major mode for editing kpp code. -Turning on kpp mode calls the value of the variable `kpp-mode-hook' -with no args, if that value is non-nil. +Turning on `kpp-mode' runs the hook `kpp-mode-hook'. + +Known issue: `:' inside KPP inline comments (between reaction products +and the rate constant) may confuse font-lock. -Command Table: \\{kpp-mode-map}" - (interactive) - (make-local-variable 'font-lock-defaults) - (setq font-lock-defaults '((kpp-font-lock-keywords) t t)) - (make-local-variable 'comment-start) - (setq comment-start "{") - (make-local-variable 'comment-end) - (setq comment-end "}") - (use-local-map kpp-mode-map) - (setq mode-name "kpp") - (setq major-mode 'kpp-mode) - (turn-on-font-lock) - (set-syntax-table (copy-syntax-table)) - (modify-syntax-entry ?_ "w") ; the underscore can be part of a word - (auto-fill-mode 0) ; no automatic line breaks - (run-hooks 'kpp-mode-hook) -) + :syntax-table kpp-mode-syntax-table ; Fix #11: reuse pre-built table + ;; Fix #12: `setq-local' replaces the two-step + ;; `(make-local-variable ...) (setq ...)' pattern. + (setq-local font-lock-defaults '((kpp-font-lock-keywords) t t)) + ;; KPP uses { } as block-comment delimiters. + (setq-local comment-start "{ ") + (setq-local comment-end " }") + (setq-local comment-start-skip "{+\\s-*") ; added: needed by comment cmds + ;; Disable automatic line wrapping. + (auto-fill-mode 0) + ;; Fix #1 + #5: the original called `(turn-on-font-lock)' (deprecated) + ;; and also registered `font-lock-mode' (a toggle!) on `kpp-mode-hook'. + ;; With the hook in place, `turn-on-font-lock' ran first (enabling it), + ;; then the hook ran `font-lock-mode' with no argument (toggling it OFF). + ;; Net result: font-lock ended up disabled. Fix: call `font-lock-mode' + ;; with explicit argument 1 here; do NOT add it to `kpp-mode-hook'. + (font-lock-mode 1)) + +;; --------------------------------------------------------------------------- +;; Auto-mode associations +;; --------------------------------------------------------------------------- + +;; Fix #7: `add-to-list' is idempotent; the original `(setq … (cons …))' +;; pattern appended duplicate entries every time the file was reloaded. + +;;;###autoload +(add-to-list 'auto-mode-alist '("\\.kpp\\'" . kpp-mode)) +;;;###autoload +(add-to-list 'auto-mode-alist '("\\.eqn\\'" . kpp-mode)) + +;; Fix #17: .def and .spc are intentionally omitted. Those extensions are +;; claimed by many unrelated file types (C preprocessor, Win32 .def, SPICE, +;; R packages, …). Uncomment the lines below ONLY if you use these +;; extensions exclusively for KPP files. +;; +;; (add-to-list 'auto-mode-alist '("\\.def\\'" . kpp-mode)) +;; (add-to-list 'auto-mode-alist '("\\.spc\\'" . kpp-mode)) (provide 'kpp) -;; kpp.el ends here +;;; kpp.el ends here From 883ac712d46403441b69dea7d13ec20356d20ee1 Mon Sep 17 00:00:00 2001 From: Rolf Sander Date: Sun, 3 May 2026 18:42:10 +0200 Subject: [PATCH 2/8] email updated; ignore *.elc --- .gitignore | 5 ++++- site-lisp/kpp.el | 5 +---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 25826a2..c4ce056 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,9 @@ /ci-tests/**/*results* /ci-tests/**/*.csv +# Ignore byte-compiled emacs lisp files +/site-lisp/*.elc + # Ignore files generated by KPP (everywhere) **/*_Function* **/*_Global* @@ -73,4 +76,4 @@ docs/build/* !/util/Makefile* # ReadTheDocs -docs/_build/* \ No newline at end of file +docs/_build/* diff --git a/site-lisp/kpp.el b/site-lisp/kpp.el index 8e8c066..734bac6 100644 --- a/site-lisp/kpp.el +++ b/site-lisp/kpp.el @@ -1,9 +1,6 @@ ;;; kpp.el --- Major mode for KPP (Kinetic PreProcessor) files -*- lexical-binding: t; -*- -;; Copyright (C) 2005 Rolf Sander - -;; Author: Rolf Sander -;; Maintainer: Rolf Sander +;; Author: Rolf Sander ;; Version: 1.2 ;; Keywords: languages, kpp, chemistry From 26adb6539055d147f1452583666b76146a1f2492 Mon Sep 17 00:00:00 2001 From: Rolf Sander Date: Sun, 3 May 2026 18:44:49 +0200 Subject: [PATCH 3/8] kpp_mecca.el removed because it is only for the MECCA model --- site-lisp/kpp_mecca.el | 134 ----------------------------------------- 1 file changed, 134 deletions(-) delete mode 100644 site-lisp/kpp_mecca.el diff --git a/site-lisp/kpp_mecca.el b/site-lisp/kpp_mecca.el deleted file mode 100644 index 3297154..0000000 --- a/site-lisp/kpp_mecca.el +++ /dev/null @@ -1,134 +0,0 @@ -;; kpp.el --- kpp mode for GNU Emacs -;; (c) Rolf Sander - -;; To activate it, copy kpp.el to a place where emacs can find it and -;; then add "(require 'kpp)" to your .emacs startup file. - -;; Known problem: -;; ":" inside comments between reaction products confuses font-lock - -;; This program is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2 of the License, or -;; (at your option) any later version. -;; This program is distributed in the hope that it will be useful, -;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;; GNU General Public License for more details. - -;; auto-start kpp-mode when loading a *.def, *.eqn, *.kpp, or *.spc file -(setq auto-mode-alist - (cons '("\\.def\\'" . kpp-mode) auto-mode-alist)) -(setq auto-mode-alist - (cons '("\\.eqn\\'" . kpp-mode) auto-mode-alist)) -(setq auto-mode-alist - (cons '("\\.kpp\\'" . kpp-mode) auto-mode-alist)) -(setq auto-mode-alist - (cons '("\\.spc\\'" . kpp-mode) auto-mode-alist)) - -;; Turn on font-lock-mode for KPP -(add-hook 'kpp-mode-hook 'font-lock-mode) - -(setq kpp-font-lock-keywords - (list - '("^\\([^=\n]*=[^:\n]*\\):[^;\n]*;" 1 font-lock-constant-face) ; reaction - ;; alternatively, use another color for rate constant: - ;; '("^\\([^=\n]*=[^:\n]*\\):\\([^;\n]*\\);" - ;; (1 font-lock-constant-face) (2 font-lock-keyword-face)) - '("<[A-z0-9_#]+>" 0 font-lock-variable-name-face t) ; equation tag - '("{[^}\n]*}" 0 font-lock-comment-face t) ; comment - '("!.*" 0 font-lock-comment-face t) ; f90 comment - '("{@[^}]+}" 0 font-lock-doc-face t) ; alternative LaTeX text - '("{§[^}]*}" 0 font-lock-builtin-face t) ; uncertainty of rate coefficient - '("{$[^}]+}" 0 font-lock-doc-face t) ; alternative LaTeX text - '("{&[^}]+}" 0 font-lock-function-name-face t) ; BibTeX reference - '("{%[A-z0-9#]+}" 0 font-lock-type-face t) ; marker - ;; KPP sections (Tab. 3 in thesis), commands (Tab. 13 in thesis), and - ;; fragments (Tab. 17 in thesis) - (cons (concat - "\\(#ATOMS\\|#AUTOREDUCE\\|#CHECKALL\\|#CHECK\\|#DECLARE" - "\\|#DEFFIX\\|#DEFVAR\\|#DOUBLE\\|#DRIVER\\|#DUMMYINDEX" - "\\|#ENDINLINE\\|#EQNTAGS\\|#EQUATIONS\\|#FAMILIES\\|#FUNCTION" - "\\|#GRAPH\\|#HESSIAN\\|#INCLUDE\\|#INITVALUES\\|#INLINE\\|#INTEGRATOR" - "\\|#INTFILE\\|#JACOBIAN\\|#LANGUAGE\\|#LOOKATALL\\|#LOOKAT" - "\\|#MEX\\|#MINVERSION\\|#MODEL\\|#MONITOR\\|#REORDER" - "\\|#SETFIX\\|#SETVAR\\|#STOCHASTIC\\|#STOICMAT\\|#UPPERCASEF90" - "\\|#WRITE_ATM\\|#WRITE_MAT\\|#WRITE_SPC" - "\\|#REPLACE\\|#ENDREPLACE" - ) 'font-lock-keyword-face) - '("//.*" 0 font-lock-string-face t) ; LaTeX note - '("^//.*" 0 font-lock-comment-face t) ; comment - '("qqq" 0 font-lock-warning-face t) ; - ) -) - -; comment a region (adopted from wave-comment-region) - -(defvar kpp-comment-region "// " - "*String inserted by \\[kpp-comment-region] at start of each line in region.") - -(defun kpp-comment-region (beg-region end-region arg) - "Comments every line in the region. -Puts kpp-comment-region at the beginning of every line in the region. -BEG-REGION and END-REGION are args which specify the region boundaries. -With non-nil ARG, uncomments the region." - (interactive "*r\nP") - (let ((end-region-mark (make-marker)) (save-point (point-marker))) - (set-marker end-region-mark end-region) - (goto-char beg-region) - (beginning-of-line) - (if (not arg) ;comment the region - (progn (insert kpp-comment-region) - (while (and (= (forward-line 1) 0) - (< (point) end-region-mark)) - (insert kpp-comment-region))) - (let ((com (regexp-quote kpp-comment-region))) ;uncomment the region - (if (looking-at com) - (delete-region (point) (match-end 0))) - (while (and (= (forward-line 1) 0) - (< (point) end-region-mark)) - (if (looking-at com) - (delete-region (point) (match-end 0)))))) - (goto-char save-point) - (set-marker end-region-mark nil) - (set-marker save-point nil))) - -(defvar kpp-mode-map () - "Keymap used in kpp mode.") - -(if kpp-mode-map - () - (setq kpp-mode-map (make-sparse-keymap)) - (define-key kpp-mode-map "\C-c;" 'kpp-comment-region) - ;; TAB inserts 8 spaces, not the TAB character - (define-key kpp-mode-map (kbd "TAB") - (lambda () (interactive) (insert " "))) -) - -(defun kpp-mode () - "Major mode for editing kpp code. -Turning on kpp mode calls the value of the variable `kpp-mode-hook' -with no args, if that value is non-nil. - -Command Table: -\\{kpp-mode-map}" - (interactive) - (make-local-variable 'font-lock-defaults) - (setq font-lock-defaults '((kpp-font-lock-keywords) t t)) - (make-local-variable 'comment-start) - (setq comment-start "{") - (make-local-variable 'comment-end) - (setq comment-end "}") - (use-local-map kpp-mode-map) - (setq mode-name "kpp") - (setq major-mode 'kpp-mode) - (turn-on-font-lock) - (set-syntax-table (copy-syntax-table)) - (modify-syntax-entry ?_ "w") ; the underscore can be part of a word - (auto-fill-mode 0) ; no automatic line breaks - (run-hooks 'kpp-mode-hook) -) - -(provide 'kpp) - -;; kpp.el ends here From 7bbf3a9d0ff74e3f006596638d6a4260d78de1ec Mon Sep 17 00:00:00 2001 From: Rolf Sander Date: Sun, 3 May 2026 21:09:53 +0200 Subject: [PATCH 4/8] bugfix for kpp-doc-face didn't work. MECCA-specific highlighting commented out --- site-lisp/kpp.el | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/site-lisp/kpp.el b/site-lisp/kpp.el index 734bac6..7b4d6e9 100644 --- a/site-lisp/kpp.el +++ b/site-lisp/kpp.el @@ -60,19 +60,6 @@ :type 'string :group 'kpp) -;; --------------------------------------------------------------------------- -;; Faces -;; --------------------------------------------------------------------------- - -(defface kpp-doc-face - ;; Fix #6: `font-lock-doc-face' was introduced in Emacs 22. Defining our - ;; own face that *inherits* from it gives graceful degradation on older - ;; Emacs versions while using the correct face on modern ones. - '((t (:inherit font-lock-doc-face))) - "Face for KPP LaTeX documentation strings, e.g. {@...}. -Inherits from `font-lock-doc-face'; compatible with Emacs 21+." - :group 'kpp) - ;; --------------------------------------------------------------------------- ;; Syntax table (defined once at load time; shared by all kpp buffers) ;; --------------------------------------------------------------------------- @@ -109,16 +96,16 @@ Inherits from `font-lock-doc-face'; compatible with Emacs 21+." '("!.*" 0 font-lock-comment-face t) ;; {@...} – alternative LaTeX text (documentation) - ;; Uses kpp-doc-face rather than font-lock-doc-face directly; see Fix #6. - '("{@[^}]+}" 0 kpp-doc-face t) + ;; '("{@[^}]+}" 0 font-lock-doc-face t) + + ;; uncertainty of rate coefficient + ;; '("{§[^}]*}" 0 font-lock-builtin-face t) ;; {$...} – alternative LaTeX math text - ;; Fix: the original "{$[^}]+}" relied on $ being treated as literal - ;; when not at end of regexp. Using \\$ is explicit and unambiguous. - '("{\\$[^}]+}" 0 font-lock-string-face t) + ;; '("{\\$[^}]+}" 0 font-lock-string-face t) ;; {&...} – BibTeX reference - '("{&[^}]+}" 0 font-lock-builtin-face t) + ;; '("{&[^}]+}" 0 font-lock-function-name-face t) ;; {%...} – marker tag, e.g. {%TrG} ;; Fix #2: same [A-z] → [A-Za-z] correction as above. @@ -165,6 +152,12 @@ Inherits from `font-lock-doc-face'; compatible with Emacs 21+." "\\)\\>") 'font-lock-keyword-face) + ;; LaTeX note + ;; '("//.*" 0 font-lock-string-face t) + + ;; Fixme + ;; '("qqq" 0 font-lock-warning-face t) + ;; C++-style line comment: // comment '("^//.*" 0 font-lock-comment-face t)) "Font-lock keyword specification for `kpp-mode'.") From 60b88cdd04cc945061978b5089c98bff7dabd338 Mon Sep 17 00:00:00 2001 From: Rolf Sander Date: Sun, 3 May 2026 21:15:09 +0200 Subject: [PATCH 5/8] MECCA-specific highlighting commented out --- site-lisp/kpp.el | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/site-lisp/kpp.el b/site-lisp/kpp.el index 7b4d6e9..2573fd7 100644 --- a/site-lisp/kpp.el +++ b/site-lisp/kpp.el @@ -95,21 +95,21 @@ ;; Fortran-90 / KPP inline comment: ! comment to end of line '("!.*" 0 font-lock-comment-face t) - ;; {@...} – alternative LaTeX text (documentation) + ;; {@...} – alternative LaTeX text ;; '("{@[^}]+}" 0 font-lock-doc-face t) ;; uncertainty of rate coefficient ;; '("{§[^}]*}" 0 font-lock-builtin-face t) - ;; {$...} – alternative LaTeX math text - ;; '("{\\$[^}]+}" 0 font-lock-string-face t) + ;; {$...} – alternative LaTeX text + ;; '("{\\$[^}]+}" 0 font-lock-doc-face t) ;; {&...} – BibTeX reference ;; '("{&[^}]+}" 0 font-lock-function-name-face t) ;; {%...} – marker tag, e.g. {%TrG} ;; Fix #2: same [A-z] → [A-Za-z] correction as above. - '("{%[A-Za-z0-9#]+}" 0 font-lock-type-face t) + ;; '("{%[A-Za-z0-9#]+}" 0 font-lock-type-face t) ;; KPP sections, commands, and fragments ;; (Tables 3, 13, and 17 in the KPP manual / thesis) @@ -155,11 +155,13 @@ ;; LaTeX note ;; '("//.*" 0 font-lock-string-face t) + ;; C++-style line comment: // comment + '("^//.*" 0 font-lock-comment-face t) + ;; Fixme ;; '("qqq" 0 font-lock-warning-face t) - ;; C++-style line comment: // comment - '("^//.*" 0 font-lock-comment-face t)) + ) "Font-lock keyword specification for `kpp-mode'.") ;; --------------------------------------------------------------------------- From d1e0b5ca672098a3ca868b29a4703cc525aea042 Mon Sep 17 00:00:00 2001 From: Rolf Sander Date: Mon, 4 May 2026 18:22:09 +0200 Subject: [PATCH 6/8] autoload for .def and .spc re-activated --- site-lisp/kpp.el | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/site-lisp/kpp.el b/site-lisp/kpp.el index 2573fd7..2f42d69 100644 --- a/site-lisp/kpp.el +++ b/site-lisp/kpp.el @@ -269,14 +269,10 @@ and the rate constant) may confuse font-lock. (add-to-list 'auto-mode-alist '("\\.kpp\\'" . kpp-mode)) ;;;###autoload (add-to-list 'auto-mode-alist '("\\.eqn\\'" . kpp-mode)) - -;; Fix #17: .def and .spc are intentionally omitted. Those extensions are -;; claimed by many unrelated file types (C preprocessor, Win32 .def, SPICE, -;; R packages, …). Uncomment the lines below ONLY if you use these -;; extensions exclusively for KPP files. -;; -;; (add-to-list 'auto-mode-alist '("\\.def\\'" . kpp-mode)) -;; (add-to-list 'auto-mode-alist '("\\.spc\\'" . kpp-mode)) +;;;###autoload +(add-to-list 'auto-mode-alist '("\\.def\\'" . kpp-mode)) +;;;###autoload +(add-to-list 'auto-mode-alist '("\\.spc\\'" . kpp-mode)) (provide 'kpp) From 80d55ad6fcb80127ce4efb3433ae310c7a577d23 Mon Sep 17 00:00:00 2001 From: Rolf Sander Date: Mon, 4 May 2026 18:43:40 +0200 Subject: [PATCH 7/8] autoload for .def and .spc re-activated --- site-lisp/kpp.el | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/site-lisp/kpp.el b/site-lisp/kpp.el index 2f42d69..8f2e0e1 100644 --- a/site-lisp/kpp.el +++ b/site-lisp/kpp.el @@ -25,13 +25,7 @@ ;; (require 'kpp) ;; to your Emacs init file (~/.emacs or ~/.emacs.d/init.el). ;; -;; File extensions automatically associated with kpp-mode: .kpp, .eqn -;; -;; Note on .def and .spc extensions: -;; These are intentionally NOT registered by default because they are used -;; by many other file types (C preprocessor, Win32 module definitions, -;; SPICE netlists, R packages, etc.). Uncomment the relevant lines near -;; the bottom of this file if you want them. +;; File extensions automatically associated with kpp-mode: .kpp, .eqn, .def, .spc ;; ;; Known issue: ;; ":" inside KPP inline comments (between reaction products and the rate From 3567d05a1d8cff5224f006c92a4a27dd70839d4e Mon Sep 17 00:00:00 2001 From: Rolf Sander Date: Tue, 5 May 2026 17:11:02 +0200 Subject: [PATCH 8/8] obsolete KPP sections and commands removed again --- site-lisp/kpp.el | 48 ++++++++++++++++-------------------------------- 1 file changed, 16 insertions(+), 32 deletions(-) diff --git a/site-lisp/kpp.el b/site-lisp/kpp.el index 8f2e0e1..bd4c972 100644 --- a/site-lisp/kpp.el +++ b/site-lisp/kpp.el @@ -1,6 +1,7 @@ ;;; kpp.el --- Major mode for KPP (Kinetic PreProcessor) files -*- lexical-binding: t; -*- -;; Author: Rolf Sander +;; Authors: Rolf Sander +;; Bob Yantosca (used AI to "lint") ;; Version: 1.2 ;; Keywords: languages, kpp, chemistry @@ -25,11 +26,8 @@ ;; (require 'kpp) ;; to your Emacs init file (~/.emacs or ~/.emacs.d/init.el). ;; -;; File extensions automatically associated with kpp-mode: .kpp, .eqn, .def, .spc -;; -;; Known issue: -;; ":" inside KPP inline comments (between reaction products and the rate -;; constant) may confuse font-lock. +;; File extensions automatically associated with kpp-mode: +;; .def, .eqn, .kpp, .spc ;;; Code: @@ -105,44 +103,30 @@ ;; Fix #2: same [A-z] → [A-Za-z] correction as above. ;; '("{%[A-Za-z0-9#]+}" 0 font-lock-type-face t) - ;; KPP sections, commands, and fragments - ;; (Tables 3, 13, and 17 in the KPP manual / thesis) + ;; KPP sections and commands ;; ;; ORDERING RULE: in Emacs regex alternation (\|) the leftmost match ;; wins. Any keyword that is a strict prefix of another must therefore - ;; appear AFTER the longer form: - ;; - ;; Pair Original order Fixed order - ;; #CHECK / #CHECKALL CHECKALL first ✓ already correct - ;; #LOOKAT / #LOOKATALL LOOKATALL first ✓ already correct - ;; #TRANSPORT / …ALL …ALL first ✓ already correct - ;; #USE / #USES USE first ✗ BUG → fixed below (#Fix 3) + ;; appear AFTER the longer form. ;; ;; \> (end-of-word boundary) prevents a short keyword from matching ;; as a prefix of an unknown longer token. (cons (concat "\\(" "#ATOMS\\|#AUTOREDUCE" - "\\|#CHECKALL\\|#CHECK" - "\\|#DEFFIX\\|#DEFRAD\\|#DEFVAR" - "\\|#DOUBLE\\|#DRIVER\\|#DUMMYINDEX" + "\\|#CHECKALL\\|#CHECK" ; CHECKALL before CHECK + "\\|#DEFFIX\\|#DEFVAR\\|#DOUBLE\\|#DRIVER\\|#DUMMYINDEX" "\\|#ENDINLINE\\|#EQNTAGS\\|#EQUATIONS" - "\\|#FAMILIES\\|#FUNCTION\\|#GRAPH" + "\\|#FAMILIES\\|#FUNCTION" + "\\|#GRAPH" "\\|#HESSIAN" - "\\|#INCLUDE\\|#INITVALUES\\|#INITIALIZE\\|#INLINE" - "\\|#INTEGRATOR\\|#INTFILE" + "\\|#INCLUDE\\|#INITVALUES\\|#INLINE\\|#INTEGRATOR\\|#INTFILE" "\\|#JACOBIAN" - "\\|#LANGUAGE" - "\\|#LOOKATALL\\|#LOOKAT\\|#LUMP" + "\\|#LANGUAGE\\|#LOOKATALL\\|#LOOKAT" ; LOOKATALL before LOOKAT "\\|#MEX\\|#MINVERSION\\|#MODEL\\|#MONITOR" - "\\|#REORDER\\|#RUN" - "\\|#SETFIX\\|#SETRAD\\|#SETVAR" - "\\|#SPARSEDATA\\|#STOCHASTIC\\|#STOICMAT" - "\\|#TRANSPORTALL\\|#TRANSPORT" + "\\|#REORDER" + "\\|#SETFIX\\|#SETVAR\\|#STOCHASTIC\\|#STOICMAT" "\\|#UPPERCASEF90" - "\\|#USES\\|#USE" ; Fix #3: #USES before #USE - "\\|#WRITE_ATM\\|#WRITE_MAT\\|#WRITE_OPT\\|#WRITE_SPC" - "\\|#XGRID\\|#YGRID\\|#ZGRID" "\\)\\>") 'font-lock-keyword-face) @@ -260,11 +244,11 @@ and the rate constant) may confuse font-lock. ;; pattern appended duplicate entries every time the file was reloaded. ;;;###autoload -(add-to-list 'auto-mode-alist '("\\.kpp\\'" . kpp-mode)) +(add-to-list 'auto-mode-alist '("\\.def\\'" . kpp-mode)) ;;;###autoload (add-to-list 'auto-mode-alist '("\\.eqn\\'" . kpp-mode)) ;;;###autoload -(add-to-list 'auto-mode-alist '("\\.def\\'" . kpp-mode)) +(add-to-list 'auto-mode-alist '("\\.kpp\\'" . kpp-mode)) ;;;###autoload (add-to-list 'auto-mode-alist '("\\.spc\\'" . kpp-mode))