Subject: bug#77313: 30.1.50; Regression: flymake indicators are erroneously using margins

From: Spencer Baugh <[email-masked]>
Date: Wed, 16 Apr 2025 13:57:03 -0400

Eli Zaretskii <[email-masked]> writes:
>> From: Spencer Baugh <[email-masked]>
>> Date: Sat, 12 Apr 2025 07:43:11 -0400
>> Cc: [email-masked], Juri Linkov <[email-masked]>
>> 
>> On Sat, Apr 12, 2025, 7:13 AM Eli Zaretskii <[email-masked]> wrote:
>> 
>>  Thanks, installed on master.
>> 
>>  Should we now close this bug?
>> 
>> No, we need to backport it to Emacs 30.2 to fix the regression.
>
> OK, but it cannot be cherry-picked as is, because it includes a NEWS
> entry.  So the fix for emacs-30, when we decide to install it, will
> need to be a separate commit.

OK, here is a version ready for backporting to emacs-30, with a NEWS
entry appropriate for 30.2.

>From 1031bf89a5444ad225b1ef1af64bbb32a2a7512a Mon Sep 17 00:00:00 2001
From: Spencer Baugh <[email-masked]>
Date: Tue, 8 Apr 2025 08:43:37 -0400
Subject: [PATCH] flymake: fall back to margins on text terminals

Previously, flymake-indicator-type defaulted to either fringes
or margins.  But fringes should be used on graphical frames, and
margins on TTY frames.  So default to fringes instead, and
simply fall back to margins automatically on text frames.

* lisp/progmodes/flymake.el (flymake-indicator-type): Set to
fringes.  (bug#77313)
(flymake-mode): Fallback to margins if there's no fringes.
* doc/misc/flymake.texi (Customizable variables): Mention
fallback behavior.
* etc/NEWS: Announce fallback behavior.
---
 doc/misc/flymake.texi     |  3 +++
 etc/NEWS                  |  7 +++++++
 lisp/progmodes/flymake.el | 20 ++++++++++++++------
 3 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/doc/misc/flymake.texi b/doc/misc/flymake.texi
index 54835767928..668a72b4cd1 100644
--- a/doc/misc/flymake.texi
+++ b/doc/misc/flymake.texi
@@ -313,6 +313,9 @@ Customizable variables
 errors or warnings.
 Depending on your preference, this can either use @code{fringes} or
 @code{margins} for indicating errors.
+If set to @code{fringes} (the default), it will automatically fall back
+to using margins in windows or frames without fringes, such as text
+terminals.
 
 @item flymake-error-bitmap
 A bitmap used in the fringe to mark lines for which an error has
diff --git a/etc/NEWS b/etc/NEWS
index dfe4c65f1dd..1915c3170a7 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -30,6 +30,13 @@ with a prefix argument or by typing 'C-u C-h C-n'.
 
 * Changes in Specialized Modes and Packages in Emacs 30.2
 
+** Flymake
+
+*** Windows without fringes now automatically use margin indicators
+When flymake-indicator-type is set to 'fringes', as is now the default,
+flymake will automatically fall back to using margin indicators in
+windows without fringes, including any window in a text terminal.
+
 
 * New Modes and Packages in Emacs 30.2
 
diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el
index f8a294908ba..08e96565229 100644
--- a/lisp/progmodes/flymake.el
+++ b/lisp/progmodes/flymake.el
@@ -185,22 +185,23 @@ flymake-fringe-indicator-position
 		 (const right-fringe)
 		 (const :tag "No fringe indicators" nil)))
 
-(defcustom flymake-indicator-type (if (display-graphic-p)
-                                      'fringes
-                                    'margins)
+(defcustom flymake-indicator-type 'fringes
   "Indicate which indicator type to use for display errors.
 
 The value can be nil (don't indicate errors but just highlight them),
-fringes (use fringes) or margins (use margins)
+the symbol `fringes' (use fringes) or the symbol `margins' (use
+margins).
 
 Difference between fringes and margin is that fringes support displaying
 bitmaps on graphical displays and margins display text in a blank area
 from current buffer that works in both graphical and text displays.
+Thus, even when `fringes' is selected, margins will still be used on
+text displays and also when fringes are disabled.
 
 See Info node `Fringes' and Info node `(elisp)Display Margins'."
-  :version "30.1"
+  :version "31.1"
   :type '(choice (const :tag "Use Fringes" fringes)
-                 (const :tag "Use Margins "margins)
+                 (const :tag "Use Margins" margins)
                  (const :tag "No indicators" nil)))
 
 (defcustom flymake-margin-indicators-string
@@ -1393,6 +1394,13 @@ flymake-mode
     (add-hook 'kill-buffer-hook 'flymake-kill-buffer-hook nil t)
     (add-hook 'eldoc-documentation-functions 'flymake-eldoc-function t t)
 
+    (when (and (eq flymake-indicator-type 'fringes)
+               (not (cl-case flymake-fringe-indicator-position
+                      (left-fringe (< 0 (nth 0 (window-fringes))))
+                      (right-fringe (< 0 (nth 1 (window-fringes)))))))
+      ;; There are no fringes in the buffer, fallback to margins.
+      (setq-local flymake-indicator-type 'margins))
+
     ;; AutoResize margins.
     (flymake--resize-margins)
 
-- 
2.39.3