> From: "Todd C. Miller" <todd.mil...@sudo.ws>
> Date: Sun, 17 Jun 2018 09:00:17 -0600
> 
> On Sat, 16 Jun 2018 16:16:57 -0600, "Todd C. Miller" wrote:
> 
> > On Sat, 16 Jun 2018 14:50:40 +0200, Mark Kettenis wrote:
> >
> > > To be honest, I find the whole idea of invoking an external program to
> > > clear the screen insane.
> >
> > Linking with curses doesn't increase the size a huge amount since
> > we just need to query terminfo.
> >
> > text    data    bss     dec     hex
> > 529120  12584   57024   598728  922c8   /bin/ksh
> > 595671  21904   57024   674599  a4b27   ./obj/ksh
> 
> Slightly simpler, we can use the clear_screen macro instead of looking
> it up with tigetstr().
> 
> text    data    bss     dec     hex
> 529120  12584   57024   598728  922c8   /bin/ksh
> 594844  21888   57024   673756  a47dc   ./obj/ksh

If folks indeed think that this is a must-have feature, this is
certainly a better approach.  I wonder though if the setupterm() call
should happen earlier when interactive mode is initialized?  Probably
best to link against libterminfo to indicate that we don't really want
full-blown curses.

The man page needs to be adjusted now that you no longer call clear(1).

Cheers,

Mark

