mirror of
git://git.code.sf.net/p/zsh/code
synced 2024-06-06 15:26:04 +02:00
24822: highlighting of isearch matches
unposted: not in NEWS that COMBINING_CHARS is not on by default
This commit is contained in:
parent
8a323cae8c
commit
91a10708b2
|
@ -1,5 +1,11 @@
|
|||
2008-04-26 Peter Stephenson <p.w.stephenson@ntlworld.com>
|
||||
|
||||
* unposted: NEWS: note that COMBINING_CHARS is not on by
|
||||
default.
|
||||
|
||||
* 24882: Doc/Zsh/zle.yo, Src/Zle/zle_hist.c, Src/Zle/zle_refresh.c:
|
||||
highlighting of incremental search match.
|
||||
|
||||
* unposted because everyone's seen enough of my mistakes:
|
||||
Src/pattern.c, Src/Zle/zle_hist.c: with pattern matching the
|
||||
end position of the match wasn't calculated; we used the
|
||||
|
|
|
@ -2064,6 +2064,10 @@ The contexts available for highlighting are the following:
|
|||
startitem()
|
||||
cindex(region, highlighting)
|
||||
cindex(highlighting, region)
|
||||
item(tt(isearch))(
|
||||
When one of the incremental history search widgets is active, the
|
||||
area of the command line matched by the search string or pattern.
|
||||
)
|
||||
item(tt(region))(
|
||||
The region between the cursor (point) and the mark as set with
|
||||
tt(set-mark-command). The region is only highlighted if it is active,
|
||||
|
@ -2102,7 +2106,7 @@ mode. The actual effect is specific to the terminal; on many terminals it
|
|||
is inverse video. On some such terminals, where the cursor does not blink
|
||||
it appears with standout mode negated, making it less than clear where
|
||||
the cursor actually is. On such terminals one of the other effects
|
||||
may be preferable for highlighting the region.
|
||||
may be preferable for highlighting the region and matched search string.
|
||||
)
|
||||
item(tt(underline))(
|
||||
The characters in the given context are shown underlined. Some
|
||||
|
@ -2133,7 +2137,8 @@ enditem()
|
|||
If tt(zle_highlight) is not set or no value applies to a particular
|
||||
context, the defaults applied are equivalent to
|
||||
|
||||
example(zle_highlight=LPAR()region:standout special:standout+RPAR())
|
||||
example(zle_highlight=LPAR()region:standout special:standout
|
||||
isearch:underline+RPAR())
|
||||
|
||||
i.e. both the region and special characters are shown in standout mode.
|
||||
|
||||
|
|
3
NEWS
3
NEWS
|
@ -10,7 +10,8 @@ Major changes between versions 4.3.6 and 4.3.7
|
|||
The option COMBINING_CHARS has been added. When it is set, the
|
||||
line editor assumes the terminal is capable of displaying zero-width
|
||||
combining characters (typically accents) correctly as modifications
|
||||
to the base character, and will act accordingly.
|
||||
to the base character, and will act accordingly. Note it is not set
|
||||
by default owing to vagaries of terminals.
|
||||
|
||||
The option HIST_FCNTL_LOCK has been added to provide locking of history
|
||||
files using the system call fcntl(). On recent NFS implementations this
|
||||
|
|
|
@ -907,6 +907,7 @@ static struct isrch_spot {
|
|||
int pat_hl; /* histline where pattern search started */
|
||||
unsigned short pos; /* The search position in our metafied str */
|
||||
unsigned short pat_pos; /* pos where pattern search started */
|
||||
unsigned short end_pos; /* The position of the end of the matched str */
|
||||
unsigned short cs; /* The visible search position to the user */
|
||||
unsigned short len; /* The search string's length */
|
||||
unsigned short flags; /* This spot's flags */
|
||||
|
@ -928,7 +929,7 @@ free_isrch_spots(void)
|
|||
/**/
|
||||
static void
|
||||
set_isrch_spot(int num, int hl, int pos, int pat_hl, int pat_pos,
|
||||
int cs, int len, int dir, int nomatch)
|
||||
int end_pos, int cs, int len, int dir, int nomatch)
|
||||
{
|
||||
if (num >= max_spot) {
|
||||
if (!isrch_spots) {
|
||||
|
@ -944,6 +945,7 @@ set_isrch_spot(int num, int hl, int pos, int pat_hl, int pat_pos,
|
|||
isrch_spots[num].pos = (unsigned short)pos;
|
||||
isrch_spots[num].pat_hl = pat_hl;
|
||||
isrch_spots[num].pat_pos = (unsigned short)pat_pos;
|
||||
isrch_spots[num].end_pos = (unsigned short)end_pos;
|
||||
isrch_spots[num].cs = (unsigned short)cs;
|
||||
isrch_spots[num].len = (unsigned short)len;
|
||||
isrch_spots[num].flags = (dir > 0? ISS_FORWARD : 0)
|
||||
|
@ -953,12 +955,13 @@ set_isrch_spot(int num, int hl, int pos, int pat_hl, int pat_pos,
|
|||
/**/
|
||||
static void
|
||||
get_isrch_spot(int num, int *hlp, int *posp, int *pat_hlp, int *pat_posp,
|
||||
int *csp, int *lenp, int *dirp, int *nomatch)
|
||||
int *end_posp, int *csp, int *lenp, int *dirp, int *nomatch)
|
||||
{
|
||||
*hlp = isrch_spots[num].hl;
|
||||
*posp = (int)isrch_spots[num].pos;
|
||||
*pat_hlp = isrch_spots[num].pat_hl;
|
||||
*pat_posp = (int)isrch_spots[num].pat_pos;
|
||||
*end_posp = (int)isrch_spots[num].end_pos;
|
||||
*csp = (int)isrch_spots[num].cs;
|
||||
*lenp = (int)isrch_spots[num].len;
|
||||
*dirp = (isrch_spots[num].flags & ISS_FORWARD)? 1 : -1;
|
||||
|
@ -1010,6 +1013,9 @@ isearch_newpos(LinkList matchlist, int curpos, int dir,
|
|||
#define NORM_PROMPT_POS (BAD_TEXT_LEN+1)
|
||||
#define FIRST_SEARCH_CHAR (NORM_PROMPT_POS + 14)
|
||||
|
||||
/**/
|
||||
int isearch_active, isearch_startpos, isearch_endpos;
|
||||
|
||||
/**/
|
||||
static void
|
||||
doisearch(char **args, int dir, int pattern)
|
||||
|
@ -1087,6 +1093,12 @@ doisearch(char **args, int dir, int pattern)
|
|||
* case it's OK.
|
||||
*/
|
||||
int dup_ok = 0;
|
||||
/*
|
||||
* End position of the match.
|
||||
* When forward matching, this is the position for the cursor.
|
||||
* When backward matching, the cursor position is pos.
|
||||
*/
|
||||
int end_pos = 0;
|
||||
/*
|
||||
* savekeys records the unget buffer, so that if we have arguments
|
||||
* they don't pollute the input.
|
||||
|
@ -1138,7 +1150,7 @@ doisearch(char **args, int dir, int pattern)
|
|||
pat_pos = pos = zlemetacs;
|
||||
for (;;) {
|
||||
/* Remember the current values in case search fails (doesn't push). */
|
||||
set_isrch_spot(top_spot, hl, pos, pat_hl, pat_pos,
|
||||
set_isrch_spot(top_spot, hl, pos, pat_hl, pat_pos, end_pos,
|
||||
zlemetacs, sbptr, dir, nomatch);
|
||||
if (sbptr == 1 && sbuf[0] == '^') {
|
||||
zlemetacs = 0;
|
||||
|
@ -1147,11 +1159,6 @@ doisearch(char **args, int dir, int pattern)
|
|||
} else if (sbptr > 0) {
|
||||
/* The matched text, used as flag that we matched */
|
||||
char *t = NULL;
|
||||
/*
|
||||
* When forward matching, position for the cursor.
|
||||
* When backward matching, the position is pos.
|
||||
*/
|
||||
int forwardmatchpos = 0;
|
||||
last_line = zt;
|
||||
|
||||
sbuf[sbptr] = '\0';
|
||||
|
@ -1233,7 +1240,7 @@ doisearch(char **args, int dir, int pattern)
|
|||
*/
|
||||
if (!skip_pos &&
|
||||
pattryrefs(patprog, zt, -1, -1, 0, NULL, NULL,
|
||||
&forwardmatchpos))
|
||||
&end_pos))
|
||||
t = zt;
|
||||
} else {
|
||||
if (!matchlist && !skip_pos) {
|
||||
|
@ -1268,7 +1275,7 @@ doisearch(char **args, int dir, int pattern)
|
|||
newpos = pos + 1;
|
||||
}
|
||||
newpos = isearch_newpos(matchlist, newpos,
|
||||
dir, &forwardmatchpos);
|
||||
dir, &end_pos);
|
||||
/* need a new list next time if off the end */
|
||||
if (newpos < 0) {
|
||||
freematchlist(matchlist);
|
||||
|
@ -1316,7 +1323,7 @@ doisearch(char **args, int dir, int pattern)
|
|||
} else
|
||||
t = zlinefind(zt, pos, sbuf, dir, sens);
|
||||
if (t)
|
||||
forwardmatchpos = pos + sbptr - (sbuf[0] == '^');
|
||||
end_pos = pos + sbptr - (sbuf[0] == '^');
|
||||
}
|
||||
}
|
||||
if (t) {
|
||||
|
@ -1333,7 +1340,8 @@ doisearch(char **args, int dir, int pattern)
|
|||
&& (isrch_spots[top_spot-1].flags >> ISS_NOMATCH_SHIFT))
|
||||
top_spot--;
|
||||
get_isrch_spot(top_spot, &hl, &pos, &pat_hl, &pat_pos,
|
||||
&zlemetacs, &sbptr, &dir, &nomatch);
|
||||
&end_pos, &zlemetacs, &sbptr, &dir,
|
||||
&nomatch);
|
||||
if (!nomatch) {
|
||||
feep = 1;
|
||||
nomatch = 1;
|
||||
|
@ -1366,7 +1374,7 @@ doisearch(char **args, int dir, int pattern)
|
|||
if (t || (nosearch && !nomatch)) {
|
||||
zle_setline(he);
|
||||
if (dir == 1)
|
||||
zlemetacs = forwardmatchpos;
|
||||
zlemetacs = end_pos;
|
||||
else
|
||||
zlemetacs = pos;
|
||||
statusline = ibuf + NORM_PROMPT_POS;
|
||||
|
@ -1384,11 +1392,39 @@ doisearch(char **args, int dir, int pattern)
|
|||
}
|
||||
sbuf[sbptr] = '_';
|
||||
sbuf[sbptr+1] = '\0';
|
||||
if (!nomatch && sbptr && (sbptr > 1 || sbuf[0] != '^')) {
|
||||
#ifdef MULTIBYTE_SUPPORT
|
||||
int charpos = 0, charcount = 0, ret;
|
||||
wint_t wc;
|
||||
mbstate_t mbs;
|
||||
|
||||
/*
|
||||
* Count unmetafied character positions for the
|
||||
* start and end of the match for the benefit of
|
||||
* highlighting.
|
||||
*/
|
||||
memset(&mbs, 0, sizeof(mbs));
|
||||
while (charpos < end_pos) {
|
||||
ret = mb_metacharlenconv_r(zlemetaline + charpos, &wc, &mbs);
|
||||
if (charpos <= pos && pos < charpos + ret)
|
||||
isearch_startpos = charcount;
|
||||
charcount++;
|
||||
charpos += ret;
|
||||
}
|
||||
isearch_endpos = charcount;
|
||||
#else
|
||||
isearch_startpos = ztrsub(zlemetaline + pos, zlemetaline);
|
||||
isearch_endpos = ztrsub(zlemetaline + end_pos,
|
||||
zlemetaline);
|
||||
#endif
|
||||
isearch_active = 1;
|
||||
} else
|
||||
isearch_active = 0;
|
||||
ref:
|
||||
zrefresh();
|
||||
if (!(cmd = getkeycmd()) || cmd == Th(z_sendbreak)) {
|
||||
int i;
|
||||
get_isrch_spot(0, &hl, &pos, &pat_hl, &pat_pos,
|
||||
get_isrch_spot(0, &hl, &pos, &pat_hl, &pat_pos, &end_pos,
|
||||
&i, &sbptr, &dir, &nomatch);
|
||||
he = quietgethist(hl);
|
||||
zle_setline(he);
|
||||
|
@ -1410,7 +1446,7 @@ doisearch(char **args, int dir, int pattern)
|
|||
cmd == Th(z_backwarddeletechar)) {
|
||||
if (top_spot) {
|
||||
get_isrch_spot(--top_spot, &hl, &pos, &pat_hl, &pat_pos,
|
||||
&zlemetacs, &sbptr, &dir, &nomatch);
|
||||
&end_pos, &zlemetacs, &sbptr, &dir, &nomatch);
|
||||
patprog = NULL;
|
||||
nosearch = 1;
|
||||
} else
|
||||
|
@ -1452,7 +1488,7 @@ doisearch(char **args, int dir, int pattern)
|
|||
cmd == Th(z_historyincrementalpatternsearchbackward)) {
|
||||
pat_hl = hl;
|
||||
pat_pos = pos;
|
||||
set_isrch_spot(top_spot++, hl, pos, pat_hl, pat_pos,
|
||||
set_isrch_spot(top_spot++, hl, pos, pat_hl, pat_pos, end_pos,
|
||||
zlemetacs, sbptr, dir, nomatch);
|
||||
if (dir != -1)
|
||||
dir = -1;
|
||||
|
@ -1463,7 +1499,7 @@ doisearch(char **args, int dir, int pattern)
|
|||
cmd == Th(z_historyincrementalpatternsearchforward)) {
|
||||
pat_hl = hl;
|
||||
pat_pos = pos;
|
||||
set_isrch_spot(top_spot++, hl, pos, pat_hl, pat_pos,
|
||||
set_isrch_spot(top_spot++, hl, pos, pat_hl, pat_pos, end_pos,
|
||||
zlemetacs, sbptr, dir, nomatch);
|
||||
if (dir != 1)
|
||||
dir = 1;
|
||||
|
@ -1473,7 +1509,7 @@ doisearch(char **args, int dir, int pattern)
|
|||
} else if(cmd == Th(z_virevrepeatsearch)) {
|
||||
pat_hl = hl;
|
||||
pat_pos = pos;
|
||||
set_isrch_spot(top_spot++, hl, pos, pat_hl, pat_pos,
|
||||
set_isrch_spot(top_spot++, hl, pos, pat_hl, pat_pos, end_pos,
|
||||
zlemetacs, sbptr, dir, nomatch);
|
||||
dir = -odir;
|
||||
skip_pos = 1;
|
||||
|
@ -1481,7 +1517,7 @@ doisearch(char **args, int dir, int pattern)
|
|||
} else if(cmd == Th(z_virepeatsearch)) {
|
||||
pat_hl = hl;
|
||||
pat_pos = pos;
|
||||
set_isrch_spot(top_spot++, hl, pos, pat_hl, pat_pos,
|
||||
set_isrch_spot(top_spot++, hl, pos, pat_hl, pat_pos, end_pos,
|
||||
zlemetacs, sbptr, dir, nomatch);
|
||||
dir = odir;
|
||||
skip_pos = 1;
|
||||
|
@ -1534,7 +1570,7 @@ doisearch(char **args, int dir, int pattern)
|
|||
feep = 1;
|
||||
continue;
|
||||
}
|
||||
set_isrch_spot(top_spot++, hl, pos, pat_hl, pat_pos,
|
||||
set_isrch_spot(top_spot++, hl, pos, pat_hl, pat_pos, end_pos,
|
||||
zlemetacs, sbptr, dir, nomatch);
|
||||
if (sbptr >= sibuf - FIRST_SEARCH_CHAR - 2
|
||||
#ifdef MULTIBYTE_SUPPORT
|
||||
|
@ -1569,6 +1605,7 @@ doisearch(char **args, int dir, int pattern)
|
|||
zsfree(okeymap);
|
||||
if (matchlist)
|
||||
freematchlist(matchlist);
|
||||
isearch_active = 0;
|
||||
/*
|
||||
* Don't allow unused characters provided as a string to the
|
||||
* widget to overflow and be used as separated commands.
|
||||
|
|
|
@ -241,9 +241,16 @@ struct region_highlight {
|
|||
* via the parameter region_highlight.
|
||||
*/
|
||||
struct region_highlight *region_highlights;
|
||||
/*
|
||||
* Count of special uses of region highlighting, which account
|
||||
* for the first few elements of region_highlights.
|
||||
* 0: region between point and mark
|
||||
* 1: isearch region
|
||||
*/
|
||||
#define N_SPECIAL_HIGHLIGHTS (2)
|
||||
/*
|
||||
* Number of elements in region_highlights.
|
||||
* This includes the region between point and mark, element 0.
|
||||
* This includes the special elements above.
|
||||
*/
|
||||
int n_region_highlights;
|
||||
|
||||
|
@ -380,12 +387,14 @@ void zle_set_highlight(void)
|
|||
char **atrs = getaparam("zle_highlight");
|
||||
int special_atr_on_set = 0;
|
||||
int region_atr_on_set = 0;
|
||||
int isearch_atr_on_set = 0;
|
||||
struct region_highlight *rhp;
|
||||
|
||||
special_atr_on = 0;
|
||||
if (!region_highlights) {
|
||||
region_highlights = (struct region_highlight *)
|
||||
zshcalloc(sizeof(struct region_highlight));
|
||||
n_region_highlights = 1;
|
||||
zshcalloc(N_SPECIAL_HIGHLIGHTS*sizeof(struct region_highlight));
|
||||
n_region_highlights = N_SPECIAL_HIGHLIGHTS;
|
||||
} else {
|
||||
region_highlights->atr = 0;
|
||||
}
|
||||
|
@ -394,14 +403,23 @@ void zle_set_highlight(void)
|
|||
for (; *atrs; atrs++) {
|
||||
if (!strcmp(*atrs, "none")) {
|
||||
/* reset attributes for consistency... usually unnecessary */
|
||||
special_atr_on = region_highlights->atr = 0;
|
||||
special_atr_on_set = region_atr_on_set = 1;
|
||||
special_atr_on = 0;
|
||||
special_atr_on_set = region_atr_on_set =
|
||||
isearch_atr_on_set = 1;
|
||||
for (rhp = region_highlights;
|
||||
rhp < region_highlights + N_SPECIAL_HIGHLIGHTS;
|
||||
rhp++) {
|
||||
rhp->atr = 0;
|
||||
}
|
||||
} else if (strpfx("special:", *atrs)) {
|
||||
match_highlight(*atrs + 8, &special_atr_on);
|
||||
special_atr_on_set = 1;
|
||||
} else if (strpfx("region:", *atrs)) {
|
||||
match_highlight(*atrs + 7, ®ion_highlights->atr);
|
||||
region_atr_on_set = 1;
|
||||
} else if (strpfx("isearch:", *atrs)) {
|
||||
match_highlight(*atrs + 8, &(region_highlights[1].atr));
|
||||
isearch_atr_on_set = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -411,6 +429,8 @@ void zle_set_highlight(void)
|
|||
special_atr_on = TXTSTANDOUT;
|
||||
if (!region_atr_on_set)
|
||||
region_highlights->atr = TXTSTANDOUT;
|
||||
if (!isearch_atr_on_set)
|
||||
region_highlights[1].atr = TXTUNDERLINE;
|
||||
special_atr_off = special_atr_on << TXT_ATTR_OFF_ON_SHIFT;
|
||||
}
|
||||
|
||||
|
@ -432,15 +452,17 @@ get_region_highlight(UNUSED(Param pm))
|
|||
|
||||
/* region_highlights may not have been set yet */
|
||||
if (!arrsize)
|
||||
arrsize = 1;
|
||||
arrsize = N_SPECIAL_HIGHLIGHTS;
|
||||
arrp = retarr = (char **)zhalloc(arrsize*sizeof(char *));
|
||||
/* ignore NULL termination */
|
||||
arrsize--;
|
||||
if (arrsize) {
|
||||
struct region_highlight *rhp;
|
||||
|
||||
/* ignore point/mark at start */
|
||||
for (rhp = region_highlights+1; arrsize--; rhp++, arrp++) {
|
||||
/* ignore special highlighting */
|
||||
for (rhp = region_highlights + N_SPECIAL_HIGHLIGHTS;
|
||||
arrsize--;
|
||||
rhp++, arrp++) {
|
||||
char digbuf1[DIGBUFSIZE], digbuf2[DIGBUFSIZE];
|
||||
int atrlen = 0, alloclen, done1;
|
||||
const struct highlight *hp;
|
||||
|
@ -503,9 +525,9 @@ set_region_highlight(UNUSED(Param pm), char **aval)
|
|||
struct region_highlight *rhp;
|
||||
|
||||
len = aval ? arrlen(aval) : 0;
|
||||
if (n_region_highlights != len + 1) {
|
||||
/* no null termination, but include point/mark region at start */
|
||||
n_region_highlights = len + 1;
|
||||
if (n_region_highlights != len + N_SPECIAL_HIGHLIGHTS) {
|
||||
/* no null termination, but include special highlighting at start */
|
||||
n_region_highlights = len + N_SPECIAL_HIGHLIGHTS;
|
||||
region_highlights = (struct region_highlight *)
|
||||
zrealloc(region_highlights,
|
||||
sizeof(struct region_highlight) * n_region_highlights);
|
||||
|
@ -514,7 +536,9 @@ set_region_highlight(UNUSED(Param pm), char **aval)
|
|||
if (!aval)
|
||||
return;
|
||||
|
||||
for (rhp = region_highlights + 1; *aval; rhp++, aval++) {
|
||||
for (rhp = region_highlights + N_SPECIAL_HIGHLIGHTS;
|
||||
*aval;
|
||||
rhp++, aval++) {
|
||||
char *strp, *oldstrp;
|
||||
|
||||
oldstrp = *aval;
|
||||
|
@ -1050,6 +1074,13 @@ zrefresh(void)
|
|||
} else {
|
||||
region_highlights->start = region_highlights->end = -1;
|
||||
}
|
||||
/* check for isearch string to highlight */
|
||||
if (isearch_active) {
|
||||
region_highlights[1].start = isearch_startpos;
|
||||
region_highlights[1].end = isearch_endpos;
|
||||
} else {
|
||||
region_highlights[1].start = region_highlights[1].end = -1;
|
||||
}
|
||||
|
||||
if (clearlist && listshown > 0) {
|
||||
if (tccan(TCCLEAREOD)) {
|
||||
|
|
Loading…
Reference in New Issue