• Completely overhaul prompt length calculation and
prompt display routines; make Emacs and Vi share code, permitting reducing of duplication and code removal as well as more consistent behaviour; put some common code into shared helper functions, too • New x_adjust() logic (Emacs mode): when determining what portion of a line to render use a much more sophisticated algorithm and try to fill up ⅔ of the total screen width (with line and prompt both) also as wished from Steffen Daode Nurpmeso
This commit is contained in:
parent
472bc350b5
commit
247e20c524
6
check.t
6
check.t
|
@ -1,4 +1,4 @@
|
|||
# $MirOS: src/bin/mksh/check.t,v 1.624 2013/07/25 18:07:44 tg Exp $
|
||||
# $MirOS: src/bin/mksh/check.t,v 1.625 2013/07/26 20:33:35 tg Exp $
|
||||
# $OpenBSD: bksl-nl.t,v 1.2 2001/01/28 23:04:56 niklas Exp $
|
||||
# $OpenBSD: history.t,v 1.5 2001/01/28 23:04:56 niklas Exp $
|
||||
# $OpenBSD: read.t,v 1.3 2003/03/10 03:48:16 david Exp $
|
||||
|
@ -31,7 +31,7 @@
|
|||
# http://www.freebsd.org/cgi/cvsweb.cgi/src/tools/regression/bin/test/regress.sh?rev=HEAD
|
||||
|
||||
expected-stdout:
|
||||
@(#)MIRBSD KSH R47 2013/07/25
|
||||
@(#)MIRBSD KSH R47 2013/07/26
|
||||
description:
|
||||
Check version of shell.
|
||||
stdin:
|
||||
|
@ -40,7 +40,7 @@ name: KSH_VERSION
|
|||
category: shell:legacy-no
|
||||
---
|
||||
expected-stdout:
|
||||
@(#)LEGACY KSH R47 2013/07/25
|
||||
@(#)LEGACY KSH R47 2013/07/26
|
||||
description:
|
||||
Check version of legacy shell.
|
||||
stdin:
|
||||
|
|
157
edit.c
157
edit.c
|
@ -28,7 +28,7 @@
|
|||
|
||||
#ifndef MKSH_NO_CMDLINE_EDITING
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.267 2013/06/03 22:27:42 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.268 2013/07/26 20:33:37 tg Exp $");
|
||||
|
||||
/*
|
||||
* in later versions we might use libtermcap for this, but since external
|
||||
|
@ -919,7 +919,6 @@ static bool x_adj_ok;
|
|||
*/
|
||||
static int x_adj_done; /* is incremented by x_adjust() */
|
||||
|
||||
static int x_col;
|
||||
static int x_displen;
|
||||
static int x_arg; /* general purpose arg */
|
||||
static bool x_arg_defaulted; /* x_arg not explicitly set; defaulted to 1 */
|
||||
|
@ -944,9 +943,6 @@ static int x_curprefix;
|
|||
static char *macroptr; /* bind key macro active? */
|
||||
#endif
|
||||
#if !MKSH_S_NOVI
|
||||
static int cur_col; /* current column on line */
|
||||
static int pwidth; /* width of prompt */
|
||||
static int prompt_trunc; /* how much of prompt to truncate */
|
||||
static int winwidth; /* width of window */
|
||||
static char *wbuf[2]; /* window buffers */
|
||||
static int wbuf_len; /* length of window buffers (x_cols - 3) */
|
||||
|
@ -955,13 +951,16 @@ static char morec; /* more character at right of window */
|
|||
static int lastref; /* argument to last refresh() */
|
||||
static int holdlen; /* length of holdbuf */
|
||||
#endif
|
||||
static bool prompt_redraw; /* false if newline forced after prompt */
|
||||
static int pwidth; /* width of prompt */
|
||||
static int prompt_trunc; /* how much of prompt to truncate or -1 */
|
||||
static int x_col; /* current column on line */
|
||||
|
||||
static int x_ins(const char *);
|
||||
static void x_delete(size_t, bool);
|
||||
static size_t x_bword(void);
|
||||
static size_t x_fword(bool);
|
||||
static void x_goto(char *);
|
||||
static char *x_bs0(char *, char *);
|
||||
static void x_bs3(char **);
|
||||
static int x_size_str(char *);
|
||||
static int x_size2(char *, char **);
|
||||
|
@ -1170,20 +1169,14 @@ x_e_getmbc(char *sbuf)
|
|||
static void
|
||||
x_init_prompt(void)
|
||||
{
|
||||
x_col = promptlen(prompt);
|
||||
x_adj_ok = true;
|
||||
prompt_redraw = true;
|
||||
if (x_col >= xx_cols)
|
||||
x_col %= xx_cols;
|
||||
x_displen = xx_cols - 2 - x_col;
|
||||
x_adj_done = 0;
|
||||
|
||||
pprompt(prompt, 0);
|
||||
if (x_displen < 1) {
|
||||
x_col = 0;
|
||||
x_displen = xx_cols - 2;
|
||||
prompt_trunc = pprompt(prompt, 0);
|
||||
pwidth = prompt_trunc % x_cols;
|
||||
prompt_trunc -= pwidth;
|
||||
if ((mksh_uari_t)pwidth > ((mksh_uari_t)x_cols - 3 - MIN_EDIT_SPACE)) {
|
||||
/* force newline after prompt */
|
||||
prompt_trunc = -1;
|
||||
pwidth = 0;
|
||||
x_e_putc2('\n');
|
||||
prompt_redraw = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1202,8 +1195,10 @@ x_emacs(char *buf, size_t len)
|
|||
x_histp = histptr + 1;
|
||||
x_last_command = XFUNC_error;
|
||||
|
||||
xx_cols = x_cols;
|
||||
x_init_prompt();
|
||||
x_displen = (xx_cols = x_cols) - 2 - (x_col = pwidth);
|
||||
x_adj_done = 0;
|
||||
x_adj_ok = true;
|
||||
|
||||
x_histncp = NULL;
|
||||
if (x_nextcmd >= 0) {
|
||||
|
@ -1561,11 +1556,7 @@ x_fword(bool move)
|
|||
static void
|
||||
x_goto(char *cp)
|
||||
{
|
||||
if (cp >= xep)
|
||||
cp = xep;
|
||||
else if (UTFMODE)
|
||||
while ((cp > xbuf) && ((*cp & 0xC0) == 0x80))
|
||||
--cp;
|
||||
cp = cp >= xep ? xep : x_bs0(cp, xbuf);
|
||||
if (cp < xbp || cp >= utf_skipcols(xbp, x_displen)) {
|
||||
/* we are heading off screen */
|
||||
xcp = cp;
|
||||
|
@ -1581,16 +1572,22 @@ x_goto(char *cp)
|
|||
}
|
||||
}
|
||||
|
||||
static char *
|
||||
x_bs0(char *cp, char *lower_bound)
|
||||
{
|
||||
if (UTFMODE)
|
||||
while ((!lower_bound || (cp > lower_bound)) &&
|
||||
((*(unsigned char *)cp & 0xC0) == 0x80))
|
||||
--cp;
|
||||
return (cp);
|
||||
}
|
||||
|
||||
static void
|
||||
x_bs3(char **p)
|
||||
{
|
||||
int i;
|
||||
|
||||
(*p)--;
|
||||
if (UTFMODE)
|
||||
while (((unsigned char)**p & 0xC0) == 0x80)
|
||||
(*p)--;
|
||||
|
||||
*p = x_bs0((*p) - 1, NULL);
|
||||
i = x_size2(*p, NULL);
|
||||
while (i--)
|
||||
x_e_putc2('\b');
|
||||
|
@ -2080,7 +2077,7 @@ x_cls(int c MKSH_A_UNUSED)
|
|||
static void
|
||||
x_redraw(int limit)
|
||||
{
|
||||
int i, j, x_trunc = 0;
|
||||
int i, j;
|
||||
char *cp;
|
||||
|
||||
x_adj_ok = false;
|
||||
|
@ -2090,19 +2087,11 @@ x_redraw(int limit)
|
|||
x_e_putc2('\r');
|
||||
x_flush();
|
||||
if (xbp == xbuf) {
|
||||
x_col = promptlen(prompt);
|
||||
if (x_col >= xx_cols)
|
||||
x_trunc = (x_col / xx_cols) * xx_cols;
|
||||
if (prompt_redraw)
|
||||
pprompt(prompt, x_trunc);
|
||||
if (prompt_trunc != -1)
|
||||
pprompt(prompt, prompt_trunc);
|
||||
x_col = pwidth;
|
||||
}
|
||||
if (x_col >= xx_cols)
|
||||
x_col %= xx_cols;
|
||||
x_displen = xx_cols - 2 - x_col;
|
||||
if (x_displen < 1) {
|
||||
x_col = 0;
|
||||
x_displen = xx_cols - 2;
|
||||
}
|
||||
xlp_valid = false;
|
||||
x_zots(xbp);
|
||||
if (xbp != xbuf || xep > xlp)
|
||||
|
@ -2816,16 +2805,42 @@ do_complete(
|
|||
static void
|
||||
x_adjust(void)
|
||||
{
|
||||
/* flag the fact that we were called. */
|
||||
int col_left, n;
|
||||
|
||||
/* flag the fact that we were called */
|
||||
x_adj_done++;
|
||||
|
||||
/*
|
||||
* we had a problem if the prompt length > xx_cols / 2
|
||||
* calculate the amount of columns we need to "go back"
|
||||
* from xcp to set xbp to (but never < xbuf) to 2/3 of
|
||||
* the display width; take care of pwidth though
|
||||
*/
|
||||
if ((xbp = xcp - (x_displen / 2)) < xbuf)
|
||||
xbp = xbuf;
|
||||
if (UTFMODE)
|
||||
while ((xbp > xbuf) && ((*xbp & 0xC0) == 0x80))
|
||||
--xbp;
|
||||
if ((col_left = xx_cols * 2 / 3) < MIN_EDIT_SPACE) {
|
||||
/*
|
||||
* cowardly refuse to do anything
|
||||
* if the available space is too small;
|
||||
* fall back to dumb pdksh code
|
||||
*/
|
||||
if ((xbp = xcp - (x_displen / 2)) < xbuf)
|
||||
xbp = xbuf;
|
||||
/* elide UTF-8 fixup as penalty */
|
||||
goto x_adjust_out;
|
||||
}
|
||||
|
||||
/* fix up xbp to character begin first */
|
||||
xbp = x_bs0(xcp, xbuf);
|
||||
/* walk backwards */
|
||||
while (xbp > xbuf && col_left > 0) {
|
||||
xbp = x_bs0(xbp - 1, xbuf);
|
||||
col_left -= (n = x_size2(xbp, NULL));
|
||||
}
|
||||
/* check if we hit the prompt */
|
||||
if (xbp == xbuf && xcp != xbuf && col_left > 0 && col_left < pwidth) {
|
||||
/* so we did; force scrolling occurs */
|
||||
xbp += utf_ptradj(xbp);
|
||||
}
|
||||
|
||||
x_adjust_out:
|
||||
xlp_valid = false;
|
||||
x_redraw(xx_cols);
|
||||
x_flush();
|
||||
|
@ -3517,18 +3532,8 @@ x_vi(char *buf, size_t len)
|
|||
es->cursor = undo->cursor = 0;
|
||||
es->winleft = undo->winleft = 0;
|
||||
|
||||
cur_col = promptlen(prompt);
|
||||
prompt_trunc = (cur_col / x_cols) * x_cols;
|
||||
cur_col -= prompt_trunc;
|
||||
|
||||
pprompt(prompt, 0);
|
||||
if ((mksh_uari_t)cur_col > (mksh_uari_t)x_cols - 3 - MIN_EDIT_SPACE) {
|
||||
prompt_redraw = false;
|
||||
cur_col = 0;
|
||||
x_putc('\n');
|
||||
} else
|
||||
prompt_redraw = true;
|
||||
pwidth = cur_col;
|
||||
x_init_prompt();
|
||||
x_col = pwidth;
|
||||
|
||||
if (!wbuf_len || wbuf_len != x_cols - 3) {
|
||||
wbuf_len = x_cols - 3;
|
||||
|
@ -5057,9 +5062,9 @@ redraw_line(bool newl)
|
|||
x_putc('\r');
|
||||
x_putc('\n');
|
||||
}
|
||||
if (prompt_redraw)
|
||||
if (prompt_trunc != -1)
|
||||
pprompt(prompt, prompt_trunc);
|
||||
cur_col = pwidth;
|
||||
x_col = pwidth;
|
||||
morec = ' ';
|
||||
}
|
||||
|
||||
|
@ -5177,10 +5182,10 @@ display(char *wb1, char *wb2, int leftside)
|
|||
twb2 = wb2;
|
||||
while (cnt--) {
|
||||
if (*twb1 != *twb2) {
|
||||
if (cur_col != col)
|
||||
if (x_col != col)
|
||||
ed_mov_opt(col, wb1);
|
||||
x_putc(*twb1);
|
||||
cur_col++;
|
||||
x_col++;
|
||||
}
|
||||
twb1++;
|
||||
twb2++;
|
||||
|
@ -5201,34 +5206,34 @@ display(char *wb1, char *wb2, int leftside)
|
|||
if (mc != morec) {
|
||||
ed_mov_opt(pwidth + winwidth + 1, wb1);
|
||||
x_putc(mc);
|
||||
cur_col++;
|
||||
x_col++;
|
||||
morec = mc;
|
||||
}
|
||||
if (cur_col != ncol)
|
||||
if (x_col != ncol)
|
||||
ed_mov_opt(ncol, wb1);
|
||||
}
|
||||
|
||||
static void
|
||||
ed_mov_opt(int col, char *wb)
|
||||
{
|
||||
if (col < cur_col) {
|
||||
if (col + 1 < cur_col - col) {
|
||||
if (col < x_col) {
|
||||
if (col + 1 < x_col - col) {
|
||||
x_putc('\r');
|
||||
if (prompt_redraw)
|
||||
if (prompt_trunc != -1)
|
||||
pprompt(prompt, prompt_trunc);
|
||||
cur_col = pwidth;
|
||||
while (cur_col++ < col)
|
||||
x_col = pwidth;
|
||||
while (x_col++ < col)
|
||||
x_putcf(*wb++);
|
||||
} else {
|
||||
while (cur_col-- > col)
|
||||
while (x_col-- > col)
|
||||
x_putc('\b');
|
||||
}
|
||||
} else {
|
||||
wb = &wb[cur_col - pwidth];
|
||||
while (cur_col++ < col)
|
||||
wb = &wb[x_col - pwidth];
|
||||
while (x_col++ < col)
|
||||
x_putcf(*wb++);
|
||||
}
|
||||
cur_col = col;
|
||||
x_col = col;
|
||||
}
|
||||
|
||||
|
||||
|
|
30
lex.c
30
lex.c
|
@ -23,7 +23,7 @@
|
|||
|
||||
#include "sh.h"
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.186 2013/06/01 00:15:57 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.187 2013/07/26 20:33:38 tg Exp $");
|
||||
|
||||
/*
|
||||
* states while lexing word
|
||||
|
@ -102,8 +102,6 @@ static void gethere(bool);
|
|||
static Lex_state *push_state_i(State_info *, Lex_state *);
|
||||
static Lex_state *pop_state_i(State_info *, Lex_state *);
|
||||
|
||||
static int dopprompt(const char *, int, bool);
|
||||
|
||||
static int backslash_skip;
|
||||
static int ignore_backslash_newline;
|
||||
|
||||
|
@ -1520,8 +1518,8 @@ set_prompt(int to, Source *s)
|
|||
}
|
||||
}
|
||||
|
||||
static int
|
||||
dopprompt(const char *cp, int ntruncate, bool doprint)
|
||||
int
|
||||
pprompt(const char *cp, int ntruncate)
|
||||
{
|
||||
int columns = 0, lines = 0;
|
||||
bool indelimit = false;
|
||||
|
@ -1554,35 +1552,21 @@ dopprompt(const char *cp, int ntruncate, bool doprint)
|
|||
else if (UTFMODE && ((unsigned char)*cp > 0x7F)) {
|
||||
const char *cp2;
|
||||
columns += utf_widthadj(cp, &cp2);
|
||||
if (doprint && (indelimit ||
|
||||
(ntruncate < (x_cols * lines + columns))))
|
||||
if (indelimit ||
|
||||
(ntruncate < (x_cols * lines + columns)))
|
||||
shf_write(cp, cp2 - cp, shl_out);
|
||||
cp = cp2 - /* loop increment */ 1;
|
||||
continue;
|
||||
} else
|
||||
columns++;
|
||||
if (doprint && (*cp != delimiter) &&
|
||||
if ((*cp != delimiter) &&
|
||||
(indelimit || (ntruncate < (x_cols * lines + columns))))
|
||||
shf_putc(*cp, shl_out);
|
||||
}
|
||||
if (doprint)
|
||||
shf_flush(shl_out);
|
||||
shf_flush(shl_out);
|
||||
return (x_cols * lines + columns);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
pprompt(const char *cp, int ntruncate)
|
||||
{
|
||||
dopprompt(cp, ntruncate, true);
|
||||
}
|
||||
|
||||
int
|
||||
promptlen(const char *cp)
|
||||
{
|
||||
return (dopprompt(cp, 0, false));
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the variable part of a ${...} expression (i.e. up to but not
|
||||
* including the :[-+?=#%] or close-brace).
|
||||
|
|
11
sh.h
11
sh.h
|
@ -164,9 +164,9 @@
|
|||
#endif
|
||||
|
||||
#ifdef EXTERN
|
||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.662 2013/07/25 18:07:47 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.663 2013/07/26 20:33:39 tg Exp $");
|
||||
#endif
|
||||
#define MKSH_VERSION "R47 2013/07/25"
|
||||
#define MKSH_VERSION "R47 2013/07/26"
|
||||
|
||||
/* arithmetic types: C implementation */
|
||||
#if !HAVE_CAN_INTTYPES
|
||||
|
@ -444,8 +444,6 @@ extern int wcwidth(__WCHAR_TYPE__);
|
|||
#define MAGIC (7) /* prefix for *?[!{,} during expand */
|
||||
#define ISMAGIC(c) ((unsigned char)(c) == MAGIC)
|
||||
|
||||
#define LINE 4096 /* input line size */
|
||||
|
||||
EXTERN const char *safe_prompt; /* safe prompt if PS1 substitution fails */
|
||||
|
||||
#ifdef MKSH_LEGACY_MODE
|
||||
|
@ -992,6 +990,8 @@ EXTERN uint32_t builtin_flag;
|
|||
/* current working directory */
|
||||
EXTERN char *current_wd;
|
||||
|
||||
/* input line size */
|
||||
#define LINE 4096
|
||||
/*
|
||||
* Minimum required space to work with on a line - if the prompt leaves
|
||||
* less space than this on a line, the prompt is truncated.
|
||||
|
@ -1837,8 +1837,7 @@ void yyerror(const char *, ...)
|
|||
MKSH_A_FORMAT(__printf__, 1, 2);
|
||||
Source *pushs(int, Area *);
|
||||
void set_prompt(int, Source *);
|
||||
void pprompt(const char *, int);
|
||||
int promptlen(const char *);
|
||||
int pprompt(const char *, int);
|
||||
/* main.c */
|
||||
int include(const char *, int, const char **, bool);
|
||||
int command(const char *, int);
|
||||
|
|
Loading…
Reference in New Issue