Skip to content

Commit

Permalink
Support an 'owner' key in region_highlight.
Browse files Browse the repository at this point in the history
This is to allow plugins to easily remove only entries they had added.
See zsh-users/zsh-syntax-highlighting#418 and
the cross-referenced issues.
  • Loading branch information
danielshahaf committed May 3, 2020
1 parent d128bc0 commit 955caae
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 17 deletions.
19 changes: 11 additions & 8 deletions Doc/Zsh/zle.yo
Original file line number Diff line number Diff line change
Expand Up @@ -974,27 +974,30 @@ of the non-editable parts of the command line in tt(PREDISPLAY)
and tt(POSTDISPLAY) are possible, but note that the tt(P) flag
is needed for character indexing to include tt(PREDISPLAY).

Each string consists of the following parts:
Each string consists of the following whitespace-separated parts:

startitemize()
itemiz(Optionally, a `tt(P)' to signify that the start and end offset that
follow include any string set by the tt(PREDISPLAY) special parameter;
this is needed if the predisplay string itself is to be highlighted.
Whitespace may follow the `tt(P)'.)
itemiz(A start offset in the same units as tt(CURSOR), terminated by
whitespace.)
itemiz(An end offset in the same units as tt(CURSOR), terminated by
whitespace.)
Whitespace between the `tt(P)' and the start offset is optional.)
itemiz(A start offset in the same units as tt(CURSOR).)
itemiz(An end offset in the same units as tt(CURSOR).)
itemiz(A highlight specification in the same format as
used for contexts in the parameter tt(zle_highlight), see
ifnzman(noderef(Character Highlighting))\
ifzman(the section `Character Highlighting' below);
for example, tt(standout) or tt(fg=red,bold)).
for example, tt(standout) or tt(fg=red,bold).)
itemiz(Optionally, a string of the form `tt(owner=)var(token)'.
The var(token) value is preserved verbatim but not parsed in any way.
Plugins may use this to identify elements they had added, for example, in order
to remove them with
`tt(region_highlight=+LPAR() ${region_highlight:#*owner=)var(token)tt(} +RPAR())'.)
enditemize()

For example,

example(region_highlight=("P0 20 bold"))
example(region_highlight=("P0 20 bold owner=myplugin"))

specifies that the first twenty characters of the text including
any predisplay string should be highlighted in bold.
Expand Down
4 changes: 4 additions & 0 deletions Src/Zle/zle.h
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,10 @@ struct region_highlight {
* Any of the flags defined above.
*/
int flags;
/*
* User-settable "owner" key. Metafied.
*/
const char *owner;
};

/*
Expand Down
29 changes: 23 additions & 6 deletions Src/Zle/zle_refresh.c
Original file line number Diff line number Diff line change
Expand Up @@ -212,9 +212,9 @@ static zattr default_atr_on, special_atr_on;

/*
* Array of region highlights, no special termination.
* The first element (0) always describes the region between
* point and mark. Any other elements are set by the user
* via the parameter region_highlight.
* The first N_SPECIAL_HIGHLIGHTS elements describe special uses of
* highlighting, documented under N_SPECIAL_HIGHLIGHTS.
* Any other elements are set by the user via the parameter region_highlight.
*/

/**/
Expand Down Expand Up @@ -414,16 +414,19 @@ get_region_highlight(UNUSED(Param pm))
arrsize--;
rhp++, arrp++) {
char digbuf1[DIGBUFSIZE], digbuf2[DIGBUFSIZE];
int atrlen = 0, alloclen;
int atrlen, alloclen;
const char owner_equals[] = "owner=";

sprintf(digbuf1, "%d", rhp->start);
sprintf(digbuf2, "%d", rhp->end);

atrlen = output_highlight(rhp->atr, NULL);
alloclen = atrlen + strlen(digbuf1) + strlen(digbuf2) +
3; /* 2 spaces, 1 0 */
3; /* 2 spaces, 1 terminating NUL */
if (rhp->flags & ZRH_PREDISPLAY)
alloclen += 2; /* "P " */
if (rhp->owner)
alloclen += 1 /* space */ + strlen(owner_equals) + strlen(rhp->owner);
*arrp = (char *)zhalloc(alloclen * sizeof(char));
/*
* On input we allow a space after the flags.
Expand All @@ -436,6 +439,12 @@ get_region_highlight(UNUSED(Param pm))
(rhp->flags & ZRH_PREDISPLAY) ? "P" : "",
digbuf1, digbuf2);
(void)output_highlight(rhp->atr, *arrp + strlen(*arrp));

if (rhp->owner) {
strcat(*arrp, " ");
strcat(*arrp, owner_equals);
strcat(*arrp, rhp->owner);
}
}
*arrp = NULL;
return retarr;
Expand Down Expand Up @@ -502,7 +511,15 @@ set_region_highlight(UNUSED(Param pm), char **aval)
while (inblank(*strp))
strp++;

match_highlight(strp, &rhp->atr);
strp = (char*) match_highlight(strp, &rhp->atr);

while (inblank(*strp))
strp++;

if (strpfx("owner=", strp))
rhp->owner = ztrdup(strp + 6);
else
rhp->owner = NULL;
}

freearray(av);
Expand Down
2 changes: 2 additions & 0 deletions Src/Zle/zle_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,7 @@ zle_save_positions(void)
newrhp->next = NULL;
newrhp->atr = rhp->atr;
newrhp->flags = rhp->flags;
/* TODO: save rhp->owner here? */
if (zlemetaline) {
newrhp->start = rhp->start_meta;
newrhp->end = rhp->end_meta;
Expand Down Expand Up @@ -694,6 +695,7 @@ zle_restore_positions(void)

rhp->atr = oldrhp->atr;
rhp->flags = oldrhp->flags;
rhp->owner = NULL;
if (zlemetaline) {
rhp->start_meta = oldrhp->start;
rhp->end_meta = oldrhp->end;
Expand Down
9 changes: 6 additions & 3 deletions Src/prompt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1724,10 +1724,11 @@ match_colour(const char **teststrp, int is_fg, int colour)
/*
* Match a set of highlights in the given teststr.
* Set *on_var to reflect the values found.
* Return a pointer to the first character not consumed.
*/

/**/
mod_export void
mod_export const char *
match_highlight(const char *teststr, zattr *on_var)
{
int found = 1;
Expand All @@ -1745,7 +1746,7 @@ match_highlight(const char *teststr, zattr *on_var)
atr = match_colour(&teststr, is_fg, 0);
if (*teststr == ',')
teststr++;
else if (*teststr)
else if (*teststr && *teststr != ' ')
break;
found = 1;
/* skip out of range colours but keep scanning attributes */
Expand All @@ -1758,7 +1759,7 @@ match_highlight(const char *teststr, zattr *on_var)

if (*val == ',')
val++;
else if (*val)
else if (*val && *val != ' ')
break;

*on_var |= hl->mask_on;
Expand All @@ -1769,6 +1770,8 @@ match_highlight(const char *teststr, zattr *on_var)
}
}
}

return teststr;
}

/*
Expand Down
11 changes: 11 additions & 0 deletions Test/X04zlehighlight.ztst
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,17 @@
0:basic region_highlight with 8 colors
>0m27m24mCDE|32|trueCDE|39|

zpty_start
zpty_input 'rh_widget() { region_highlight+=( "0 4 fg=green owner=someplugin" ); typeset -p region_highlight }'
zpty_input 'zle -N rh_widget'
zpty_input 'bindkey "\C-a" rh_widget'
zpty_enable_zle
zpty_input $'\C-a'
zpty_line
zpty_stop
0:region_highlight owner information round trips
>typeset -a region_highlight=( '0 4 fg=green owner=someplugin' )

zpty_start
zpty_input 'rh_widget() { BUFFER="true"; region_highlight+=( "0 4 fg=#040810" ); }'
zpty_input 'zle -N rh_widget'
Expand Down

0 comments on commit 955caae

Please sign in to comment.