From 905b699ab74c6b029cf5fd158a35030546fcd0ed Mon Sep 17 00:00:00 2001 From: christos Date: Thu, 31 Oct 2002 02:01:46 +0000 Subject: [PATCH] support for % command [matching parens/brackets/braces] on vi modes. From David Laight, thanks! --- lib/libedit/map.c | 6 +++--- lib/libedit/vi.c | 52 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/lib/libedit/map.c b/lib/libedit/map.c index 422fa5bcaefd..5f8ac5bdc204 100644 --- a/lib/libedit/map.c +++ b/lib/libedit/map.c @@ -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 @@ -41,7 +41,7 @@ #if 0 static char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/4/93"; #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 /* not lint && not SCCSID */ @@ -668,7 +668,7 @@ private const el_action_t el_map_vi_command[] = { /* 34 */ ED_UNASSIGNED, /* " */ /* 35 */ ED_UNASSIGNED, /* # */ /* 36 */ ED_MOVE_TO_END, /* $ */ - /* 37 */ ED_UNASSIGNED, /* % */ + /* 37 */ VI_MATCH, /* % */ /* 38 */ ED_UNASSIGNED, /* & */ /* 39 */ ED_UNASSIGNED, /* ' */ /* 40 */ ED_UNASSIGNED, /* ( */ diff --git a/lib/libedit/vi.c b/lib/libedit/vi.c index 846a3dcb8c6a..badaf8665022 100644 --- a/lib/libedit/vi.c +++ b/lib/libedit/vi.c @@ -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 @@ -41,7 +41,7 @@ #if 0 static char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93"; #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 /* 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_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); +}