On Sun, 17 Jun 2018 17:29:31 +0200, Mark Kettenis wrote:

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

This turns out to be simpler than expected.  Now whenever TERM is
set (including at startup) it will call setupterm().

 - todd

Index: bin/ksh/Makefile
===================================================================
RCS file: /cvs/src/bin/ksh/Makefile,v
retrieving revision 1.38
diff -u -p -u -r1.38 Makefile
--- bin/ksh/Makefile    6 Jan 2018 16:28:58 -0000       1.38
+++ bin/ksh/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: bin/ksh/edit.c
===================================================================
RCS file: /cvs/src/bin/ksh/edit.c,v
retrieving revision 1.65
diff -u -p -u -r1.65 edit.c
--- bin/ksh/edit.c      9 Apr 2018 17:53:36 -0000       1.65
+++ bin/ksh/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: bin/ksh/edit.h
===================================================================
RCS file: /cvs/src/bin/ksh/edit.h,v
retrieving revision 1.11
diff -u -p -u -r1.11 edit.h
--- bin/ksh/edit.h      26 Jan 2016 17:39:31 -0000      1.11
+++ bin/ksh/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: bin/ksh/emacs.c
===================================================================
RCS file: /cvs/src/bin/ksh/emacs.c,v
retrieving revision 1.84
diff -u -p -u -r1.84 emacs.c
--- bin/ksh/emacs.c     16 Jan 2018 17:17:18 -0000      1.84
+++ bin/ksh/emacs.c     17 Jun 2018 21:43:56 -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,20 @@ x_redraw(int limit)
        char    *cp;
 
        x_adj_ok = 0;
-       if (limit == -1)
+       if (limit == -2) {
+               int cleared = 0;
+#ifndef SMALL
+               if (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: bin/ksh/ksh.1
===================================================================
RCS file: /cvs/src/bin/ksh/ksh.1,v
retrieving revision 1.200
diff -u -p -u -r1.200 ksh.1
--- bin/ksh/ksh.1       30 May 2018 21:20:52 -0000      1.200
+++ bin/ksh/ksh.1       17 Jun 2018 21:49:14 -0000
@@ -4690,6 +4690,11 @@ 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:
+Clears the screen if the
+.Ev TERM
+parameter is set and the terminal supports clearing the screen, then
+reprints the prompt string and the 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
Index: bin/ksh/table.h
===================================================================
RCS file: /cvs/src/bin/ksh/table.h,v
retrieving revision 1.14
diff -u -p -u -r1.14 table.h
--- bin/ksh/table.h     9 Apr 2018 17:53:36 -0000       1.14
+++ bin/ksh/table.h     17 Jun 2018 21:35:49 -0000
@@ -170,6 +170,7 @@ extern const struct builtin shbuiltins [
 #define        V_TMOUT                 16
 #define        V_TMPDIR                17
 #define        V_LINENO                18
+#define        V_TERM                  19
 
 /* values for set_prompt() */
 #define PS1    0               /* command */
Index: bin/ksh/var.c
===================================================================
RCS file: /cvs/src/bin/ksh/var.c,v
retrieving revision 1.68
diff -u -p -u -r1.68 var.c
--- bin/ksh/var.c       13 Apr 2018 18:18:36 -0000      1.68
+++ bin/ksh/var.c       17 Jun 2018 21:42:39 -0000
@@ -11,6 +11,9 @@
 #include <string.h>
 #include <time.h>
 #include <unistd.h>
+#ifndef SMALL
+# include <term.h>
+#endif
 
 #include "sh.h"
 
@@ -111,12 +114,13 @@ initvar(void)
                { "SECONDS",            V_SECONDS },
                { "TMOUT",              V_TMOUT },
                { "LINENO",             V_LINENO },
+               { "TERM",               V_TERM },
                { NULL, 0 }
        };
        int i;
        struct tbl *tp;
 
-       ktinit(&specials, APERM, 32); /* must be 2^n (currently 17 specials) */
+       ktinit(&specials, APERM, 32); /* must be 2^n (currently 19 specials) */
        for (i = 0; names[i].name; i++) {
                tp = ktenter(&specials, names[i].name, hash(names[i].name));
                tp->flag = DEFINED|ISSET;
@@ -1056,6 +1060,17 @@ setspec(struct tbl *vp)
                /* The -1 is because line numbering starts at 1. */
                user_lineno = (unsigned int) intval(vp) - current_lineno - 1;
                vp->flag |= SPECIAL;
+               break;
+       case V_TERM:
+#ifndef SMALL
+               {
+                       int errret;
+
+                       vp->flag &= ~SPECIAL;
+                       (void)setupterm(str_val(vp), 1, &errret);
+                       vp->flag |= SPECIAL;
+               }
+#endif
                break;
        }
 }

Reply via email to