]> git.eshelyaron.com Git - emacs.git/commitdiff
New functions '(set-)window-cursor-type'
authorEshel Yaron <me@eshelyaron.com>
Sat, 27 Apr 2024 18:47:34 +0000 (20:47 +0200)
committerEshel Yaron <me@eshelyaron.com>
Sat, 18 May 2024 19:12:31 +0000 (21:12 +0200)
* src/window.h (struct window): Add 'cursor_type' slot.
(wset_cursor_type): New inline function.
* src/xdisp.c (get_window_cursor_type): Consult 'cursor_type'.
* src/window.c (make_window): Initialize 'cursor_type' to t.
(Fset_window_cursor_type, Fwindow_cursor_type): New functions.
(syms_of_window): List their symbols.
* doc/lispref/windows.texi (Window Point): Document them.
* doc/lispref/frames.texi (Cursor Parameters): Mention
new 'set-window-cursor-type'.
* etc/NEWS: Announce new functions.  (Bug#70622)

(cherry picked from commit 3b890bf2bd2fec54433f35d61e30542b3dadb612)

doc/lispref/frames.texi
doc/lispref/windows.texi
etc/NEWS
src/window.c
src/window.h
src/xdisp.c

index cae93acae9f9aa86b7183508896a30f6e166a380..974def3de103744af358a5ce0f2f4d4eccab8c87 100644 (file)
@@ -2341,9 +2341,9 @@ Display a horizontal bar @var{height} pixels high.
 @end table
 
 @vindex cursor-type
-The @code{cursor-type} frame parameter may be overridden by the
-variables @code{cursor-type} and
-@code{cursor-in-non-selected-windows}:
+The @code{cursor-type} frame parameter may be overridden by
+@code{set-window-cursor-type} (@pxref{Window Point}), and by the
+variables @code{cursor-type} and @code{cursor-in-non-selected-windows}:
 
 @defopt cursor-type
 This buffer-local variable controls how the cursor looks in a selected
index 34f7b260a526e54405b23f7ef62fcdd8fd795245..61e72eae6806ab4041290a9721da3de0e1fc6a85 100644 (file)
@@ -5142,6 +5142,24 @@ Insertion Types}) of @code{window-point}.  The default is @code{nil},
 so @code{window-point} will stay behind text inserted there.
 @end defvar
 
+@defun set-window-cursor-type window type
+This function sets the cursor shape for @var{window}.  This setting
+takes precedence over the @code{cursor-type} variable, and @var{type}
+has the same format as the value of that variable.  @xref{Cursor
+Parameters}.  If @var{window} is @code{nil}, it means to set the cursor
+type for the selected window.
+
+The initial value for new windows is @code{t}, which says to respect the
+buffer-local value of @code{cursor-type}.  The value set by this
+function persists across buffers shown in @var{window}, so
+@code{set-window-buffer} does not reset it.  @xref{Buffers and Windows}.
+@end defun
+
+@defun window-cursor-type &optional window
+This function returns the cursor type of @var{window}, defaulting to the
+selected window.
+@end defun
+
 @node Window Start and End
 @section The Window Start and End Positions
 @cindex window start position
index 1f7d39d65d431a585328f7e33d044d21179773c1..1f6873f6f88861b1d25cc7cb62a4796562a9e899 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -319,6 +319,13 @@ 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 functions 'set-window-cursor-type' and 'window-cursor-type'.
+'set-window-cursor-type' sets a per-window cursor type, and
+'window-cursor-type' queries this setting for a given window.  Windows
+are always created with a 'window-cursor-type' of t, which means to
+consult the variable 'cursor-type' as before.
+
 ** Tab Bars and Tab Lines
 
 ---
index aac5b087c2c95ec5363359e9c365c454bbdf0523..ff28bac53066f77c4ba1e002159313c8d89d1c46 100644 (file)
@@ -4425,6 +4425,7 @@ make_window (void)
   wset_old_pointm (w, Fmake_marker ());
   wset_vertical_scroll_bar_type (w, Qt);
   wset_horizontal_scroll_bar_type (w, Qt);
+  wset_cursor_type (w, Qt);
   /* These Lisp fields are marked specially so they're not set to nil by
      allocate_window.  */
   wset_prev_buffers (w, Qnil);
