Allow wide characters (properly encoded as byte strings according to LC_CTYPE)
to be (perhaps part of) the "invisible" characters in a prompt, or the required prompt character which follows the literal sequence (this character must be one with a printing column width >= 1). The literal indicator character (which is just a marker, and not printed anywhere) (the PSlit parameter in sh(1)) can also be a wide char (passed to libedit as a wchar_t, encoded as that by sh(1) or other applications that support this.) Note: this has currently only been tested with everything ascii (C locale).
This commit is contained in:
parent
5ca98f2167
commit
e3112e6cea
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: Makefile,v 1.64 2017/06/27 23:25:13 christos Exp $
|
||||
# $NetBSD: Makefile,v 1.65 2017/06/30 20:26:52 kre Exp $
|
||||
# @(#)Makefile 8.1 (Berkeley) 6/4/93
|
||||
|
||||
USE_SHLIBDIR= yes
|
||||
|
@ -133,6 +133,7 @@ tc1: libedit.a tc1.o
|
|||
# XXX
|
||||
.if defined(HAVE_GCC)
|
||||
COPTS.editline.c+= -Wno-cast-qual
|
||||
COPTS.literal.c+= -Wno-sign-conversion
|
||||
COPTS.tokenizer.c+= -Wno-cast-qual
|
||||
COPTS.tokenizern.c+= -Wno-cast-qual
|
||||
.endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: literal.c,v 1.2 2017/06/29 02:54:40 kre Exp $ */
|
||||
/* $NetBSD: literal.c,v 1.3 2017/06/30 20:26:52 kre Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2017 The NetBSD Foundation, Inc.
|
||||
|
@ -31,7 +31,7 @@
|
|||
|
||||
#include "config.h"
|
||||
#if !defined(lint) && !defined(SCCSID)
|
||||
__RCSID("$NetBSD: literal.c,v 1.2 2017/06/29 02:54:40 kre Exp $");
|
||||
__RCSID("$NetBSD: literal.c,v 1.3 2017/06/30 20:26:52 kre Exp $");
|
||||
#endif /* not lint && not SCCSID */
|
||||
|
||||
/*
|
||||
|
@ -47,15 +47,14 @@ libedit_private void
|
|||
literal_init(EditLine *el)
|
||||
{
|
||||
el_literal_t *l = &el->el_literal;
|
||||
|
||||
memset(l, 0, sizeof(*l));
|
||||
}
|
||||
|
||||
libedit_private void
|
||||
literal_end(EditLine *el)
|
||||
{
|
||||
el_literal_t *l = &el->el_literal;
|
||||
literal_clear(el);
|
||||
el_free(l->l_buf);
|
||||
}
|
||||
|
||||
libedit_private void
|
||||
|
@ -63,33 +62,60 @@ literal_clear(EditLine *el)
|
|||
{
|
||||
el_literal_t *l = &el->el_literal;
|
||||
size_t i;
|
||||
|
||||
if (l->l_len == 0)
|
||||
return;
|
||||
|
||||
for (i = 0; i < l->l_idx; i++)
|
||||
el_free(l->l_buf[i]);
|
||||
el_free(l->l_buf);
|
||||
l->l_buf = NULL;
|
||||
l->l_len = 0;
|
||||
l->l_idx = 0;
|
||||
}
|
||||
|
||||
libedit_private wint_t
|
||||
literal_add(EditLine *el, const wchar_t *buf, const wchar_t *end)
|
||||
literal_add(EditLine *el, const wchar_t *buf, const wchar_t *end, int *wp)
|
||||
{
|
||||
// XXX: Only for narrow chars now.
|
||||
el_literal_t *l = &el->el_literal;
|
||||
size_t i, len;
|
||||
ssize_t w, n;
|
||||
char *b;
|
||||
|
||||
w = wcwidth(end[1]); /* column width of the visible char */
|
||||
*wp = (int)w;
|
||||
|
||||
if (w <= 0) /* we require something to be printed */
|
||||
return 0;
|
||||
|
||||
len = (size_t)(end - buf);
|
||||
b = el_malloc(len + 2);
|
||||
for (w = 0, i = 0; i < len; i++)
|
||||
w += ct_enc_width(buf[i]);
|
||||
w += ct_enc_width(end[1]);
|
||||
|
||||
b = el_malloc((size_t)(w + 1));
|
||||
if (b == NULL)
|
||||
return 0;
|
||||
for (i = 0; i < len; i++)
|
||||
b[i] = (char)buf[i];
|
||||
b[len] = (char)end[1];
|
||||
b[len + 1] = '\0';
|
||||
|
||||
for (n = 0, i = 0; i < len; i++)
|
||||
n += ct_encode_char(b + n, w - n, buf[i]);
|
||||
n += ct_encode_char(b + n, w - n, end[1]);
|
||||
b[n] = '\0';
|
||||
|
||||
/*
|
||||
* Then save this literal string in the list of such strings,
|
||||
* and return a "magic character" to put into the terminal buffer.
|
||||
* When that magic char is 'printed' the saved string (which includes
|
||||
* the char that belongs in that position) gets sent instead.
|
||||
*/
|
||||
if (l->l_idx == l->l_len) {
|
||||
l->l_len += 10;
|
||||
char **bp = el_realloc(l->l_buf, sizeof(*l->l_buf) * l->l_len);
|
||||
char **bp;
|
||||
|
||||
l->l_len += 4;
|
||||
bp = el_realloc(l->l_buf, sizeof(*l->l_buf) * l->l_len);
|
||||
if (bp == NULL) {
|
||||
free(b);
|
||||
l->l_len -= 4;
|
||||
return 0;
|
||||
}
|
||||
l->l_buf = bp;
|
||||
|
@ -102,6 +128,7 @@ libedit_private const char *
|
|||
literal_get(EditLine *el, wint_t idx)
|
||||
{
|
||||
el_literal_t *l = &el->el_literal;
|
||||
|
||||
assert(idx & EL_LITERAL);
|
||||
idx &= ~EL_LITERAL;
|
||||
assert(l->l_idx > (size_t)idx);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: literal.h,v 1.1 2017/06/27 23:25:13 christos Exp $ */
|
||||
/* $NetBSD: literal.h,v 1.2 2017/06/30 20:26:52 kre Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2017 The NetBSD Foundation, Inc.
|
||||
|
@ -47,7 +47,7 @@ libedit_private void literal_init(EditLine *);
|
|||
libedit_private void literal_end(EditLine *);
|
||||
libedit_private void literal_clear(EditLine *);
|
||||
libedit_private wint_t literal_add(EditLine *, const wchar_t *,
|
||||
const wchar_t *);
|
||||
const wchar_t *, int *);
|
||||
libedit_private const char *literal_get(EditLine *, wint_t);
|
||||
|
||||
#endif /* _h_el_literal */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: refresh.c,v 1.53 2017/06/27 23:29:12 christos Exp $ */
|
||||
/* $NetBSD: refresh.c,v 1.54 2017/06/30 20:26:52 kre Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -37,7 +37,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)refresh.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: refresh.c,v 1.53 2017/06/27 23:29:12 christos Exp $");
|
||||
__RCSID("$NetBSD: refresh.c,v 1.54 2017/06/30 20:26:52 kre Exp $");
|
||||
#endif
|
||||
#endif /* not lint && not SCCSID */
|
||||
|
||||
|
@ -164,12 +164,20 @@ re_putliteral(EditLine *el, const wchar_t *begin, const wchar_t *end)
|
|||
coord_t *cur = &el->el_refresh.r_cursor;
|
||||
wint_t c;
|
||||
int sizeh = el->el_terminal.t_size.h;
|
||||
int i, w;
|
||||
|
||||
c = literal_add(el, begin, end);
|
||||
if (c == 0)
|
||||
c = literal_add(el, begin, end, &w);
|
||||
if (c == 0 || w <= 0)
|
||||
return;
|
||||
el->el_vdisplay[cur->v][cur->h] = c;
|
||||
cur->h += 1; /* XXX: only for narrow */
|
||||
|
||||
i = w;
|
||||
if (i > sizeh - cur->h) /* avoid overflow */
|
||||
i = sizeh - cur->h;
|
||||
while (--i > 0)
|
||||
el->el_vdisplay[cur->v][cur->h + i] = MB_FILL_CHAR;
|
||||
|
||||
cur->h += w;
|
||||
if (cur->h >= sizeh) {
|
||||
/* assure end of line */
|
||||
el->el_vdisplay[cur->v][sizeh] = '\0';
|
||||
|
|
Loading…
Reference in New Issue