branch: elpa/flycheck
commit bf620f70e4a4e4bc6ade30089f95fd76d8071f98
Author: Bozhidar Batsov <[email protected]>
Commit: Bozhidar Batsov <[email protected]>
[Fix #2170] Use LC_MESSAGES=C instead of LC_ALL=C for checkers
Forcing LC_ALL=C (added to get English output for error patterns, #1859)
also pins the character encoding to ASCII, which breaks checkers that
read UTF-8 input, e.g. hledger on journals with unicode. LC_MESSAGES=C
gives English messages while leaving LC_CTYPE alone.
---
CHANGES.rst | 3 +++
flycheck.el | 8 ++++++--
test/specs/test-command-checker.el | 15 ++++++++++++++-
test/specs/test-helpers.el | 20 ++++++++++++++++++++
4 files changed, 43 insertions(+), 3 deletions(-)
diff --git a/CHANGES.rst b/CHANGES.rst
index fc7e32ebcc..b3f222a3ff 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -8,6 +8,9 @@
scripts.
- [#2163]: Disable native compilation in the ``emacs-lisp`` checker subprocess
so it no longer writes stray ``.eln`` files to the native-comp cache.
+- [#2170]: Force English checker output with ``LC_MESSAGES=C`` instead of
+ ``LC_ALL=C``, so the character encoding is left untouched. ``LC_ALL=C``
+ broke checkers reading UTF-8 input, such as ``hledger``.
36.0 (2026-02-19)
======================
diff --git a/flycheck.el b/flycheck.el
index 4894d5eff0..dddd3fa1fe 100644
--- a/flycheck.el
+++ b/flycheck.el
@@ -6267,8 +6267,12 @@ PROCESS, and terminates standard input with EOF."
;; can easily use pipes.
(process-connection-type nil)
;; Force English messages from checker processes so that
- ;; error patterns can match reliably.
- (process-environment (cons "LC_ALL=C" process-environment)))
+ ;; error patterns can match reliably. We set LC_MESSAGES
+ ;; rather than LC_ALL so that the character encoding
+ ;; (LC_CTYPE) is left untouched; using LC_ALL=C forces an
+ ;; ASCII locale that breaks checkers reading UTF-8 input,
+ ;; such as hledger (see #2170).
+ (process-environment (cons "LC_MESSAGES=C"
process-environment)))
;; We do not associate the process with any buffer, by
;; passing nil for the BUFFER argument of `start-process'.
;; Instead, we just remember the buffer being checked in a
diff --git a/test/specs/test-command-checker.el
b/test/specs/test-command-checker.el
index e45020164b..da48c10c25 100644
--- a/test/specs/test-command-checker.el
+++ b/test/specs/test-command-checker.el
@@ -126,6 +126,19 @@
(truncated-stdin-mode)
(insert (make-string 65537 ?\n))
(expect (shut-up (flycheck-buttercup-should-syntax-check-in-buffer))
- :to-throw 'flycheck-buttercup-suspicious-checker))))))
+ :to-throw 'flycheck-buttercup-suspicious-checker))))
+
+ (it "forces English messages without overriding the character set"
+ ;; LC_MESSAGES=C gives English output, while LC_ALL is left alone so
+ ;; that the subprocess keeps the user's LC_CTYPE (see #2170).
+ (assume (or (executable-find "python3") (executable-find "python")))
+ (cl-letf* ((flycheck-checker 'print-locale)
+ ((symbol-plist 'print-locale) flycheck-test--print-locale))
+ (flycheck-buttercup-with-env '(("LC_MESSAGES" . nil) ("LC_ALL" . nil))
+ (flycheck-buttercup-with-temp-buffer
+ (print-locale-mode)
+ (insert "dummy\n")
+ (flycheck-buttercup-should-syntax-check-in-buffer
+ '(1 1 error "LC_MESSAGES=C LC_ALL=" :checker print-locale))))))))
;;; test-command-checker.el ends here
diff --git a/test/specs/test-helpers.el b/test/specs/test-helpers.el
index 1de0d7471e..9ac1424247 100644
--- a/test/specs/test-helpers.el
+++ b/test/specs/test-helpers.el
@@ -161,6 +161,26 @@ The manifest path is relative to
(setf (symbol-plist 'truncated-stdin) nil)
+;;; Locale test helpers (for command-checker tests)
+
+(define-derived-mode print-locale-mode prog-mode "locale")
+
+(flycheck-define-command-checker 'print-locale
+ "Report the LC_MESSAGES and LC_ALL the subprocess inherits."
+ :command `(,(or (executable-find "python3") "python")
+ "-c" ,(concat "import os; print('locale:1:1:LC_MESSAGES=%s
LC_ALL=%s'"
+ " % (os.environ.get('LC_MESSAGES', ''),"
+ " os.environ.get('LC_ALL', '')))"))
+ :error-patterns '((error bol "locale" ":" line ":" column ":" (message)))
+ :modes '(print-locale-mode))
+
+(defconst flycheck-test--print-locale
+ (symbol-plist 'print-locale)
+ "Saved plist for the print-locale checker.")
+
+(setf (symbol-plist 'print-locale) nil)
+
+
;;; Custom error level for error-level tests
(flycheck-define-error-level 'test-level