Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: PATCH: isearch match highlighting
- X-seq: zsh-workers 24899
- From: Peter Stephenson <pws@xxxxxxx>
- To: zsh-workers@xxxxxxxxxx
- Subject: Re: PATCH: isearch match highlighting
- Date: Thu, 1 May 2008 11:37:06 +0100
- In-reply-to: <20080429181022.12809d23@news01>
- Mailing-list: contact zsh-workers-help@xxxxxxxxxx; run by ezmlm
- Organization: CSR
- References: <godlygeek@xxxxxxxxx> <17393e3e0804261727s560acff7sb6125d8f8b46b4b4@xxxxxxxxxxxxxx> <200804271957.m3RJvxiS004075@xxxxxxxxxxxxxxxxxxx> <17393e3e0804271849l30fe20bdp4008fc8247298d12@xxxxxxxxxxxxxx> <20080428102001.7b55074e@news01> <20080429181022.12809d23@news01>
On Tue, 29 Apr 2008 18:10:22 +0100
Peter Stephenson <pws@xxxxxxx> wrote:
> I would like at the least to make the use of the ANSI escapes
> configurable. They are in completion listings, but unfortunately that's
> tied to the variable interface for GNU ls colouring which doesn't really
> fit the case here. I suppose special values in zle_highlight would be
> suitable (with bindkey escapes).
I've done this. Looks suspiciously like overkill, but it's probably best
to be general.
I've also added handling of names for ANSI colours.
Index: Doc/Zsh/zle.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/zle.yo,v
retrieving revision 1.65
diff -u -r1.65 zle.yo
--- Doc/Zsh/zle.yo 29 Apr 2008 17:19:26 -0000 1.65
+++ Doc/Zsh/zle.yo 1 May 2008 10:35:05 -0000
@@ -2088,6 +2088,39 @@
)
enditem()
+tt(zle_highlight) may contain additional fields for controlling how
+terminal sequences to change colours are output. Each of the following is
+followed by a colon and a string in the same form as for key bindings.
+This will not be necessary for the vast majority of terminals as the
+defaults shown in parentheses are widely used.
+
+startitem()
+cindex(escape sequences, terminal, for highlighting)
+cindex(terminal escape sequences for highlighting)
+item(tt(fg_start_code) (tt(\e[3)))(
+The start of the escape sequence for the foreground colour.
+This is followed by an ASCII digit representing the colour.
+)
+item(tt(fg_default_code) (tt(9)))(
+The number to use instead of the colour to reset the default foreground
+colour.
+)
+item(tt(fg_end_code) (tt(m)))(
+The end of the escape sequence for the foreground colour.
+)
+item(tt(bg_start_code) (tt(\e[4)))(
+The start of the escape sequence for the background colour.
+This is followed by an ASCII digit representing the colour.
+)
+item(tt(bg_default_code) (tt(9)))(
+The number to use instead of the colour to reset the default
+background colour.
+)
+item(tt(bg_end_code) (tt(m)))(
+The end of the escape sequence for the background colour.
+)
+enditem()
+
The available types of highlighting are the following. Note that
not all types of highlighting are available on all terminals:
@@ -2098,11 +2131,19 @@
a default.
)
item(tt(fg=)var(colour))(
-The foreground colour should be set to var(colour), a decimal integer. Not
-all terminals support this, and of those that do not all provide facilities
-to test the support, hence the user should decide based on the terminal
-type. Most terminals with colour support accept the numbers 0 to 7, and
-may generate additional colours if the tt(bold) attributes is also present.
+The foreground colour should be set to var(colour), a decimal integer
+or the name of one of the eight most widely-supported colours.
+
+Not all terminals support this and, of those that do, not all provide
+facilities to test the support, hence the user should decide based on the
+terminal type. Most terminals with colour support accept the numbers 0 to
+7, and may generate additional colours if the tt(bold) attributes is also
+present. Most terminals also have a standard range of colours for those
+numbers (though the interpretation of the colour can vary); these colours
+can be set by one of the names tt(black), tt(red), tt(green), tt(yellow),
+tt(blue), tt(magenta), tt(cyan) and tt(white). Abbreviations are
+allowed; tt(b) or tt(bl) selects black.
+
On recent terminals and on systems with an up-to-date terminal database the
number of colours supported may be tested by with the command `tt(echotc
Co)'; if this succeeds, it indicates a limit on the number of colours which
@@ -2112,7 +2153,7 @@
Colour is also known as color.
)
item(tt(bg=)var(colour))(
-The background colour should be set to var(colour), a decimal integer.
+The background colour should be set to var(colour).
This works similarly to the foreground colour, except the background is
not usually affected by the bold attribute.
)
@@ -2144,12 +2185,18 @@
`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.
+This item applies to control characters not in the ASCII range,
+plus other characters as follows. If the tt(MULTIBYTE) option is in
+effect, multibyte characters not in the ASCII character set that are
+reported as having zero width are treated as combining characters when the
+option tt(COMBINING_CHARS) is on. If the option is off, or if a character
+appears where a combining character is not valid, the character
+is treated as unprintable.
+
+Unprintable multibyte characters 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()
Index: Src/Zle/zle_main.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_main.c,v
retrieving revision 1.110
diff -u -r1.110 zle_main.c
--- Src/Zle/zle_main.c 20 Apr 2008 21:17:29 -0000 1.110
+++ Src/Zle/zle_main.c 1 May 2008 10:35:06 -0000
@@ -1903,6 +1903,7 @@
addhookfunc("before_trap", (Hookfn) zlebeforetrap);
addhookfunc("after_trap", (Hookfn) zleaftertrap);
(void)addhookdefs(m, zlehooks, sizeof(zlehooks)/sizeof(*zlehooks));
+ zle_refresh_boot();
return 0;
}
Index: Src/Zle/zle_refresh.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Zle/zle_refresh.c,v
retrieving revision 1.64
diff -u -r1.64 zle_refresh.c
--- Src/Zle/zle_refresh.c 29 Apr 2008 17:19:27 -0000 1.64
+++ Src/Zle/zle_refresh.c 1 May 2008 10:35:06 -0000
@@ -326,6 +326,11 @@
#define ZR_START_ELLIPSIS_SIZE \
((int)(sizeof(zr_start_ellipsis)/sizeof(zr_start_ellipsis[0])))
+/* Defines standard ANSI colour names in index order */
+static const char *ansi_colours[] = {
+ "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white",
+ NULL
+};
/* Defines the available types of highlighting */
struct highlight {
@@ -342,6 +347,101 @@
{ NULL, 0, 0 }
};
+/* Structure and array for holding special colour terminal sequences */
+
+/* Start of escape sequence for foreground colour */
+#define TC_COL_FG_START "\033[3"
+/* End of escape sequence for foreground colour */
+#define TC_COL_FG_END "m"
+/* Code to reset foreground colour */
+#define TC_COL_FG_DEFAULT "9"
+
+/* Start of escape sequence for background colour */
+#define TC_COL_BG_START "\033[4"
+/* End of escape sequence for background colour */
+#define TC_COL_BG_END "m"
+/* Code to reset background colour */
+#define TC_COL_BG_DEFAULT "9"
+
+struct colour_sequences {
+ char *start; /* Escape sequence start */
+ char *end; /* Escape sequence terminator */
+ char *def; /* Code to reset default colour */
+};
+struct colour_sequences fg_bg_sequences[2];
+
+#define COL_SEQ_FG (0)
+#define COL_SEQ_BG (1)
+#define COL_SEQ_COUNT (2)
+
+/*
+ * We need a buffer for colour sequence compostion. It may
+ * vary depending on the sequences set. However, it's inefficient
+ * allocating it separately every time we send a colour sequence,
+ * so do it once per refresh.
+ */
+static char *colseq_buf;
+
+static void
+set_default_colour_sequences(void)
+{
+ fg_bg_sequences[COL_SEQ_FG].start = ztrdup(TC_COL_FG_START);
+ fg_bg_sequences[COL_SEQ_FG].end = ztrdup(TC_COL_FG_END);
+ fg_bg_sequences[COL_SEQ_FG].def = ztrdup(TC_COL_FG_DEFAULT);
+
+ fg_bg_sequences[COL_SEQ_BG].start = ztrdup(TC_COL_BG_START);
+ fg_bg_sequences[COL_SEQ_BG].end = ztrdup(TC_COL_BG_END);
+ fg_bg_sequences[COL_SEQ_BG].def = ztrdup(TC_COL_BG_DEFAULT);
+}
+
+static void
+free_colour_sequences(void)
+{
+ int i;
+
+ for (i = 0; i < COL_SEQ_COUNT; i++) {
+ zsfree(fg_bg_sequences[i].start);
+ zsfree(fg_bg_sequences[i].end);
+ zsfree(fg_bg_sequences[i].def);
+ }
+}
+
+/*
+ * Return index of ANSI colour for which *teststrp is an abbreviation.
+ * Any non-alphabetic character ends the abbreviation.
+ */
+
+static int
+match_colour(const char **teststrp)
+{
+ const char *teststr = *teststrp, *end, **cptr;
+ int len;
+
+ for (end = teststr; ialpha(*end); end++)
+ ;
+ len = end - teststr;
+ *teststrp = end;
+
+ for (cptr = ansi_colours; *cptr; cptr++) {
+ if (!strncmp(teststr, *cptr, len))
+ return cptr - ansi_colours;
+ }
+
+ return -1;
+}
+
+static void
+set_colour_code(char *str, char **var)
+{
+ char *keyseq;
+ int len;
+
+ zsfree(*var);
+ keyseq = getkeystring(str, &len, GETKEYS_BINDKEY, NULL);
+ *var = metafy(keyseq, len, META_DUP);
+}
+
+
/*
* Match a set of highlights in the given teststr.
* Set *on_var to reflect the values found.
@@ -359,15 +459,20 @@
found = 0;
if (strpfx("fg=", teststr) || strpfx("bg=", teststr)) {
int is_fg = (teststr[0] == 'f');
- int colour = (int)zstrtol(teststr+3, (char **)&teststr, 10);
- int shft, on;
+ int colour, shft, on;
+
+ teststr += 3;
+ if (ialpha(*teststr))
+ colour = match_colour(&teststr);
+ else
+ colour = (int)zstrtol(teststr, (char **)&teststr, 10);
if (*teststr == ',')
teststr++;
else if (*teststr)
break;
found = 1;
/* skip out of range colours but keep scanning attributes */
- if (colour >= 256)
+ if (colour < 0 || colour >= 256)
continue;
if (is_fg) {
shft = TXT_ATTR_FG_COL_SHIFT;
@@ -404,12 +509,14 @@
*/
/**/
-void zle_set_highlight(void)
+static 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;
+ int lenfg, lenbg, len;
struct region_highlight *rhp;
special_atr_on = 0;
@@ -442,6 +549,18 @@
} else if (strpfx("isearch:", *atrs)) {
match_highlight(*atrs + 8, &(region_highlights[1].atr));
isearch_atr_on_set = 1;
+ } else if (strpfx("fg_start_code:", *atrs)) {
+ set_colour_code(*atrs + 14, &fg_bg_sequences[COL_SEQ_FG].start);
+ } else if (strpfx("fg_default_code:", *atrs)) {
+ set_colour_code(*atrs + 16, &fg_bg_sequences[COL_SEQ_FG].def);
+ } else if (strpfx("fg_end_code:", *atrs)) {
+ set_colour_code(*atrs + 12, &fg_bg_sequences[COL_SEQ_FG].end);
+ } else if (strpfx("bg_start_code:", *atrs)) {
+ set_colour_code(*atrs + 14, &fg_bg_sequences[COL_SEQ_BG].start);
+ } else if (strpfx("bg_default_code:", *atrs)) {
+ set_colour_code(*atrs + 16, &fg_bg_sequences[COL_SEQ_BG].def);
+ } else if (strpfx("bg_end_code:", *atrs)) {
+ set_colour_code(*atrs + 12, &fg_bg_sequences[COL_SEQ_BG].end);
}
}
}
@@ -453,9 +572,35 @@
region_highlights->atr = TXTSTANDOUT;
if (!isearch_atr_on_set)
region_highlights[1].atr = TXTUNDERLINE;
+
+ /* Allocate buffer for colour code composition */
+ lenfg = strlen(fg_bg_sequences[COL_SEQ_FG].def);
+ /* always need 1 character for non-default code */
+ if (lenfg < 1)
+ lenfg = 1;
+ lenfg += strlen(fg_bg_sequences[COL_SEQ_FG].start) +
+ strlen(fg_bg_sequences[COL_SEQ_FG].end);
+
+ lenbg = strlen(fg_bg_sequences[COL_SEQ_BG].def);
+ /* always need 1 character for non-default code */
+ if (lenbg < 1)
+ lenbg = 1;
+ lenbg += strlen(fg_bg_sequences[COL_SEQ_BG].start) +
+ strlen(fg_bg_sequences[COL_SEQ_BG].end);
+
+ len = lenfg > lenbg ? lenfg : lenbg;
+ colseq_buf = (char *)zalloc(len+1);
}
+/**/
+static void
+zle_free_highlight(void)
+{
+ /* Free buffer for colour code composition */
+ free(colseq_buf);
+}
+
/*
* Interface to the region_highlight ZLE parameter.
* Converts betwen a format like "P32 42 underline,bold" to
@@ -942,26 +1087,12 @@
rpms->sen = rpms->s + winw;
}
-/*
- * HERE: these need to be made configurable, somehow.
- * Ideally we need to make the complist stuff use the
- * same system, but that may be too much tied to the GNU ls
- * interface to make that possible.
- */
-/* Start of escape sequence for foreground colour */
-#define TC_COL_FG_START "\033[3"
-/* Start of escape sequence for background colour */
-#define TC_COL_BG_START "\033[4"
-/* End of either escape sequence */
-#define TC_COL_END "m"
-/* Numeric code (to be turned into ASCII) to reset default colour */
-#define TC_COL_DEFAULT 9
static void
-setcolourattribute(int colour, char *start, int tc, int def,
+setcolourattribute(int colour, int fg_bg, int tc, int def,
int use_termcap)
{
- char out[16], *ptr;
+ char *ptr;
/*
* If we're not restoring the default, and either have a
* colour value that is too large for ANSI, or have been told
@@ -980,14 +1111,17 @@
return;
}
- strcpy(out, start);
- if (def)
- colour = TC_COL_DEFAULT;
-
- ptr = out + strlen(start);
- *ptr++ = colour + '0';
- strcpy(ptr, TC_COL_END);
- tputs(out, 1, putshout);
+ strcpy(colseq_buf, fg_bg_sequences[fg_bg].start);
+
+ ptr = colseq_buf + strlen(colseq_buf);
+ if (def) {
+ strcpy(ptr, fg_bg_sequences[fg_bg].def);
+ while (*ptr)
+ ptr++;
+ } else
+ *ptr++ = colour + '0';
+ strcpy(ptr, fg_bg_sequences[fg_bg].end);
+ tputs(colseq_buf, 1, putshout);
}
/**/
@@ -1008,13 +1142,13 @@
tsetcap(TCUNDERLINEBEG, 0);
if (txtchangeisset(atr, TXTFGCOLOUR|TXTNOFGCOLOUR)) {
setcolourattribute(txtchangeget(atr, TXT_ATTR_FG_COL),
- TC_COL_FG_START, TCFGCOLOUR,
+ COL_SEQ_FG, TCFGCOLOUR,
txtchangeisset(atr, TXTNOFGCOLOUR),
txtchangeisset(atr, TXT_ATTR_FG_TERMCAP));
}
if (txtchangeisset(atr, TXTBGCOLOUR|TXTNOBGCOLOUR)) {
setcolourattribute(txtchangeget(atr, TXT_ATTR_BG_COL),
- TC_COL_BG_START, TCBGCOLOUR,
+ COL_SEQ_BG, TCBGCOLOUR,
txtchangeisset(atr, TXTNOBGCOLOUR),
txtchangeisset(atr, TXT_ATTR_BG_TERMCAP));
}
@@ -1796,6 +1930,8 @@
if (tmpalloced)
zfree(tmpline, tmpll * sizeof(*tmpline));
+ zle_free_highlight();
+
/* if we have a new list showing, note it; if part of the list has been
overwritten, redisplay it. We have to metafy line back before calling
completion code */
@@ -2711,6 +2847,15 @@
vcs = pos;
}
+/* Provided for loading the module in a modular fashion */
+
+/**/
+void
+zle_refresh_boot(void)
+{
+ set_default_colour_sequences();
+}
+
/* Provided for unloading the module in a modular fashion */
/**/
@@ -2722,4 +2867,6 @@
if (region_highlights)
zfree(region_highlights,
sizeof(struct region_highlight) * n_region_highlights);
+
+ free_colour_sequences();
}
Messages sorted by:
Reverse Date,
Date,
Thread,
Author