slightly optimised and, more importantly, much more consistent (use only
one set of CTRL, UNCTRL, and new ISCTRL macros) C0 and DEL handling; the optimisation only works for 7-bit ASCII, so those places 8-bit must pass intact have an added check also, while here, remove an editor oops (‘;’), oksh rcsid sync (they did accept I was right wrt. set -e), int → bool, and code merge/cleanup
This commit is contained in:
105
edit.c
105
edit.c
@ -1,4 +1,4 @@
|
||||
;/* $OpenBSD: edit.c,v 1.38 2013/06/03 15:41:59 tedu Exp $ */
|
||||
/* $OpenBSD: edit.c,v 1.38 2013/06/03 15:41:59 tedu Exp $ */
|
||||
/* $OpenBSD: edit.h,v 1.9 2011/05/30 17:14:35 martynas Exp $ */
|
||||
/* $OpenBSD: emacs.c,v 1.44 2011/09/05 04:50:33 marco Exp $ */
|
||||
/* $OpenBSD: vi.c,v 1.26 2009/06/29 22:50:19 martynas Exp $ */
|
||||
@ -28,7 +28,7 @@
|
||||
|
||||
#ifndef MKSH_NO_CMDLINE_EDITING
|
||||
|
||||
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.271 2013/08/16 10:59:01 tg Exp $");
|
||||
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.272 2013/09/24 20:19:42 tg Exp $");
|
||||
|
||||
/*
|
||||
* in later versions we might use libtermcap for this, but since external
|
||||
@ -966,7 +966,6 @@ static void x_bs3(char **);
|
||||
static int x_size_str(char *);
|
||||
static int x_size2(char *, char **);
|
||||
static void x_zots(char *);
|
||||
static void x_zotc2(int);
|
||||
static void x_zotc3(char **);
|
||||
static void x_load_hist(char **);
|
||||
static int x_search(char *, int, int);
|
||||
@ -1608,7 +1607,7 @@ x_size_str(char *cp)
|
||||
static int
|
||||
x_size2(char *cp, char **dcp)
|
||||
{
|
||||
int c = *(unsigned char *)cp;
|
||||
uint8_t c = *(unsigned char *)cp;
|
||||
|
||||
if (UTFMODE && (c > 0x7F))
|
||||
return (utf_widthadj(cp, (const char **)dcp));
|
||||
@ -1617,7 +1616,7 @@ x_size2(char *cp, char **dcp)
|
||||
if (c == '\t')
|
||||
/* Kludge, tabs are always four spaces. */
|
||||
return (4);
|
||||
if (c < ' ' || c == 0x7f)
|
||||
if (ISCTRL(c) && /* but not C1 */ c < 0x80)
|
||||
/* control unsigned char */
|
||||
return (2);
|
||||
return (1);
|
||||
@ -1633,19 +1632,6 @@ x_zots(char *str)
|
||||
x_zotc3(&str);
|
||||
}
|
||||
|
||||
static void
|
||||
x_zotc2(int c)
|
||||
{
|
||||
if (c == '\t') {
|
||||
/* Kludge, tabs are always four spaces. */
|
||||
x_e_puts(" ");
|
||||
} else if (c < ' ' || c == 0x7f) {
|
||||
x_e_putc2('^');
|
||||
x_e_putc2(UNCTRL(c));
|
||||
} else
|
||||
x_e_putc2(c);
|
||||
}
|
||||
|
||||
static void
|
||||
x_zotc3(char **cp)
|
||||
{
|
||||
@ -1655,7 +1641,7 @@ x_zotc3(char **cp)
|
||||
/* Kludge, tabs are always four spaces. */
|
||||
x_e_puts(" ");
|
||||
(*cp)++;
|
||||
} else if (c < ' ' || c == 0x7f) {
|
||||
} else if (ISCTRL(c) && /* but not C1 */ c < 0x80) {
|
||||
x_e_putc2('^');
|
||||
x_e_putc2(UNCTRL(c));
|
||||
(*cp)++;
|
||||
@ -1767,7 +1753,10 @@ x_newline(int c MKSH_A_UNUSED)
|
||||
static int
|
||||
x_end_of_text(int c MKSH_A_UNUSED)
|
||||
{
|
||||
x_zotc2(edchars.eof);
|
||||
char tmp = edchars.eof;
|
||||
char *cp = &tmp;
|
||||
|
||||
x_zotc3(&cp);
|
||||
x_putc('\r');
|
||||
x_putc('\n');
|
||||
x_flush();
|
||||
@ -2379,6 +2368,7 @@ x_mapin(const char *cp, Area *ap)
|
||||
/* XXX -- should handle \^ escape? */
|
||||
if (*cp == '^') {
|
||||
cp++;
|
||||
/*XXX or ^^ escape? this is ugly. */
|
||||
if (*cp >= '?')
|
||||
/* includes '?'; ASCII */
|
||||
*op++ = CTRL(*cp);
|
||||
@ -2400,7 +2390,7 @@ x_mapout2(int c, char **buf)
|
||||
{
|
||||
char *p = *buf;
|
||||
|
||||
if (c < ' ' || c == 0x7f) {
|
||||
if (ISCTRL(c)) {
|
||||
*p++ = '^';
|
||||
*p++ = UNCTRL(c);
|
||||
} else
|
||||
@ -3343,8 +3333,6 @@ x_mode(bool onoff)
|
||||
#if !MKSH_S_NOVI
|
||||
/* +++ vi editing mode +++ */
|
||||
|
||||
#define Ctrl(c) (c&0x1f)
|
||||
|
||||
struct edstate {
|
||||
char *cbuf;
|
||||
ssize_t winleft;
|
||||
@ -3378,13 +3366,14 @@ static void redraw_line(bool);
|
||||
static void refresh(int);
|
||||
static int outofwin(void);
|
||||
static void rewindow(void);
|
||||
static int newcol(int, int);
|
||||
static int newcol(unsigned char, int);
|
||||
static void display(char *, char *, int);
|
||||
static void ed_mov_opt(int, char *);
|
||||
static int expand_word(int);
|
||||
static int complete_word(int, int);
|
||||
static int print_expansions(struct edstate *, int);
|
||||
#define char_len(c) ((c) < ' ' || (c) == 0x7F ? 2 : 1)
|
||||
#define char_len(c) ((ISCTRL((unsigned char)c) && \
|
||||
/* but not C1 */ (unsigned char)c < 0x80) ? 2 : 1)
|
||||
static void x_vi_zotc(int);
|
||||
static void vi_error(void);
|
||||
static void vi_macro_reset(void);
|
||||
@ -3620,7 +3609,7 @@ vi_hook(int ch)
|
||||
|
||||
case VNORMAL:
|
||||
if (insert != 0) {
|
||||
if (ch == Ctrl('v')) {
|
||||
if (ch == CTRL('v')) {
|
||||
state = VLIT;
|
||||
ch = '^';
|
||||
}
|
||||
@ -3732,7 +3721,7 @@ vi_hook(int ch)
|
||||
break;
|
||||
|
||||
case VXCH:
|
||||
if (ch == Ctrl('['))
|
||||
if (ch == CTRL('['))
|
||||
state = VNORMAL;
|
||||
else {
|
||||
curcmd[cmdlen++] = ch;
|
||||
@ -3741,7 +3730,7 @@ vi_hook(int ch)
|
||||
break;
|
||||
|
||||
case VSEARCH:
|
||||
if (ch == '\r' || ch == '\n' /*|| ch == Ctrl('[')*/ ) {
|
||||
if (ch == '\r' || ch == '\n' /*|| ch == CTRL('[')*/ ) {
|
||||
restore_cbuf();
|
||||
/* Repeat last search? */
|
||||
if (srchlen == 0) {
|
||||
@ -3756,10 +3745,10 @@ vi_hook(int ch)
|
||||
memcpy(srchpat, locpat, srchlen + 1);
|
||||
}
|
||||
state = VCMD;
|
||||
} else if (ch == edchars.erase || ch == Ctrl('h')) {
|
||||
} else if (ch == edchars.erase || ch == CTRL('h')) {
|
||||
if (srchlen != 0) {
|
||||
srchlen--;
|
||||
es->linelen -= char_len((unsigned char)locpat[srchlen]);
|
||||
es->linelen -= char_len(locpat[srchlen]);
|
||||
es->cursor = es->linelen;
|
||||
refresh(0);
|
||||
return (0);
|
||||
@ -3786,7 +3775,7 @@ vi_hook(int ch)
|
||||
es = save_es;
|
||||
|
||||
for (i = srchlen; --i >= n; )
|
||||
es->linelen -= char_len((unsigned char)locpat[i]);
|
||||
es->linelen -= char_len(locpat[i]);
|
||||
srchlen = n;
|
||||
es->cursor = es->linelen;
|
||||
refresh(0);
|
||||
@ -3796,12 +3785,12 @@ vi_hook(int ch)
|
||||
vi_error();
|
||||
else {
|
||||
locpat[srchlen++] = ch;
|
||||
if (ch < ' ' || ch == 0x7f) {
|
||||
if (ISCTRL(ch) && /* but not C1 */ ch < 0x80) {
|
||||
if ((size_t)es->linelen + 2 >
|
||||
(size_t)es->cbufsize)
|
||||
vi_error();
|
||||
es->cbuf[es->linelen++] = '^';
|
||||
es->cbuf[es->linelen++] = ch ^ '@';
|
||||
es->cbuf[es->linelen++] = UNCTRL(ch);
|
||||
} else {
|
||||
if (es->linelen >= es->cbufsize)
|
||||
vi_error();
|
||||
@ -3912,7 +3901,7 @@ nextstate(int ch)
|
||||
return (VXCH);
|
||||
else if (ch == '.')
|
||||
return (VREDO);
|
||||
else if (ch == Ctrl('v'))
|
||||
else if (ch == CTRL('v'))
|
||||
return (VVERSION);
|
||||
else if (is_cmd(ch))
|
||||
return (VCMD);
|
||||
@ -3925,7 +3914,7 @@ vi_insert(int ch)
|
||||
{
|
||||
int tcursor;
|
||||
|
||||
if (ch == edchars.erase || ch == Ctrl('h')) {
|
||||
if (ch == edchars.erase || ch == CTRL('h')) {
|
||||
if (insert == REPLACE) {
|
||||
if (es->cursor == undo->cursor) {
|
||||
vi_error();
|
||||
@ -3982,7 +3971,7 @@ vi_insert(int ch)
|
||||
* buffer (if user inserts & deletes char, ibuf gets trashed and
|
||||
* we don't want to use it)
|
||||
*/
|
||||
if (first_insert && ch != Ctrl('['))
|
||||
if (first_insert && ch != CTRL('['))
|
||||
saved_inslen = 0;
|
||||
switch (ch) {
|
||||
case '\0':
|
||||
@ -3992,7 +3981,7 @@ vi_insert(int ch)
|
||||
case '\n':
|
||||
return (1);
|
||||
|
||||
case Ctrl('['):
|
||||
case CTRL('['):
|
||||
expanded = NONE;
|
||||
if (first_insert) {
|
||||
first_insert = false;
|
||||
@ -4010,19 +3999,19 @@ vi_insert(int ch)
|
||||
return (redo_insert(lastac - 1));
|
||||
|
||||
/* { Begin nonstandard vi commands */
|
||||
case Ctrl('x'):
|
||||
case CTRL('x'):
|
||||
expand_word(0);
|
||||
break;
|
||||
|
||||
case Ctrl('f'):
|
||||
case CTRL('f'):
|
||||
complete_word(0, 0);
|
||||
break;
|
||||
|
||||
case Ctrl('e'):
|
||||
case CTRL('e'):
|
||||
print_expansions(es, 0);
|
||||
break;
|
||||
|
||||
case Ctrl('i'):
|
||||
case CTRL('i'):
|
||||
if (Flag(FVITABCOMPLETE)) {
|
||||
complete_word(0, 0);
|
||||
break;
|
||||
@ -4077,8 +4066,8 @@ vi_cmd(int argcnt, const char *cmd)
|
||||
}
|
||||
switch (*cmd) {
|
||||
|
||||
case Ctrl('l'):
|
||||
case Ctrl('r'):
|
||||
case CTRL('l'):
|
||||
case CTRL('r'):
|
||||
redraw_line(true);
|
||||
break;
|
||||
|
||||
@ -4265,7 +4254,7 @@ vi_cmd(int argcnt, const char *cmd)
|
||||
|
||||
case 'j':
|
||||
case '+':
|
||||
case Ctrl('n'):
|
||||
case CTRL('n'):
|
||||
if (grabhist(modified, hnum + argcnt) < 0)
|
||||
return (-1);
|
||||
else {
|
||||
@ -4276,7 +4265,7 @@ vi_cmd(int argcnt, const char *cmd)
|
||||
|
||||
case 'k':
|
||||
case '-':
|
||||
case Ctrl('p'):
|
||||
case CTRL('p'):
|
||||
if (grabhist(modified, hnum - argcnt) < 0)
|
||||
return (-1);
|
||||
else {
|
||||
@ -4508,26 +4497,26 @@ vi_cmd(int argcnt, const char *cmd)
|
||||
/* AT&T ksh */
|
||||
case '=':
|
||||
/* Nonstandard vi/ksh */
|
||||
case Ctrl('e'):
|
||||
case CTRL('e'):
|
||||
print_expansions(es, 1);
|
||||
break;
|
||||
|
||||
|
||||
/* Nonstandard vi/ksh */
|
||||
case Ctrl('i'):
|
||||
case CTRL('i'):
|
||||
if (!Flag(FVITABCOMPLETE))
|
||||
return (-1);
|
||||
complete_word(1, argcnt);
|
||||
break;
|
||||
|
||||
/* some annoying AT&T kshs */
|
||||
case Ctrl('['):
|
||||
case CTRL('['):
|
||||
if (!Flag(FVIESCCOMPLETE))
|
||||
return (-1);
|
||||
/* AT&T ksh */
|
||||
case '\\':
|
||||
/* Nonstandard vi/ksh */
|
||||
case Ctrl('f'):
|
||||
case CTRL('f'):
|
||||
complete_word(1, argcnt);
|
||||
break;
|
||||
|
||||
@ -4535,7 +4524,7 @@ vi_cmd(int argcnt, const char *cmd)
|
||||
/* AT&T ksh */
|
||||
case '*':
|
||||
/* Nonstandard vi/ksh */
|
||||
case Ctrl('x'):
|
||||
case CTRL('x'):
|
||||
expand_word(1);
|
||||
break;
|
||||
|
||||
@ -4614,7 +4603,7 @@ domove(int argcnt, const char *cmd, int sub)
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
case Ctrl('h'):
|
||||
case CTRL('h'):
|
||||
if (!sub && es->cursor == 0)
|
||||
return (-1);
|
||||
ncursor = es->cursor - argcnt;
|
||||
@ -5030,7 +5019,7 @@ grabsearch(int save, int start, int fwd, const char *pat)
|
||||
{
|
||||
char *hptr;
|
||||
int hist;
|
||||
int anchored;
|
||||
bool anchored;
|
||||
|
||||
if ((start == 0 && fwd == 0) || (start >= hlast - 1 && fwd == 1))
|
||||
return (-1);
|
||||
@ -5038,7 +5027,7 @@ grabsearch(int save, int start, int fwd, const char *pat)
|
||||
start++;
|
||||
else
|
||||
start--;
|
||||
anchored = *pat == '^' ? (++pat, 1) : 0;
|
||||
anchored = *pat == '^' ? (++pat, true) : false;
|
||||
if ((hist = findhist(start, fwd, pat, anchored)) < 0) {
|
||||
/* (start != 0 && fwd && match(holdbufp, pat) >= 0) */
|
||||
if (start != 0 && fwd && strcmp(holdbufp, pat) >= 0) {
|
||||
@ -5127,7 +5116,7 @@ rewindow(void)
|
||||
}
|
||||
|
||||
static int
|
||||
newcol(int ch, int col)
|
||||
newcol(unsigned char ch, int col)
|
||||
{
|
||||
if (ch == '\t')
|
||||
return ((col | 7) + 1);
|
||||
@ -5155,10 +5144,10 @@ display(char *wb1, char *wb2, int leftside)
|
||||
*twb1++ = ' ';
|
||||
} while (++col < winwidth && (col & 7) != 0);
|
||||
else if (col < winwidth) {
|
||||
if (ch < ' ' || ch == 0x7f) {
|
||||
if (ISCTRL(ch) && /* but not C1 */ ch < 0x80) {
|
||||
*twb1++ = '^';
|
||||
if (++col < winwidth) {
|
||||
*twb1++ = ch ^ '@';
|
||||
*twb1++ = UNCTRL(ch);
|
||||
col++;
|
||||
}
|
||||
} else {
|
||||
@ -5435,9 +5424,9 @@ print_expansions(struct edstate *est, int cmd MKSH_A_UNUSED)
|
||||
static void
|
||||
x_vi_zotc(int c)
|
||||
{
|
||||
if (c < ' ' || c == 0x7f) {
|
||||
if (ISCTRL(c)) {
|
||||
x_putc('^');
|
||||
c ^= '@';
|
||||
c = UNCTRL(c);
|
||||
}
|
||||
x_putc(c);
|
||||
}
|
||||
|
Reference in New Issue
Block a user