[Rd] Customizing width of input in Rterm

Ivan Krylov |kry|ov @end|ng |rom d|@root@org
Wed Feb 26 12:42:03 CET 2025


В Fri, 21 Feb 2025 11:52:41 +0100
Iago Giné-Vázquez <iago.gine using sjd.es> пишет:

> When using Rterm.exe (on Windows, I didn’t check Linux) only a
> limited number of characters is displayed in the input lines,
> independent on the |width| option, and, when navigating through the
> command history this becomes very uncomfortable, since a command is
> not fully displayed and, for example, it is very difficult to know
> which parts of a command are being edited.

The patch at the end of this message reads the console width on startup
and handles the console resize events while getline() is running. The
automatic resizing doesn't look nice due to gl_redraw() starting a new
line newline before redrawing the prompt, but it works.

This may have accessibility implications since it changes the behaviour
of Rterm.exe, which is what A. Jonathan R. Godfrey recommends for blind
Windows users [1]. I've experimented with NVDA and didn't notice
anything breaking in Windows 10 terminal or mintty.exe, but it's hard
to be sure without the real experience of using a screen reader.

Is this approach worth adopting? Is it better to erase the current line
instead of starting a new one? options(setWidthOnResize) could be
implemented similarly but may require more care due to
R_SetOptionWidth(...) evaluating R code.

Index: src/gnuwin32/getline/getline.c
===================================================================
--- src/gnuwin32/getline/getline.c	(revision 87795)
+++ src/gnuwin32/getline/getline.c	(working copy)
@@ -25,6 +25,7 @@
 int 		(*gl_in_hook)(char *) = 0;
 int 		(*gl_out_hook)(char *) = 0;
 int 		(*gl_tab_hook)(char *, int, int *) = gl_tab;
+static int      do_setwidth(int w);
 
 #include <Rconfig.h>
 #include <R_ext/Riconv.h>
@@ -214,6 +215,10 @@
          The bug still exists in Windows 10, and thus we now call
          GetConsoleInputW to get uchar.UnicodeChar. */
       ReadConsoleInputW(Win32InputStream, &r, 1, &a);
+      if (r.EventType == WINDOW_BUFFER_SIZE_EVENT) {
+        if (do_setwidth(r.Event.WindowBufferSizeEvent.dwSize.X))
+          gl_redraw();
+      }
       if (!(r.EventType == KEY_EVENT)) break;
       st = r.Event.KeyEvent.dwControlKeyState;
       vk = r.Event.KeyEvent.wVirtualKeyCode;
@@ -487,6 +492,11 @@
     gl_w2e_map = gl_realloc(NULL, 0, BUF_SIZE, sizeof(size_t)); 
 
     gl_char_init();
+
+    CONSOLE_SCREEN_BUFFER_INFO csb;
+    GetConsoleScreenBufferInfo(Win32OutputStream, &csb);
+    do_setwidth(csb.dwSize.X);
+
     gl_init_done = 1;
 }
 
@@ -536,13 +546,21 @@
     BUF_SIZE = newsize;
 }
 
+static int
+do_setwidth(int w)
+{
+    /* may be called from gl_getc if a resize event is received */
+    if (w > 20) {
+	gl_w_termw = w;
+	return 1;
+    }
+    return 0;
+}
+
 void
 gl_setwidth(int w)
 {
-    /* not used in R; should arrange for redraw */
-    if (w > 20) 
-	gl_w_termw = w;
-    else 
+    if (!do_setwidth(w))
 	gl_error("\n*** Error: minimum screen width is 21\n");
 }
 


-- 
Best regards,
Ivan

[1]
https://r-resources.massey.ac.nz/lurnblind/LURNBlindch2.html#x4-80002.3



More information about the R-devel mailing list