1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2025-10-26 16:40:29 +01:00

24782: initial go at highlighting of characters in zle command lines

This commit is contained in:
Peter Stephenson 2008-04-03 11:38:55 +00:00
parent b44ed0b032
commit 2c5ea79f17
11 changed files with 1079 additions and 260 deletions

View file

@ -1,5 +1,12 @@
2008-04-03 Peter Stephenson <pws@csr.com>
* 24782, plus a couple of fixes: Doc/Zsh/zle.yo,
Functions/Zle/read-from-minibuffer,
Functions/Zle/replace-string-again, Src/zsh.h, Src/Zle/zle.h,
Src/Zle/zle_main.c, Src/Zle/zle_move.c, Src/Zle/zle_params.c,
Src/Zle/zle_refresh.c: initial go at highlighting of command
lines in zle using $zle_highlight and $region_highlight.
* unposted, see users/12758: actually, [(w)...] does work with
(r) and (R).

View file

@ -29,10 +29,22 @@ line editor.
ifzman(See em(Parameters Used By The Shell) in zmanref(zshparam))\
ifnzman(noderef(Parameters Used By The Shell)).
The parameter tt(zle_highlight) is also used by the line editor;
ifzman(see em(Character Highlighting) below)\
ifnzman(noderef(Character Highlighting)). Highlighting
of special characters and the region between the cursor and the
mark (as set with tt(set-mark-command) in Emacs mode) is enabled
by default; consult this reference for more information. Irrascible
conservatives will wish to know that all highlighting may be disabled by
the following setting:
example(zle_highlight=(none))
startmenu()
menu(Keymaps)
menu(Zle Builtins)
menu(Zle Widgets)
menu(Character Highlighting)
endmenu()
texinode(Keymaps)(Zle Builtins)()(Zsh Line Editor)
@ -578,7 +590,7 @@ enditem()
)
enditem()
texinode(Zle Widgets)()(Zle Builtins)(Zsh Line Editor)
texinode(Zle Widgets)(Character Highlighting)(Zle Builtins)(Zsh Line Editor)
sect(Widgets)
cindex(widgets)
All actions in the editor are performed by `widgets'. A widget's job is
@ -762,6 +774,45 @@ The part of the buffer that lies to the right of the cursor position.
If it is assigned to, only that part of the buffer is replaced, and the
cursor remains between the old tt($LBUFFER) and the new tt($RBUFFER).
)
vindex(region_highlight)
item(tt(region_highlight) (array))(
Each element of this array may be set to a string that describes
highlighting for an arbitrary region of the command line that will
take effect the next time the command line is redisplayed. Each
string consists of the following parts:
startlist()
list(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)'.)
list(A start offset in the same units as tt(CURSOR), terminated by
whitespace.)
list(An end offset in the same units as tt(CURSOR), terminated by
whitespace.)
list(A highlight specification in the same format as
used for the contexts tt(region) or tt(special)
in the parameter tt(zle_highlight),
ifnzman(noderef(Character Highlighting))\
ifzman(see Character Highlighting below).
Hence this should be a comma-separated list of any of the
words tt(bold), tt(standout) or tt(underline).
endlist()
For example,
example(region_highlight=("P0 20 bold"))
specifies that the first twenty characters of the text including
any predisplay string should be highlighted in bold.
Note that the effect of tt(region_highlight) is not saved and disappears
as soon as the line is accepted. The line editor makes no attempt to
keep the highlighting effect synchronised with the line as it is edited;
hence region highlighting is best limited to static effects within
user widgets.
)
)
vindex(WIDGET)
item(tt(WIDGET) (scalar))(
The name of the widget currently being executed; read-only.
@ -1720,7 +1771,11 @@ Reads a key sequence, then prints the function bound to that sequence.
)
tindex(exchange-point-and-mark)
item(tt(exchange-point-and-mark) (^X^X) (unbound) (unbound))(
Exchange the cursor position with the position of the mark.
Exchange the cursor position (point) with the position of the mark.
Unless a negative prefix argument is given, the region between
point and mark is activated so that it can be highlighted.
If a zero prefix argument is given, the region is activated but
point and mark are not swapped.
)
tindex(execute-named-cmd)
item(tt(execute-named-cmd) (ESC-x) (unbound) (unbound))(
@ -1914,7 +1969,10 @@ Set the specified mark at the cursor position.
)
tindex(set-mark-command)
item(tt(set-mark-command) (^@) (unbound) (unbound))(
Set the mark at the cursor position.
Set the mark at the cursor position. If called with a negative
prefix argument, do not set the mark but deactivate the region so that
it is no longer highlighted (it is still usable for other purposes).
Otherwise the region is marked as active.
)
tindex(spell-word)
item(tt(spell-word) (ESC-$ ESC-S ESC-s) (unbound) (unbound))(
@ -1961,3 +2019,98 @@ If the last command executed was a digit as part of an argument,
continue the argument. Otherwise, execute vi-beginning-of-line.
)
enditem()
texinode(Character Highlighting)()(Zle Widgets)(Zsh Line Editor)
sect(Character Highlighting)
The line editor has the ability to highlight characters or regions
of the line that have a particular significance. This is controlled
by the array parameter tt(zsh_highlight), if it has been set by the user.
If the parameter contains the single entry tt(none) all highlighting
is turned off. Note the parameter is still expected to be an array.
Otherwise each entry of the array should consist of a word indicating a
context for highlighting, then a colon, then a comma-separated list of
the types of highlighting to apply in that context.
The contexts available for highlighting are the following:
startitem()
cindex(region, highlighting)
cindex(highlighting, region)
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,
which is the case if tt(set-mark-command) or tt(exchange-point-and-mark)
has been called and the line has not been subsequently modified. The
region can be deactivated by calling tt(set-mark-command) with a
negative prefix argument, or reactivated by calling
tt(exchange-point-and-mark) with a zero prefix argument. Note
that whether or not the region is active has no effect on its
use within widgets, it simply determines whether it is highlighted.
)
cindex(special characters, highlighting)
cindex(highlighting, special characters)
item(tt(special))(
Individual characters that have no direct printable
representation but are shown in a special manner by the line editor.
These characters are described below.)
enditem()
The available types of highlighting are the following. Note that
not all types of highlighting are available on all terminals:
startitem()
item(tt(none))(
No highlighting is applied to the given context. It is not useful for
this to appear with other types of highlighting; it is used to override
a default.
)
item(tt(bold))(
The characters in the given context are shown in a bold font.
)
item(tt(standout))(
The characters in the given context are shown in the terminal's standout
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.
)
item(tt(underline))(
The characters in the given context are shown underlined. Some
terminals show the foreground in a different colour instead; in this
case whitespace will not be highlighted.
)
enditem()
The characters described above as `special' are as follows. The
formatting described here is used irrespective of whether the characters
are highlighted:
startitem()
item(ASCII control characters)(
Control characters in the ASCII range are shown as
`tt(^)' followed by the base character.)
item(Unprintable multibyte characters)(
If the tt(MULTIBYTE) option is in effect,
multibyte characters not in the ASCII character set that are reported as
having zero width are shown as a hexadecimal number between
angle brackets. The number is the code point of the character in
the wide character set; this may or may not be Unicode, depending
on the operating system.)
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())
i.e. both the region and special characters are shown in standout mode.
Within widgets, arbitrary regions may be highlighted by setting the
special array parameter tt(region_highlight); see
ifnzman(nodreref(Zle Widgets))\
ifzman(above).

View file

@ -19,14 +19,14 @@ while getopts "k:" opt; do
done
(( OPTIND > 1 )) && shift $(( OPTIND - 1 ))
local savelbuffer=$LBUFFER saverbuffer=$RBUFFER
local savepredisplay=$PREDISPLAY savepostdisplay=$POSTDISPLAY
LBUFFER="$2"
RBUFFER="$3"
PREDISPLAY="$PREDISPLAY$savelbuffer$saverbuffer$POSTDISPLAY
${1:-? }"
POSTDISPLAY=
local pretext="$PREDISPLAY$LBUFFER$RBUFFER$POSTDISPLAY
"
local LBUFFER="$2"
local RBUFFER="$3"
local PREDISPLAY="$pretext${1:-? }"
local POSTDISPLAY=
local -a region_highlight
region_highlight=("P${#pretext} ${#PREDISPLAY} bold")
if [[ -n $keys ]]; then
zle -R
@ -38,9 +38,4 @@ else
(( stat )) || REPLY=$BUFFER
fi
LBUFFER=$savelbuffer
RBUFFER=$saverbuffer
PREDISPLAY=$savepredisplay
POSTDISPLAY=$savepostdisplay
return $stat

View file

@ -9,7 +9,8 @@ local MATCH MBEGIN MEND curwidget=${1:-$WIDGET}
local -a match mbegin mend
if [[ -z $_replace_string_src ]]; then
zle -M No string to replace.
zle -M "No string to replace."
return 1
fi
if [[ $curwidget = *pattern* ]]; then

View file

@ -325,6 +325,37 @@ enum suffixtype {
SUFTYP_NEGRNG /* Range of characters not to match */
};
#ifdef MULTIBYTE_SUPPORT
/*
* We use a wint_t here, since we need an invalid character as a
* placeholder and wint_t guarantees that we can use WEOF to do this.
*/
typedef wint_t REFRESH_CHAR;
#else
typedef char REFRESH_CHAR;
#endif
/*
* Description of one screen cell in zle_refresh.c
*/
typedef struct {
/* The (possibly wide) character */
REFRESH_CHAR chr;
/*
* Its attributes. 'On' attributes (TXT_ATTR_ON_MASK) are
* applied before the character, 'off' attributes (TXT_ATTR_OFF_MASK)
* after it. 'On' attributes are present for all characters that
* need the effect; 'off' attributes are only present for the
* last character in the sequence.
*/
REFRESH_CHAR atr;
} REFRESH_ELEMENT;
/* A string of screen cells */
typedef REFRESH_ELEMENT *REFRESH_STRING;
#ifdef DEBUG
#define METACHECK() \
DPUTS(zlemetaline == NULL, "line not metafied")

View file

@ -1076,6 +1076,7 @@ zlecore(void)
freeheap();
}
region_active = 0;
popheap();
}
@ -1933,6 +1934,7 @@ finish_(UNUSED(Module m))
getkeyptr = NULL;
zfree(clwords, clwsize * sizeof(char *));
zle_refresh_finish();
return 0;
}

View file

@ -183,7 +183,12 @@ backwardchar(UNUSED(char **args))
int
setmarkcommand(UNUSED(char **args))
{
if (zmult < 0) {
region_active = 0;
return 0;
}
mark = zlecs;
region_active = 1;
return 0;
}
@ -193,11 +198,17 @@ exchangepointandmark(UNUSED(char **args))
{
int x;
if (zmult == 0) {
region_active = 1;
return 0;
}
x = mark;
mark = zlecs;
zlecs = x;
if (zlecs > zlell)
zlecs = zlell;
if (zmult > 0)
region_active = 1;
return 0;
}

View file

@ -90,6 +90,9 @@ static const struct gsu_integer pending_gsu =
static const struct gsu_array killring_gsu =
{ get_killring, set_killring, unset_killring };
/* implementation is in zle_refresh.c */
static const struct gsu_array region_highlight_gsu =
{ get_region_highlight, set_region_highlight, unset_region_highlight };
#define GSU(X) ( (GsuScalar)(void*)(&(X)) )
static struct zleparam {
@ -120,6 +123,7 @@ static struct zleparam {
{ "PREBUFFER", PM_SCALAR | PM_READONLY, GSU(prebuffer_gsu), NULL },
{ "PREDISPLAY", PM_SCALAR, GSU(predisplay_gsu), NULL },
{ "RBUFFER", PM_SCALAR, GSU(rbuffer_gsu), NULL },
{ "region_highlight", PM_ARRAY, GSU(region_highlight_gsu), NULL },
{ "WIDGET", PM_SCALAR | PM_READONLY, GSU(widget_gsu), NULL },
{ "WIDGETFUNC", PM_SCALAR | PM_READONLY, GSU(widgetfunc_gsu), NULL },
{ "WIDGETSTYLE", PM_SCALAR | PM_READONLY, GSU(widgetstyle_gsu), NULL },

File diff suppressed because it is too large Load diff

View file

@ -384,6 +384,7 @@ spaceinline(int ct)
if (mark > zlecs)
mark += ct;
}
region_active = 0;
}
/**/
@ -408,6 +409,7 @@ shiftchars(int to, int cnt)
}
zleline[zlell = to] = ZWC('\0');
}
region_active = 0;
}
/**/
@ -724,8 +726,12 @@ getzlequery(void)
else
c = ZC_tolower(c);
/* echo response and return */
if (c != ZWC('\n'))
zwcputc(c);
if (c != ZWC('\n')) {
REFRESH_ELEMENT re;
re.chr = c;
re.atr = 0;
zwcputc(&re, NULL);
}
return c == ZWC('y');
}
@ -903,6 +909,7 @@ int
handlefeep(UNUSED(char **args))
{
zbeep();
region_active = 0;
return 0;
}

View file

@ -1941,6 +1941,8 @@ struct ttyinfo {
#define TXTUNDERLINE 0x04
#define TXTDIRTY 0x80
#define TXT_ATTR_ON_MASK 0x07
#define txtisset(X) (txtattrmask & (X))
#define txtset(X) (txtattrmask |= (X))
#define txtunset(X) (txtattrmask &= ~(X))
@ -1949,7 +1951,11 @@ struct ttyinfo {
#define TXTNOSTANDOUT 0x20
#define TXTNOUNDERLINE 0x40
#define txtchangeisset(X) (txtchange & (X))
#define TXT_ATTR_OFF_MASK 0x70
/* Bits to shift off right to get on */
#define TXT_ATTR_OFF_ON_SHIFT (4)
#define txtchangeisset(T,X) ((T) & (X))
#define txtchangeset(X, Y) (txtchange |= (X), txtchange &= ~(Y))
/****************************************/