> 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 > >