From 790c312e9fda6c3e5354ff47e33810f5c594646b Mon Sep 17 00:00:00 2001 From: tg Date: Wed, 2 Aug 2006 11:33:37 +0000 Subject: [PATCH] fix the prompt redrawal routines for multi-line prompts, prompts with embedded newline (\n), and multi-line prompts with embedded newlines. single-line prompts should be not affected; prompts with embedded carriage return (\r) should be fixed by this as well. also fix prompt_redraw comment (can't remove the variable though, since it's required if the shell inserts a newline after the prompt herself). tested on cygwin and interix --- edit.c | 33 ++++++++++----------------------- lex.c | 33 +++++++++++++-------------------- sh.h | 4 ++-- 3 files changed, 25 insertions(+), 45 deletions(-) diff --git a/edit.c b/edit.c index 9834fa7..73032f3 100644 --- a/edit.c +++ b/edit.c @@ -5,7 +5,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.28 2006/08/01 14:59:50 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.29 2006/08/02 11:33:36 tg Exp $"); /* tty driver characters we are interested in */ typedef struct { @@ -915,8 +915,7 @@ static char *macroptr; 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 prompt_skip; /* how much of prompt to skip */ -static int prompt_redraw; /* do we need to redraw the prompt? */ +static int prompt_redraw; /* 0 if newline forced after prompt */ static int winwidth; /* width of window */ static char *wbuf[2]; /* window buffers */ static int wbuf_len; /* length of window buffers (x_cols-3)*/ @@ -1220,9 +1219,7 @@ static struct x_defbindings const x_defbindings[] = { int x_emacs(char *buf, size_t len) { - int c; - const char *p; - int i; + int c, i; u_char f; xbp = xbuf = buf; xend = buf + len; @@ -1236,8 +1233,7 @@ x_emacs(char *buf, size_t len) x_last_command = XFUNC_error; xx_cols = x_cols; - x_col = promptlen(prompt, &p); - prompt_skip = p - prompt; + x_col = promptlen(prompt); x_adj_ok = 1; prompt_redraw = 1; if (x_col > xx_cols) @@ -1934,11 +1930,11 @@ x_redraw(int limit) x_e_putc('\r'); x_flush(); if (xbp == xbuf) { - x_col = promptlen(prompt, NULL); + x_col = promptlen(prompt); if (x_col > xx_cols) x_trunc = (x_col / xx_cols) * xx_cols; if (prompt_redraw) - pprompt(prompt + prompt_skip, x_trunc); + pprompt(prompt, x_trunc); } if (x_col > xx_cols) x_col %= xx_cols; @@ -2934,7 +2930,6 @@ static int complete_word(int, int); static int print_expansions(struct edstate *, int); static int char_len(int); static void x_vi_zotc(int); -static void vi_pprompt(int); static void vi_error(void); static void vi_macro_reset(void); static int x_vi_putbuf(const char *, size_t); @@ -3067,7 +3062,7 @@ x_vi(char *buf, size_t len) int c; vi_reset(buf, len > LINE ? LINE : len); - vi_pprompt(1); + pprompt(prompt, prompt_trunc); x_flush(); while (1) { if (macro.p) { @@ -4282,7 +4277,6 @@ free_edstate(struct edstate *old) static void edit_reset(char *buf, size_t len) { - const char *p; es = &ebuf; es->cbuf = buf; @@ -4294,8 +4288,7 @@ edit_reset(char *buf, size_t len) es->cursor = undo->cursor = 0; es->winleft = undo->winleft = 0; - cur_col = pwidth = promptlen(prompt, &p); - prompt_skip = p - prompt; + cur_col = pwidth = promptlen(prompt); if (pwidth > x_cols - 3 - MIN_EDIT_SPACE) { cur_col = x_cols - 3 - MIN_EDIT_SPACE; prompt_trunc = pwidth - cur_col; @@ -4581,7 +4574,7 @@ redraw_line(int newl) x_putc('\r'); x_putc('\n'); } - vi_pprompt(0); + pprompt(prompt, prompt_trunc); cur_col = pwidth; morec = ' '; } @@ -4746,7 +4739,7 @@ ed_mov_opt(int col, char *wb) if (col < cur_col) { if (col + 1 < cur_col - col) { x_putc('\r'); - vi_pprompt(0); + pprompt(prompt, prompt_trunc); cur_col = pwidth; while (cur_col++ < col) x_putc(*wb++); @@ -4976,12 +4969,6 @@ x_vi_zotc(int c) x_putc(c); } -static void -vi_pprompt(int full) -{ - pprompt(prompt + (full ? 0 : prompt_skip), prompt_trunc); -} - static void vi_error(void) { diff --git a/lex.c b/lex.c index c435a68..fc8bbb1 100644 --- a/lex.c +++ b/lex.c @@ -2,7 +2,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.20 2006/08/02 10:42:30 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.21 2006/08/02 11:33:37 tg Exp $"); /* Structure to keep track of the lexing state and the various pieces of info * needed for each particular state. */ @@ -58,7 +58,7 @@ static void gethere(void); static Lex_state *push_state_(State_info *, Lex_state *); static Lex_state *pop_state_(State_info *, Lex_state *); -static int dopprompt(const char *, int, const char **, int); +static int dopprompt(const char *, int, int); static int backslash_skip; static int ignore_backslash_newline; @@ -1088,12 +1088,10 @@ set_prompt(int to, Source *s) } static int -dopprompt(const char *cp, int ntruncate, const char **spp, int doprint) +dopprompt(const char *cp, int ntruncate, int doprint) { - int columns = 0, lines = 0; - const char *sp = cp; + int columns = 0, lines = 0, indelimit = 0; char delimiter = 0; - int indelimit = 0; /* Undocumented AT&T ksh feature: * If the second char in the prompt string is \r then the first char @@ -1109,9 +1107,8 @@ dopprompt(const char *cp, int ntruncate, const char **spp, int doprint) if (indelimit && *cp != delimiter) ; else if (*cp == '\n' || *cp == '\r') { + lines += columns / x_cols + ((*cp == '\n') ? 1 : 0); columns = 0; - ++lines; - sp = cp + 1; } else if (*cp == '\t') { columns = (columns | 7) + 1; } else if (*cp == '\b') { @@ -1121,31 +1118,27 @@ dopprompt(const char *cp, int ntruncate, const char **spp, int doprint) indelimit = !indelimit; else columns++; - if (*cp != delimiter) { - if (ntruncate && !indelimit) - --ntruncate; - else if (doprint) - shf_putc(*cp, shl_out); - } + if (doprint && (*cp != delimiter) && + (indelimit || (ntruncate < (x_cols * lines + columns)))) + shf_putc(*cp, shl_out); } - if (spp) - *spp = sp; if (doprint) shf_flush(shl_out); - return (columns + (lines * x_cols)); + indelimit = (x_cols * lines + columns); + return indelimit; } void pprompt(const char *cp, int ntruncate) { - dopprompt(cp, ntruncate, NULL, 1); + dopprompt(cp, ntruncate, 1); } int -promptlen(const char *cp, const char **spp) +promptlen(const char *cp) { - return (dopprompt(cp, 0, spp, 0)); + return (dopprompt(cp, 0, 0)); } /* Read the variable part of a ${...} expression (ie, up to but not including diff --git a/sh.h b/sh.h index 1eab8b5..c437454 100644 --- a/sh.h +++ b/sh.h @@ -8,7 +8,7 @@ /* $OpenBSD: c_test.h,v 1.4 2004/12/20 11:34:26 otto Exp $ */ /* $OpenBSD: tty.h,v 1.5 2004/12/20 11:34:26 otto Exp $ */ -#define MKSH_SH_H_ID "$MirOS: src/bin/mksh/sh.h,v 1.30 2006/08/01 14:10:25 tg Exp $" +#define MKSH_SH_H_ID "$MirOS: src/bin/mksh/sh.h,v 1.31 2006/08/02 11:33:37 tg Exp $" #include @@ -1081,7 +1081,7 @@ void yyerror(const char *, ...) Source * pushs(int, Area *); void set_prompt(int, Source *); void pprompt(const char *, int); -int promptlen(const char *, const char **); +int promptlen(const char *); /* main.c */ int include(const char *, int, char **, int); int command(const char *);