Subject: bug#70622: [PATCH] New window parameter 'cursor-type'

From: Eshel Yaron <[email-masked]>
Date: Sun, 28 Apr 2024 08:27:53 +0200

Tags: patch

This patch makes it possible to set the cursor type in a specific window,
without affecting other windows that may be showing the same buffer.

>From 518a6708c6d94f152c9cb9ca7a8c73aeffa4a03a Mon Sep 17 00:00:00 2001
From: Eshel Yaron <[email-masked]>
Date: Sat, 27 Apr 2024 20:47:34 +0200
Subject: [PATCH] New window parameter 'cursor-type'

* src/xdisp.c (get_window_cursor_type): Consult new window
parameter 'cursor-type'.
* doc/lispref/windows.texi (Window Parameters): Document it.
* etc/NEWS: Announce it.
---
 doc/lispref/windows.texi |  9 +++++++++
 etc/NEWS                 |  6 ++++++
 src/xdisp.c              | 28 ++++++++++++++++++----------
 3 files changed, 33 insertions(+), 10 deletions(-)

diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi
index 104420235df..19154692056 100644
--- a/doc/lispref/windows.texi
+++ b/doc/lispref/windows.texi
@@ -6691,6 +6691,15 @@ Window Parameters
 window and should be used, with due care, exclusively by those
 applications.  It might be replaced by an improved solution in future
 versions of Emacs.
+
+@item cursor-type
+@vindex cursor-type@r{, a window parameter}
+If this parameter is set to a cons cell, its @sc{car} specifies the
+shape of the cursor in this window, using the same format as the
+buffer-local variable @code{cursor-type}.  @xref{Cursor Parameters}.
+Use this window parameter instead of the @code{cursor-type} variable or
+frame parameter when a buffer is displayed in multiple windows and you
+want to change the cursor for one window without affecting the others.
 @end table

diff --git a/etc/NEWS b/etc/NEWS
index 9c356e64bde..e08998e4b6f 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -340,6 +340,12 @@ and 'window-state-get'.  Then later another new variable
 'window-state-put' to restore positions of window points
 according to the context stored in a window parameter.
 
++++
+*** New window parameter 'cursor-type'.
+If this parameter is set to a cons cell, its 'car' specifies the shape
+of the window's cursor, using the same format as the buffer-local
+variable 'cursor-type'.
+
 ** Tab Bars and Tab Lines
 
 ---
diff --git a/src/xdisp.c b/src/xdisp.c
index 85802ec5083..ac2b2d186ff 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -33605,7 +33605,7 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
   struct frame *f = XFRAME (w->frame);
   struct buffer *b = XBUFFER (w->contents);
   int cursor_type = DEFAULT_CURSOR;
-  Lisp_Object alt_cursor;
+  Lisp_Object alt_cursor, win_cursor;
   bool non_selected = false;
 
   *active_cursor = true;
@@ -33644,18 +33644,26 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
       non_selected = true;
     }
 
-  /* Never display a cursor in a window in which cursor-type is nil.  */
-  if (NILP (BVAR (b, cursor_type)))
-    return NO_CURSOR;
-
-  /* Get the normal cursor type for this window.  */
-  if (EQ (BVAR (b, cursor_type), Qt))
+  win_cursor = window_parameter (w, Qcursor_type);
+  if (CONSP (win_cursor))
     {
-      cursor_type = FRAME_DESIRED_CURSOR (f);
-      *width = FRAME_CURSOR_WIDTH (f);
+      cursor_type = get_specified_cursor_type (XCAR (win_cursor), width);
     }
   else
-    cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
+    {
+      /* Never display a cursor in a window in which cursor-type is nil.  */
+      if (NILP (BVAR (b, cursor_type)))
+	return NO_CURSOR;
+
+      /* Get the normal cursor type for this window.  */
+      if (EQ (BVAR (b, cursor_type), Qt))
+	{
+	  cursor_type = FRAME_DESIRED_CURSOR (f);
+	  *width = FRAME_CURSOR_WIDTH (f);
+	}
+      else
+	cursor_type = get_specified_cursor_type (BVAR (b, cursor_type), width);
+    }
 
   /* Use cursor-in-non-selected-windows instead
      for non-selected window or frame.  */
-- 
2.44.0