support for % command [matching parens/brackets/braces] on vi modes.

From David Laight, thanks!
This commit is contained in:
christos 2002-10-31 02:01:46 +00:00
parent 293419f314
commit 905b699ab7
2 changed files with 53 additions and 5 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: map.c,v 1.16 2002/10/27 21:41:50 christos Exp $ */ /* $NetBSD: map.c,v 1.17 2002/10/31 02:01:46 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -41,7 +41,7 @@
#if 0 #if 0
static char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/4/93"; static char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/4/93";
#else #else
__RCSID("$NetBSD: map.c,v 1.16 2002/10/27 21:41:50 christos Exp $"); __RCSID("$NetBSD: map.c,v 1.17 2002/10/31 02:01:46 christos Exp $");
#endif #endif
#endif /* not lint && not SCCSID */ #endif /* not lint && not SCCSID */
@ -668,7 +668,7 @@ private const el_action_t el_map_vi_command[] = {
/* 34 */ ED_UNASSIGNED, /* " */ /* 34 */ ED_UNASSIGNED, /* " */
/* 35 */ ED_UNASSIGNED, /* # */ /* 35 */ ED_UNASSIGNED, /* # */
/* 36 */ ED_MOVE_TO_END, /* $ */ /* 36 */ ED_MOVE_TO_END, /* $ */
/* 37 */ ED_UNASSIGNED, /* % */ /* 37 */ VI_MATCH, /* % */
/* 38 */ ED_UNASSIGNED, /* & */ /* 38 */ ED_UNASSIGNED, /* & */
/* 39 */ ED_UNASSIGNED, /* ' */ /* 39 */ ED_UNASSIGNED, /* ' */
/* 40 */ ED_UNASSIGNED, /* ( */ /* 40 */ ED_UNASSIGNED, /* ( */

View File

@ -1,4 +1,4 @@
/* $NetBSD: vi.c,v 1.10 2002/10/27 21:41:50 christos Exp $ */ /* $NetBSD: vi.c,v 1.11 2002/10/31 02:01:47 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -41,7 +41,7 @@
#if 0 #if 0
static char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93"; static char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93";
#else #else
__RCSID("$NetBSD: vi.c,v 1.10 2002/10/27 21:41:50 christos Exp $"); __RCSID("$NetBSD: vi.c,v 1.11 2002/10/31 02:01:47 christos Exp $");
#endif #endif
#endif /* not lint && not SCCSID */ #endif /* not lint && not SCCSID */
@ -835,3 +835,51 @@ vi_repeat_prev_char(EditLine *el, int c)
cv_csearch_fwd(el, el->el_search.chacha, el->el_state.argument, 0) : cv_csearch_fwd(el, el->el_search.chacha, el->el_state.argument, 0) :
cv_csearch_back(el, el->el_search.chacha, el->el_state.argument, 0); cv_csearch_back(el, el->el_search.chacha, el->el_state.argument, 0);
} }
/* vi_match():
* Vi go to matching () {} or []
* [%]
*/
protected el_action_t
/*ARGSUSED*/
vi_match(EditLine *el, int c)
{
const char match_chars[] = "()[]{}";
char *cp;
int delta, i, count;
char o_ch, c_ch;
*el->el_line.lastchar = '\0'; /* just in case */
i = strcspn(el->el_line.cursor, match_chars);
o_ch = el->el_line.cursor[i];
if (o_ch == 0)
return CC_ERROR;
delta = strchr(match_chars, o_ch) - match_chars;
c_ch = match_chars[delta ^ 1];
count = 1;
delta = 1 - (delta & 1) * 2;
for (cp = &el->el_line.cursor[i]; count; ) {
cp += delta;
if (cp < el->el_line.buffer || cp >= el->el_line.lastchar)
return CC_ERROR;
if (*cp == o_ch)
count++;
else if (*cp == c_ch)
count--;
}
el->el_line.cursor = cp;
if (el->el_chared.c_vcmd.action & DELETE) {
if (delta > 0)
el->el_line.cursor++;
else
el->el_chared.c_vcmd.pos++;
cv_delfini(el);
return (CC_REFRESH);
}
return (CC_CURSOR);
}