> Index: Makefile
> ===================================================================
> RCS file: /cvs/src/bin/ksh/Makefile,v
> retrieving revision 1.38
> diff -u -p -u -r1.38 Makefile
> --- Makefile  6 Jan 2018 16:28:58 -0000       1.38
> +++ Makefile  16 Jun 2018 22:00:32 -0000
> @@ -1,6 +1,9 @@
>  #    $OpenBSD: Makefile,v 1.38 2018/01/06 16:28:58 millert Exp $
>  
>  PROG=        ksh
> +DPADD+=      ${LIBCURSES}
> +LDADD+=      -lcurses
> +
>  SRCS=        alloc.c c_ksh.c c_sh.c c_test.c c_ulimit.c edit.c emacs.c 
> eval.c \
>       exec.c expr.c history.c io.c jobs.c lex.c mail.c main.c \
>       misc.c path.c shf.c syn.c table.c trap.c tree.c tty.c var.c \
> Index: edit.c
> ===================================================================
> RCS file: /cvs/src/bin/ksh/edit.c,v
> retrieving revision 1.65
> diff -u -p -u -r1.65 edit.c
> --- edit.c    9 Apr 2018 17:53:36 -0000       1.65
> +++ edit.c    16 Jun 2018 22:09:17 -0000
> @@ -138,10 +138,10 @@ x_flush(void)
>       shf_flush(shl_out);
>  }
>  
> -void
> +int
>  x_putc(int c)
>  {
> -     shf_putc(c, shl_out);
> +     return shf_putc(c, shl_out);
>  }
>  
>  void
> Index: edit.h
> ===================================================================
> RCS file: /cvs/src/bin/ksh/edit.h,v
> retrieving revision 1.11
> diff -u -p -u -r1.11 edit.h
> --- edit.h    26 Jan 2016 17:39:31 -0000      1.11
> +++ edit.h    16 Jun 2018 22:09:27 -0000
> @@ -37,7 +37,7 @@ extern X_chars edchars;
>  /* edit.c */
>  int  x_getc(void);
>  void x_flush(void);
> -void x_putc(int);
> +int  x_putc(int);
>  void x_puts(const char *);
>  bool x_mode(bool);
>  int  promptlen(const char *, const char **);
> Index: emacs.c
> ===================================================================
> RCS file: /cvs/src/bin/ksh/emacs.c,v
> retrieving revision 1.84
> diff -u -p -u -r1.84 emacs.c
> --- emacs.c   16 Jan 2018 17:17:18 -0000      1.84
> +++ emacs.c   17 Jun 2018 13:58:36 -0000
> @@ -21,6 +21,10 @@
>  #include <stdio.h>
>  #include <stdlib.h>
>  #include <string.h>
> +#ifndef SMALL
> +# include <term.h>
> +# include <curses.h>
> +#endif
>  
>  #include "sh.h"
>  #include "edit.h"
> @@ -28,6 +32,7 @@
>  static       Area    aedit;
>  #define      AEDIT   &aedit          /* area for kill ring and macro defns */
>  
> +#undef CTRL
>  #define      CTRL(x)         ((x) == '?' ? 0x7F : (x) & 0x1F)        /* 
> ASCII */
>  #define      UNCTRL(x)       ((x) == 0x7F ? '?' : (x) | 0x40)        /* 
> ASCII */
>  
> @@ -146,6 +151,7 @@ static int        isu8cont(unsigned char);
>  /* proto's for keybindings */
>  static int   x_abort(int);
>  static int   x_beg_hist(int);
> +static int   x_clear_screen(int);
>  static int   x_comp_comm(int);
>  static int   x_comp_file(int);
>  static int   x_complete(int);
> @@ -202,6 +208,7 @@ static int        x_debug_info(int);
>  static const struct x_ftab x_ftab[] = {
>       { x_abort,              "abort",                        0 },
>       { x_beg_hist,           "beginning-of-history",         0 },
> +     { x_clear_screen,       "clear-screen",                 0 },
>       { x_comp_comm,          "complete-command",             0 },
>       { x_comp_file,          "complete-file",                0 },
>       { x_complete,           "complete",                     0 },
> @@ -1004,12 +1011,19 @@ x_draw_line(int c)
>  {
>       x_redraw(-1);
>       return KSTD;
> +}
>  
> +static int
> +x_clear_screen(int c)
> +{
> +     x_redraw(-2);
> +     return KSTD;
>  }
>  
> -/* Redraw (part of) the line.  If limit is < 0, the everything is redrawn
> - * on a NEW line, otherwise limit is the screen column up to which needs
> - * redrawing.
> +/* Redraw (part of) the line.
> + * A non-negative limit is the screen column up to which needs
> + * redrawing. A limit of -1 redraws on a new line, while a limit
> + * of -2 (attempts to) clear the screen.
>   */
>  static void
>  x_redraw(int limit)
> @@ -1018,9 +1032,25 @@ x_redraw(int limit)
>       char    *cp;
>  
>       x_adj_ok = 0;
> -     if (limit == -1)
> +     if (limit == -2) {
> +             int cleared = 0;
> +#ifndef SMALL
> +             char *term = str_val(global("TERM"));
> +             if (term && *term) {
> +                     int errret;
> +                     if (setupterm(term, 1, &errret) != ERR &&
> +                         clear_screen != NULL && *clear_screen != '\0') {
> +                             if (tputs(clear_screen, 1, x_putc) != ERR)
> +                                     cleared = 1;
> +                     }
> +             }
> +#endif
> +             if (!cleared)
> +                     x_e_putc('\n');
> +     }
> +     else if (limit == -1)
>               x_e_putc('\n');
> -     else
> +     else if (limit >= 0)
>               x_e_putc('\r');
>       x_flush();
>       if (xbp == xbuf) {
> Index: ksh.1
> ===================================================================
> RCS file: /cvs/src/bin/ksh/ksh.1,v
> retrieving revision 1.200
> diff -u -p -u -r1.200 ksh.1
> --- ksh.1     30 May 2018 21:20:52 -0000      1.200
> +++ ksh.1     16 Jun 2018 12:29:34 -0000
> @@ -4690,6 +4690,10 @@ Moves the cursor to the beginning of the
>  Uppercase the first character in the next
>  .Ar n
>  words, leaving the cursor past the end of the last word.
> +.It clear-screen:
> +Attempts to clears the screen by invoking
> +.Xr clear 1
> +and redraws the prompt and current input line.
>  .It comment: ^[#
>  If the current line does not begin with a comment character, one is added at
>  the beginning of the line and the line is entered (as if return had been
> 
> 

Reply via email to