diff options
author | peter <peter@FreeBSD.org> | 2013-08-11 20:03:12 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 2013-08-11 20:03:12 +0000 |
commit | 5f2a1d653696ec5457bfd044f0ebcd873bfc3c80 (patch) | |
tree | 7c1ae67d07b93aea05bfea51c590c1112b65042b /contrib/nvi/vi/v_search.c | |
parent | 324febaf01918418f99998aa5537126ac98c9df0 (diff) | |
download | FreeBSD-src-5f2a1d653696ec5457bfd044f0ebcd873bfc3c80.zip FreeBSD-src-5f2a1d653696ec5457bfd044f0ebcd873bfc3c80.tar.gz |
Update nvi-1.79 to 2.1.1-4334a8297f
This is the gsoc-2011 project to clean up and backport multibyte support
from other nvi forks in a form we can use.
USE_WIDECHAR is on unless building for the rescue crunchgen. This should
allow editing in the native locale encoding.
USE_ICONV depends on make.conf having 'WITH_ICONV=YES' for now. This
adds the ability to do things like edit a KOI8-R file while having $LANG
set to (say) en_US.UTF-8. iconv is used to transcode the characters for
display.
Other points:
* It uses gencat and catopen/etc instead of homegrown msg catalog stuff.
* A lot of stuff has been trimmed out, eg: the perl and tcl bindings which
we could never use in base anyway.
* It uses ncursesw when in widechar mode. This could be interesting.
GSoC info: http://www.google-melange.com/gsoc/proposal/review/google/gsoc2011/zy/1
Repo at: https://github.com/lichray/nvi2
Obtained from: Zhihao Yuan <lichray@gmail.com>
Diffstat (limited to 'contrib/nvi/vi/v_search.c')
-rw-r--r-- | contrib/nvi/vi/v_search.c | 121 |
1 files changed, 77 insertions, 44 deletions
diff --git a/contrib/nvi/vi/v_search.c b/contrib/nvi/vi/v_search.c index 4f7a267..1d6b260 100644 --- a/contrib/nvi/vi/v_search.c +++ b/contrib/nvi/vi/v_search.c @@ -10,7 +10,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)v_search.c 10.18 (Berkeley) 9/19/96"; +static const char sccsid[] = "$Id: v_search.c,v 10.31 2012/02/08 07:26:59 zy Exp $"; #endif /* not lint */ #include <sys/types.h> @@ -29,7 +29,7 @@ static const char sccsid[] = "@(#)v_search.c 10.18 (Berkeley) 9/19/96"; #include "vi.h" static int v_exaddr __P((SCR *, VICMD *, dir_t)); -static int v_search __P((SCR *, VICMD *, char *, size_t, u_int, dir_t)); +static int v_search __P((SCR *, VICMD *, CHAR_T *, size_t, u_int, dir_t)); /* * v_srch -- [count]?RE[? offset] @@ -38,9 +38,7 @@ static int v_search __P((SCR *, VICMD *, char *, size_t, u_int, dir_t)); * PUBLIC: int v_searchb __P((SCR *, VICMD *)); */ int -v_searchb(sp, vp) - SCR *sp; - VICMD *vp; +v_searchb(SCR *sp, VICMD *vp) { return (v_exaddr(sp, vp, BACKWARD)); } @@ -52,9 +50,7 @@ v_searchb(sp, vp) * PUBLIC: int v_searchf __P((SCR *, VICMD *)); */ int -v_searchf(sp, vp) - SCR *sp; - VICMD *vp; +v_searchf(SCR *sp, VICMD *vp) { return (v_exaddr(sp, vp, FORWARD)); } @@ -64,19 +60,19 @@ v_searchf(sp, vp) * Do a vi search (which is really an ex address). */ static int -v_exaddr(sp, vp, dir) - SCR *sp; - VICMD *vp; - dir_t dir; +v_exaddr(SCR *sp, VICMD *vp, dir_t dir) { - static EXCMDLIST fake = { "search" }; + static EXCMDLIST fake = { L("search") }; EXCMD *cmdp; GS *gp; TEXT *tp; recno_t s_lno; size_t len, s_cno, tlen; int err, nb, type; - char *cmd, *t, buf[20]; + char buf[20]; + CHAR_T *cmd, *t; + CHAR_T *w; + size_t wlen; /* * !!! @@ -93,7 +89,7 @@ v_exaddr(sp, vp, dir) (O_ISSET(sp, O_SEARCHINCR) ? TXT_SEARCHINCR : 0))) return (1); - tp = sp->tiq.cqh_first; + tp = TAILQ_FIRST(sp->tiq); /* If the user backspaced over the prompt, do nothing. */ if (tp->term == TERM_BS) @@ -245,7 +241,7 @@ v_exaddr(sp, vp, dir) /* Default to z+. */ if (!type && - v_event_push(sp, NULL, "+", 1, CH_NOMAP | CH_QUOTED)) + v_event_push(sp, NULL, L("+"), 1, CH_NOMAP | CH_QUOTED)) return (1); /* Push the user's command. */ @@ -255,7 +251,8 @@ v_exaddr(sp, vp, dir) /* Push line number so get correct z display. */ tlen = snprintf(buf, sizeof(buf), "%lu", (u_long)vp->m_stop.lno); - if (v_event_push(sp, NULL, buf, tlen, CH_NOMAP | CH_QUOTED)) + CHAR2INT(sp, buf, tlen, w, wlen); + if (v_event_push(sp, NULL, w, wlen, CH_NOMAP | CH_QUOTED)) return (1); /* Don't refresh until after 'z' happens. */ @@ -284,9 +281,7 @@ err2: vp->m_final.lno = s_lno; * PUBLIC: int v_searchN __P((SCR *, VICMD *)); */ int -v_searchN(sp, vp) - SCR *sp; - VICMD *vp; +v_searchN(SCR *sp, VICMD *vp) { dir_t dir; @@ -311,35 +306,82 @@ v_searchN(sp, vp) * PUBLIC: int v_searchn __P((SCR *, VICMD *)); */ int -v_searchn(sp, vp) - SCR *sp; - VICMD *vp; +v_searchn(SCR *sp, VICMD *vp) { return (v_search(sp, vp, NULL, 0, SEARCH_PARSE, sp->searchdir)); } /* + * is_special -- + * Test if the character is special in a basic RE. + */ +static int +is_special(CHAR_T c) +{ + /* + * !!! + * `*' and `$' are ordinary when appear at the beginning of a RE, + * but it's safe to distinguish them from the ordinary characters. + * The tilde is vi-specific, of course. + */ + return (STRCHR(L(".[*\\^$~"), c) && c); +} + +/* + * Rear delimiter for word search when the keyword ends in + * (i.e., consists of) a non-word character. See v_searchw below. + */ +#define RE_NWSTOP L("([^[:alnum:]_]|$)") +#define RE_NWSTOP_LEN (SIZE(RE_NWSTOP) - 1) + +/* * v_searchw -- [count]^A * Search for the word under the cursor. * * PUBLIC: int v_searchw __P((SCR *, VICMD *)); */ int -v_searchw(sp, vp) - SCR *sp; - VICMD *vp; +v_searchw(SCR *sp, VICMD *vp) { size_t blen, len; int rval; - char *bp; + CHAR_T *bp, *p; + + /* An upper bound for the SIZE of the RE under construction. */ + len = VIP(sp)->klen + MAX(RE_WSTART_LEN, 1) + + MAX(RE_WSTOP_LEN, RE_NWSTOP_LEN); + GET_SPACE_RETW(sp, bp, blen, len); + p = bp; + + /* Only the first character can be non-word, see v_curword. */ + if (inword(VIP(sp)->keyw[0])) { + MEMCPY(p, RE_WSTART, RE_WSTART_LEN); + p += RE_WSTART_LEN; + } else if (is_special(VIP(sp)->keyw[0])) { + MEMCPY(p, L("\\"), 1); + p += 1; + } - len = VIP(sp)->klen + sizeof(RE_WSTART) + sizeof(RE_WSTOP); - GET_SPACE_RET(sp, bp, blen, len); - len = snprintf(bp, blen, "%s%s%s", RE_WSTART, VIP(sp)->keyw, RE_WSTOP); + MEMCPY(p, VIP(sp)->keyw, VIP(sp)->klen); + p += VIP(sp)->klen; + + if (inword(p[-1])) { + MEMCPY(p, RE_WSTOP, RE_WSTOP_LEN); + p += RE_WSTOP_LEN; + } else { + /* + * The keyword is a single non-word character. + * We want it to stay the same when typing ^A several times + * in a row, just the way the other cases behave. + */ + MEMCPY(p, RE_NWSTOP, RE_NWSTOP_LEN); + p += RE_NWSTOP_LEN; + } + len = p - bp; rval = v_search(sp, vp, bp, len, SEARCH_SET, FORWARD); - FREE_SPACE(sp, bp, blen); + FREE_SPACEW(sp, bp, blen); return (rval); } @@ -348,13 +390,7 @@ v_searchw(sp, vp) * The search commands. */ static int -v_search(sp, vp, ptrn, plen, flags, dir) - SCR *sp; - VICMD *vp; - u_int flags; - char *ptrn; - size_t plen; - dir_t dir; +v_search(SCR *sp, VICMD *vp, CHAR_T *ptrn, size_t plen, u_int flags, dir_t dir) { /* Display messages. */ LF_SET(SEARCH_MSG); @@ -417,10 +453,7 @@ v_search(sp, vp, ptrn, plen, flags, dir) * PUBLIC: int v_correct __P((SCR *, VICMD *, int)); */ int -v_correct(sp, vp, isdelta) - SCR *sp; - VICMD *vp; - int isdelta; +v_correct(SCR *sp, VICMD *vp, int isdelta) { dir_t dir; MARK m; @@ -462,8 +495,8 @@ v_correct(sp, vp, isdelta) * because of the wrapscan option. */ if (vp->m_start.lno > vp->m_stop.lno || - vp->m_start.lno == vp->m_stop.lno && - vp->m_start.cno > vp->m_stop.cno) { + (vp->m_start.lno == vp->m_stop.lno && + vp->m_start.cno > vp->m_stop.cno)) { m = vp->m_start; vp->m_start = vp->m_stop; vp->m_stop = m; |