* readline/terminal.c (_rl_get_screen_size): Get console size from
[external/binutils.git] / readline / terminal.c
1 /* terminal.c -- controlling the terminal with termcap. */
2
3 /* Copyright (C) 1996 Free Software Foundation, Inc.
4
5    This file is part of the GNU Readline Library, a library for
6    reading lines of text with interactive input and history editing.
7
8    The GNU Readline Library is free software; you can redistribute it
9    and/or modify it under the terms of the GNU General Public License
10    as published by the Free Software Foundation; either version 2, or
11    (at your option) any later version.
12
13    The GNU Readline Library is distributed in the hope that it will be
14    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    The GNU General Public License is often shipped with GNU software, and
19    is generally kept in a file called COPYING or LICENSE.  If you do not
20    have a copy of the license, write to the Free Software Foundation,
21    59 Temple Place, Suite 330, Boston, MA 02111 USA. */
22 #define READLINE_LIBRARY
23
24 #if defined (HAVE_CONFIG_H)
25 #  include <config.h>
26 #endif
27
28 #include <sys/types.h>
29 #include "posixstat.h"
30 #include <fcntl.h>
31 #if defined (HAVE_SYS_FILE_H)
32 #  include <sys/file.h>
33 #endif /* HAVE_SYS_FILE_H */
34
35 #if defined (HAVE_UNISTD_H)
36 #  include <unistd.h>
37 #endif /* HAVE_UNISTD_H */
38
39 #if defined (HAVE_STDLIB_H)
40 #  include <stdlib.h>
41 #else
42 #  include "ansi_stdlib.h"
43 #endif /* HAVE_STDLIB_H */
44
45 #if defined (HAVE_LOCALE_H)
46 #  include <locale.h>
47 #endif
48
49 #include <stdio.h>
50
51 /* System-specific feature definitions and include files. */
52 #include "rldefs.h"
53
54 #if defined (GWINSZ_IN_SYS_IOCTL) && !defined (TIOCGWINSZ)
55 #  include <sys/ioctl.h>
56 #endif /* GWINSZ_IN_SYS_IOCTL && !TIOCGWINSZ */
57
58 #ifdef __MSDOS__
59 # include <pc.h>
60 #endif
61
62 #include "rltty.h"
63 #include "tcap.h"
64
65 /* Some standard library routines. */
66 #include "readline.h"
67 #include "history.h"
68
69 #include "rlprivate.h"
70 #include "rlshell.h"
71 #include "xmalloc.h"
72
73 #if defined (__MINGW32__)
74 # include <windows.h>
75 # include <wincon.h>
76 #endif
77
78 #define CUSTOM_REDISPLAY_FUNC() (rl_redisplay_function != rl_redisplay)
79 #define CUSTOM_INPUT_FUNC() (rl_getc_function != rl_getc)
80
81 /* **************************************************************** */
82 /*                                                                  */
83 /*                      Terminal and Termcap                        */
84 /*                                                                  */
85 /* **************************************************************** */
86
87 #ifndef __MSDOS__
88 static char *term_buffer = (char *)NULL;
89 static char *term_string_buffer = (char *)NULL;
90
91 /* Non-zero means this terminal can't really do anything. */
92 static int dumb_term;
93 #endif /* !__MSDOS__ */
94
95 static int tcap_initialized;
96
97 #if !defined (__linux__)
98 #  if defined (__EMX__) || defined (NEED_EXTERN_PC)
99 extern 
100 #  endif /* __EMX__ || NEED_EXTERN_PC */
101 char PC, *BC, *UP;
102 #endif /* __linux__ */
103
104 /* Some strings to control terminal actions.  These are output by tputs (). */
105 char *_rl_term_clreol;
106 char *_rl_term_clrpag;
107 char *_rl_term_cr;
108 char *_rl_term_backspace;
109 char *_rl_term_goto;
110 char *_rl_term_pc;
111
112 /* Non-zero if we determine that the terminal can do character insertion. */
113 int _rl_terminal_can_insert = 0;
114
115 /* How to insert characters. */
116 char *_rl_term_im;
117 char *_rl_term_ei;
118 char *_rl_term_ic;
119 char *_rl_term_ip;
120 char *_rl_term_IC;
121
122 /* How to delete characters. */
123 char *_rl_term_dc;
124 char *_rl_term_DC;
125
126 #if defined (HACK_TERMCAP_MOTION)
127 char *_rl_term_forward_char;
128 #endif  /* HACK_TERMCAP_MOTION */
129
130 /* How to go up a line. */
131 char *_rl_term_up;
132
133 /* A visible bell; char if the terminal can be made to flash the screen. */
134 static char *_rl_visible_bell;
135
136 /* Non-zero means the terminal can auto-wrap lines. */
137 int _rl_term_autowrap;
138
139 /* Non-zero means that this terminal has a meta key. */
140 static int term_has_meta;
141
142 /* The sequences to write to turn on and off the meta key, if this
143    terminal has one. */
144 static char *_rl_term_mm;
145 static char *_rl_term_mo;
146
147 /* The key sequences output by the arrow keys, if this terminal has any. */
148 static char *_rl_term_ku;
149 static char *_rl_term_kd;
150 static char *_rl_term_kr;
151 static char *_rl_term_kl;
152
153 /* How to initialize and reset the arrow keys, if this terminal has any. */
154 static char *_rl_term_ks;
155 static char *_rl_term_ke;
156
157 /* The key sequences sent by the Home and End keys, if any. */
158 static char *_rl_term_kh;
159 static char *_rl_term_kH;
160 static char *_rl_term_at7;      /* @7 */
161
162 /* Insert key */
163 static char *_rl_term_kI;
164
165 /* Cursor control */
166 static char *_rl_term_vs;       /* very visible */
167 static char *_rl_term_ve;       /* normal */
168
169 static void bind_termcap_arrow_keys PARAMS((Keymap));
170
171 /* Variables that hold the screen dimensions, used by the display code. */
172 int _rl_screenwidth, _rl_screenheight, _rl_screenchars;
173
174 /* Non-zero means the user wants to enable the keypad. */
175 int _rl_enable_keypad;
176
177 /* Non-zero means the user wants to enable a meta key. */
178 int _rl_enable_meta = 1;
179
180 #if defined (__EMX__)
181 static void
182 _emx_get_screensize (swp, shp)
183      int *swp, *shp;
184 {
185   int sz[2];
186
187   _scrsize (sz);
188
189   if (swp)
190     *swp = sz[0];
191   if (shp)
192     *shp = sz[1];
193 }
194 #endif
195
196 /* Get readline's idea of the screen size.  TTY is a file descriptor open
197    to the terminal.  If IGNORE_ENV is true, we do not pay attention to the
198    values of $LINES and $COLUMNS.  The tests for TERM_STRING_BUFFER being
199    non-null serve to check whether or not we have initialized termcap. */
200 void
201 _rl_get_screen_size (tty, ignore_env)
202      int tty, ignore_env;
203 {
204   char *ss;
205 #if defined (TIOCGWINSZ)
206   struct winsize window_size;
207 #endif /* TIOCGWINSZ */
208
209 #if defined (TIOCGWINSZ)
210   if (ioctl (tty, TIOCGWINSZ, &window_size) == 0)
211     {
212       _rl_screenwidth = (int) window_size.ws_col;
213       _rl_screenheight = (int) window_size.ws_row;
214     }
215 #endif /* TIOCGWINSZ */
216
217   /* For MinGW, we get the console size from the Windows API.  */
218 #if defined (__MINGW32__)
219   HANDLE hConOut = GetStdHandle (STD_OUTPUT_HANDLE);
220   if (hConOut != INVALID_HANDLE_VALUE)
221     {
222       CONSOLE_SCREEN_BUFFER_INFO scr;
223       if (GetConsoleScreenBufferInfo (hConOut, &scr))
224         {
225           _rl_screenwidth = scr.dwSize.X;
226           _rl_screenheight = scr.srWindow.Bottom - scr.srWindow.Top + 1;
227         }
228     }
229 #endif
230
231 #if defined (__EMX__)
232   _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight);
233 #endif
234
235   /* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV
236      is unset. */
237   if (_rl_screenwidth <= 0)
238     {
239       if (ignore_env == 0 && (ss = sh_get_env_value ("COLUMNS")))
240         _rl_screenwidth = atoi (ss);
241
242 #if defined (__DJGPP__)
243       if (_rl_screenwidth <= 0)
244         _rl_screenwidth = ScreenCols ();
245 #else
246       if (_rl_screenwidth <= 0 && term_string_buffer)
247         _rl_screenwidth = tgetnum ("co");
248 #endif
249     }
250
251   /* Environment variable LINES overrides setting of "li" if IGNORE_ENV
252      is unset. */
253   if (_rl_screenheight <= 0)
254     {
255       if (ignore_env == 0 && (ss = sh_get_env_value ("LINES")))
256         _rl_screenheight = atoi (ss);
257
258 #if defined (__DJGPP__)
259       if (_rl_screenheight <= 0)
260         _rl_screenheight = ScreenRows ();
261 #else
262       if (_rl_screenheight <= 0 && term_string_buffer)
263         _rl_screenheight = tgetnum ("li");
264 #endif
265     }
266
267   /* If all else fails, default to 80x24 terminal. */
268   if (_rl_screenwidth <= 1)
269     _rl_screenwidth = 80;
270
271   if (_rl_screenheight <= 0)
272     _rl_screenheight = 24;
273
274   /* If we're being compiled as part of bash, set the environment
275      variables $LINES and $COLUMNS to new values.  Otherwise, just
276      do a pair of putenv () or setenv () calls. */
277   sh_set_lines_and_columns (_rl_screenheight, _rl_screenwidth);
278
279   if (_rl_term_autowrap == 0)
280     _rl_screenwidth--;
281
282   _rl_screenchars = _rl_screenwidth * _rl_screenheight;
283 }
284
285 void
286 _rl_set_screen_size (rows, cols)
287      int rows, cols;
288 {
289   if (rows == 0 || cols == 0)
290     return;
291
292   _rl_screenheight = rows;
293   _rl_screenwidth = cols;
294
295   if (_rl_term_autowrap == 0)
296     _rl_screenwidth--;
297
298   _rl_screenchars = _rl_screenwidth * _rl_screenheight;
299 }
300
301 void
302 rl_set_screen_size (rows, cols)
303      int rows, cols;
304 {
305   _rl_set_screen_size (rows, cols);
306 }
307
308 void
309 rl_get_screen_size (rows, cols)
310      int *rows, *cols;
311 {
312   if (rows)
313     *rows = _rl_screenheight;
314   if (cols)
315     *cols = _rl_screenwidth;
316 }
317      
318 void
319 rl_resize_terminal ()
320 {
321   if (readline_echoing_p)
322     {
323       _rl_get_screen_size (fileno (rl_instream), 1);
324       if (CUSTOM_REDISPLAY_FUNC ())
325         rl_forced_update_display ();
326       else
327         _rl_redisplay_after_sigwinch ();
328     }
329 }
330
331 struct _tc_string {
332      const char *tc_var;
333      char **tc_value;
334 };
335
336 /* This should be kept sorted, just in case we decide to change the
337    search algorithm to something smarter. */
338 static struct _tc_string tc_strings[] =
339 {
340   { "@7", &_rl_term_at7 },
341   { "DC", &_rl_term_DC },
342   { "IC", &_rl_term_IC },
343   { "ce", &_rl_term_clreol },
344   { "cl", &_rl_term_clrpag },
345   { "cr", &_rl_term_cr },
346   { "dc", &_rl_term_dc },
347   { "ei", &_rl_term_ei },
348   { "ic", &_rl_term_ic },
349   { "im", &_rl_term_im },
350   { "kH", &_rl_term_kH },       /* home down ?? */
351   { "kI", &_rl_term_kI },       /* insert */
352   { "kd", &_rl_term_kd },
353   { "ke", &_rl_term_ke },       /* end keypad mode */
354   { "kh", &_rl_term_kh },       /* home */
355   { "kl", &_rl_term_kl },
356   { "kr", &_rl_term_kr },
357   { "ks", &_rl_term_ks },       /* start keypad mode */
358   { "ku", &_rl_term_ku },
359   { "le", &_rl_term_backspace },
360   { "mm", &_rl_term_mm },
361   { "mo", &_rl_term_mo },
362 #if defined (HACK_TERMCAP_MOTION)
363   { "nd", &_rl_term_forward_char },
364 #endif
365   { "pc", &_rl_term_pc },
366   { "up", &_rl_term_up },
367   { "vb", &_rl_visible_bell },
368   { "vs", &_rl_term_vs },
369   { "ve", &_rl_term_ve },
370 };
371
372 #define NUM_TC_STRINGS (sizeof (tc_strings) / sizeof (struct _tc_string))
373
374 /* Read the desired terminal capability strings into BP.  The capabilities
375    are described in the TC_STRINGS table. */
376 static void
377 get_term_capabilities (bp)
378      char **bp;
379 {
380 #if !defined (__DJGPP__)        /* XXX - doesn't DJGPP have a termcap library? */
381   register int i;
382
383   for (i = 0; i < NUM_TC_STRINGS; i++)
384 #  ifdef __LCC__
385     *(tc_strings[i].tc_value) = tgetstr ((char *)tc_strings[i].tc_var, bp);
386 #  else
387     *(tc_strings[i].tc_value) = tgetstr (tc_strings[i].tc_var, bp);
388 #  endif
389 #endif
390   tcap_initialized = 1;
391 }
392
393 int
394 _rl_init_terminal_io (terminal_name)
395      const char *terminal_name;
396 {
397   const char *term;
398   char *buffer;
399   int tty, tgetent_ret;
400
401   term = terminal_name ? terminal_name : sh_get_env_value ("TERM");
402   _rl_term_clrpag = _rl_term_cr = _rl_term_clreol = (char *)NULL;
403   tty = rl_instream ? fileno (rl_instream) : 0;
404   _rl_screenwidth = _rl_screenheight = 0;
405
406   if (term == 0)
407     term = "dumb";
408
409 #ifdef __MSDOS__
410   _rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL;
411   _rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL;
412   _rl_term_ku = _rl_term_kd = _rl_term_kl = _rl_term_kr = (char *)NULL;
413   _rl_term_mm = _rl_term_mo = (char *)NULL;
414   _rl_terminal_can_insert = term_has_meta = _rl_term_autowrap = 0;
415   _rl_term_cr = "\r";
416   _rl_term_clreol = _rl_term_clrpag = _rl_term_backspace = (char *)NULL;
417   _rl_term_goto = _rl_term_pc = _rl_term_ip = (char *)NULL;
418   _rl_term_ks = _rl_term_ke =_rl_term_vs = _rl_term_ve = (char *)NULL;
419   _rl_term_kh = _rl_term_kH = _rl_term_at7 = _rl_term_kI = (char *)NULL;
420 #if defined(HACK_TERMCAP_MOTION)
421   _rl_term_forward_char = (char *)NULL;
422 #endif
423
424   _rl_get_screen_size (tty, 0);
425 #else  /* !__MSDOS__ */
426   /* I've separated this out for later work on not calling tgetent at all
427      if the calling application has supplied a custom redisplay function,
428      (and possibly if the application has supplied a custom input function). */
429   if (CUSTOM_REDISPLAY_FUNC())
430     {
431       tgetent_ret = -1;
432     }
433   else
434     {
435       if (term_string_buffer == 0)
436         term_string_buffer = (char *)xmalloc(2032);
437
438       if (term_buffer == 0)
439         term_buffer = (char *)xmalloc(4080);
440
441       buffer = term_string_buffer;
442
443       tgetent_ret = tgetent (term_buffer, term);
444     }
445
446   if (tgetent_ret <= 0)
447     {
448       FREE (term_string_buffer);
449       FREE (term_buffer);
450       buffer = term_buffer = term_string_buffer = (char *)NULL;
451
452       _rl_term_autowrap = 0;    /* used by _rl_get_screen_size */
453
454 #if defined (__EMX__)
455       _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight);
456       _rl_screenwidth--;
457 #else /* !__EMX__ */
458       _rl_get_screen_size (tty, 0);
459 #endif /* !__EMX__ */
460
461       /* Defaults. */
462       if (_rl_screenwidth <= 0 || _rl_screenheight <= 0)
463         {
464           _rl_screenwidth = 79;
465           _rl_screenheight = 24;
466         }
467
468       /* Everything below here is used by the redisplay code (tputs). */
469       _rl_screenchars = _rl_screenwidth * _rl_screenheight;
470       _rl_term_cr = "\r";
471       _rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL;
472       _rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL;
473       _rl_term_ku = _rl_term_kd = _rl_term_kl = _rl_term_kr = (char *)NULL;
474       _rl_term_kh = _rl_term_kH = _rl_term_kI = (char *)NULL;
475       _rl_term_ks = _rl_term_ke = _rl_term_at7 = (char *)NULL;
476       _rl_term_mm = _rl_term_mo = (char *)NULL;
477       _rl_term_ve = _rl_term_vs = (char *)NULL;
478 #if defined (HACK_TERMCAP_MOTION)
479       term_forward_char = (char *)NULL;
480 #endif
481       _rl_terminal_can_insert = term_has_meta = 0;
482
483       /* Reasonable defaults for tgoto().  Readline currently only uses
484          tgoto if _rl_term_IC or _rl_term_DC is defined, but just in case we
485          change that later... */
486       PC = '\0';
487       BC = _rl_term_backspace = "\b";
488       UP = _rl_term_up;
489
490       return 0;
491     }
492
493   get_term_capabilities (&buffer);
494
495   /* Set up the variables that the termcap library expects the application
496      to provide. */
497   PC = _rl_term_pc ? *_rl_term_pc : 0;
498   BC = _rl_term_backspace;
499   UP = _rl_term_up;
500
501   if (!_rl_term_cr)
502     _rl_term_cr = "\r";
503
504   _rl_term_autowrap = tgetflag ("am") && tgetflag ("xn");
505
506   _rl_get_screen_size (tty, 0);
507
508   /* "An application program can assume that the terminal can do
509       character insertion if *any one of* the capabilities `IC',
510       `im', `ic' or `ip' is provided."  But we can't do anything if
511       only `ip' is provided, so... */
512   _rl_terminal_can_insert = (_rl_term_IC || _rl_term_im || _rl_term_ic);
513
514   /* Check to see if this terminal has a meta key and clear the capability
515      variables if there is none. */
516   term_has_meta = (tgetflag ("km") || tgetflag ("MT"));
517   if (!term_has_meta)
518     _rl_term_mm = _rl_term_mo = (char *)NULL;
519
520 #endif /* !__MSDOS__ */
521
522   /* Attempt to find and bind the arrow keys.  Do not override already
523      bound keys in an overzealous attempt, however. */
524
525   bind_termcap_arrow_keys (emacs_standard_keymap);
526
527 #if defined (VI_MODE)
528   bind_termcap_arrow_keys (vi_movement_keymap);
529   bind_termcap_arrow_keys (vi_insertion_keymap);
530 #endif /* VI_MODE */
531
532   return 0;
533 }
534
535 /* Bind the arrow key sequences from the termcap description in MAP. */
536 static void
537 bind_termcap_arrow_keys (map)
538      Keymap map;
539 {
540   Keymap xkeymap;
541
542   xkeymap = _rl_keymap;
543   _rl_keymap = map;
544
545   _rl_bind_if_unbound (_rl_term_ku, rl_get_previous_history);
546   _rl_bind_if_unbound (_rl_term_kd, rl_get_next_history);
547   _rl_bind_if_unbound (_rl_term_kr, rl_forward);
548   _rl_bind_if_unbound (_rl_term_kl, rl_backward);
549
550   _rl_bind_if_unbound (_rl_term_kh, rl_beg_of_line);    /* Home */
551   _rl_bind_if_unbound (_rl_term_at7, rl_end_of_line);   /* End */
552
553   _rl_keymap = xkeymap;
554 }
555
556 char *
557 rl_get_termcap (cap)
558      const char *cap;
559 {
560   register int i;
561
562   if (tcap_initialized == 0)
563     return ((char *)NULL);
564   for (i = 0; i < NUM_TC_STRINGS; i++)
565     {
566       if (tc_strings[i].tc_var[0] == cap[0] && strcmp (tc_strings[i].tc_var, cap) == 0)
567         return *(tc_strings[i].tc_value);
568     }
569   return ((char *)NULL);
570 }
571
572 /* Re-initialize the terminal considering that the TERM/TERMCAP variable
573    has changed. */
574 int
575 rl_reset_terminal (terminal_name)
576      const char *terminal_name;
577 {
578   _rl_init_terminal_io (terminal_name);
579   return 0;
580 }
581
582 /* A function for the use of tputs () */
583 #ifdef _MINIX
584 void
585 _rl_output_character_function (c)
586      int c;
587 {
588   putc (c, _rl_out_stream);
589 }
590 #else /* !_MINIX */
591 int
592 _rl_output_character_function (c)
593      int c;
594 {
595   return putc (c, _rl_out_stream);
596 }
597 #endif /* !_MINIX */
598
599 /* Write COUNT characters from STRING to the output stream. */
600 void
601 _rl_output_some_chars (string, count)
602      const char *string;
603      int count;
604 {
605   fwrite (string, 1, count, _rl_out_stream);
606 }
607
608 /* Move the cursor back. */
609 int
610 _rl_backspace (count)
611      int count;
612 {
613   register int i;
614
615 #ifndef __MSDOS__
616   if (_rl_term_backspace)
617     for (i = 0; i < count; i++)
618       tputs (_rl_term_backspace, 1, _rl_output_character_function);
619   else
620 #endif
621     for (i = 0; i < count; i++)
622       putc ('\b', _rl_out_stream);
623   return 0;
624 }
625
626 /* Move to the start of the next line. */
627 int
628 rl_crlf ()
629 {
630 #if defined (NEW_TTY_DRIVER)
631   if (_rl_term_cr)
632     tputs (_rl_term_cr, 1, _rl_output_character_function);
633 #endif /* NEW_TTY_DRIVER */
634   putc ('\n', _rl_out_stream);
635   return 0;
636 }
637
638 /* Ring the terminal bell. */
639 int
640 rl_ding ()
641 {
642   if (readline_echoing_p)
643     {
644       switch (_rl_bell_preference)
645         {
646         case NO_BELL:
647         default:
648           break;
649         case VISIBLE_BELL:
650 #ifdef __MSDOS__
651           ScreenVisualBell ();
652           break;
653 #else
654           if (_rl_visible_bell)
655             {
656               tputs (_rl_visible_bell, 1, _rl_output_character_function);
657               break;
658             }
659 #endif
660           /* FALLTHROUGH */
661         case AUDIBLE_BELL:
662           fprintf (stderr, "\007");
663           fflush (stderr);
664           break;
665         }
666       return (0);
667     }
668   return (-1);
669 }
670
671 /* **************************************************************** */
672 /*                                                                  */
673 /*              Controlling the Meta Key and Keypad                 */
674 /*                                                                  */
675 /* **************************************************************** */
676
677 void
678 _rl_enable_meta_key ()
679 {
680 #if !defined (__DJGPP__)
681   if (term_has_meta && _rl_term_mm)
682     tputs (_rl_term_mm, 1, _rl_output_character_function);
683 #endif
684 }
685
686 void
687 _rl_control_keypad (on)
688      int on;
689 {
690 #if !defined (__DJGPP__)
691   if (on && _rl_term_ks)
692     tputs (_rl_term_ks, 1, _rl_output_character_function);
693   else if (!on && _rl_term_ke)
694     tputs (_rl_term_ke, 1, _rl_output_character_function);
695 #endif
696 }
697
698 /* **************************************************************** */
699 /*                                                                  */
700 /*                      Controlling the Cursor                      */
701 /*                                                                  */
702 /* **************************************************************** */
703
704 /* Set the cursor appropriately depending on IM, which is one of the
705    insert modes (insert or overwrite).  Insert mode gets the normal
706    cursor.  Overwrite mode gets a very visible cursor.  Only does
707    anything if we have both capabilities. */
708 void
709 _rl_set_cursor (im, force)
710      int im, force;
711 {
712 #ifndef __MSDOS__
713   if (_rl_term_ve && _rl_term_vs)
714     {
715       if (force || im != rl_insert_mode)
716         {
717           if (im == RL_IM_OVERWRITE)
718             tputs (_rl_term_vs, 1, _rl_output_character_function);
719           else
720             tputs (_rl_term_ve, 1, _rl_output_character_function);
721         }
722     }
723 #endif
724 }