@@ -8050,6 +8051,52 @@ PERSISTENT), see `set-window-fringes'.  */)
                w->fringes_persistent ? Qt : Qnil);
 }
 
+DEFUN ("set-window-cursor-type", Fset_window_cursor_type,
+       Sset_window_cursor_type, 2, 2, 0,
+       doc: /* Set the `cursor-type' of WINDOW to TYPE.
+
+This setting takes precedence over the variable `cursor-type', and TYPE
+has the same format as the value of that variable.  The initial value
+for new windows is t, which says to respect the buffer-local value of
+`cursor-type'.
+
+WINDOW nil means use the selected window.  This setting persists across
+buffers shown in WINDOW, so `set-window-buffer' does not reset it.  */)
+  (Lisp_Object window, Lisp_Object type)
+{
+  struct window *w = decode_live_window (window);
+
+  if (!(NILP (type)
+       || EQ (type, Qt)
+       || EQ (type, Qbox)
+       || EQ (type, Qhollow)
+       || EQ (type, Qbar)
+       || EQ (type, Qhbar)
+       || (CONSP (type)
+           && (EQ (XCAR (type), Qbox)
+               || EQ (XCAR (type), Qbar)
+               || EQ (XCAR (type), Qhbar))
+           && INTEGERP (XCDR (type)))))
+    error ("Invalid cursor type");
+
+  wset_cursor_type (w, type);
+
+  /* Redisplay with updated cursor type.  */
+  wset_redisplay (w);
+
+  return type;
+}
+
+/* FIXME: Add a way to get the _effective_ cursor type, possibly by
+   extending this function with an additional optional argument.  */
+DEFUN ("window-cursor-type", Fwindow_cursor_type, Swindow_cursor_type,
+       0, 1, 0,
+       doc: /* Return the `cursor-type' of WINDOW.
+WINDOW must be a live window and defaults to the selected one.  */)
+  (Lisp_Object window)
+{
+  return decode_live_window (window)->cursor_type;
+}
 
 \f
 /***********************************************************************
@@ -8985,4 +9032,6 @@ displayed after a scrolling operation to be somewhat inaccurate.  */);
   defsubr (&Swindow_parameters);
   defsubr (&Swindow_parameter);
   defsubr (&Sset_window_parameter);
+  defsubr (&Swindow_cursor_type);
+  defsubr (&Sset_window_cursor_type);
 }
index 19283725931419344f975d28489f3601876976c4..86932181252ab24304b279f3e8a340277712cd2b 100644 (file)
@@ -205,6 +205,9 @@ struct window
     /* An alist with parameters.  */
     Lisp_Object window_parameters;
 
+    /* `cursor-type' to use in this window.  */
+    Lisp_Object cursor_type;
+
     /* The help echo text for this window.  Qnil if there's none.  */
     Lisp_Object mode_line_help_echo;
 
@@ -542,6 +545,12 @@ wset_horizontal_scroll_bar_type (struct window *w, Lisp_Object val)
   w->horizontal_scroll_bar_type = val;
 }
 
+INLINE void
+wset_cursor_type (struct window *w, Lisp_Object val)
+{
+  w->cursor_type = val;
+}
+
 INLINE void
 wset_prev_buffers (struct window *w, Lisp_Object val)
 {
index 63ff8670b7905f240f4505baa7439f710a82c90a..ba5af7127c68eae0a5b57b215c1a5ab1c3c0f3e4 100644 (file)
@@ -33616,7 +33616,9 @@ get_window_cursor_type (struct window *w, struct glyph *glyph, int *width,
     {
       if (w == XWINDOW (echo_area_window))
        {
-         if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
+         if (!EQ (Qt, w->cursor_type))
+             return get_specified_cursor_type (w->cursor_type, width);
+         else if (EQ (BVAR (b, cursor_type), Qt) || NILP (BVAR (b, cursor_type)))
            {
              *width = FRAME_CURSOR_WIDTH (f);
              return FRAME_DESIRED_CURSOR (f);
@@ -33643,18 +33645,23 @@ 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))
+  if (!EQ (Qt, w->cursor_type))
+      cursor_type = get_specified_cursor_type (w->cursor_type, width);
+  else
     {
-      cursor_type = FRAME_DESIRED_CURSOR (f);
-      *width = FRAME_CURSOR_WIDTH (f);
+      /* 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);
     }
-  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.  */