From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-3.4 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 1599 invoked from network); 9 Jan 2023 23:19:09 -0000 Received: from zero.zsh.org (2a02:898:31:0:48:4558:7a:7368) by inbox.vuxu.org with ESMTPUTF8; 9 Jan 2023 23:19:09 -0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=zsh.org; s=rsa-20210803; h=List-Archive:List-Owner:List-Post:List-Unsubscribe: List-Subscribe:List-Help:List-Id:Sender:Message-ID:Date:Content-ID: Content-Type:MIME-Version:Subject:To:From:Reply-To:Cc: Content-Transfer-Encoding:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References; bh=nuYevFXRXzj9+lwbipXbkCYImsRt/7K915Gg9J42mn8=; b=UMM7nB/7QFRmBzLm7CatjhiSdz StcitYEnY7hCjF0DBfYxxmb3N2aENP51EpepvxrcKUC7vQ1saLhj2iMZRe0d8LsaphdX2wde6Y5bY GulXHoSGToeuWN2//JFU/x1RONasezRgv4YULpS1QF37FWQNKAKYlX5/y02LTOvFOn1xuGm+Ngo+R mrR2ttZpfNjHoZyo3GiGRmyblMKN/OxYCxksbU3+Y7uVRe4w0xkO9vKjLV5k8Kl2hWFLes/fVbBW0 gYzq5xvuLOFM659YoKtKnz4FcZsZtPFoc4DV45gP3/qr46Q7dpYFyuKW0IcLgmi5SSLzJxinnEmQu UTtfqAIQ==; Received: by zero.zsh.org with local id 1pF1Q5-0007T3-29; Mon, 09 Jan 2023 23:19:09 +0000 Received: by zero.zsh.org with esmtpsa (TLS1.3:TLS_AES_256_GCM_SHA384:256) id 1pF1PZ-00079n-9e; Mon, 09 Jan 2023 23:18:37 +0000 Received: from [192.168.178.21] (helo=hydra) by mail.kiddle.eu with esmtp(Exim 4.95) (envelope-from ) id 1pF1PY-000Eby-Ls for zsh-workers@zsh.org; Tue, 10 Jan 2023 00:18:36 +0100 From: Oliver Kiddle To: Zsh workers Subject: PATCH: support for highlighting ellipses in zle MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <56168.1673306316.1@hydra> Date: Tue, 10 Jan 2023 00:18:36 +0100 Message-ID: <56169-1673306316.671598@6AFd.zOJq.J0p9> X-Seq: 51291 Archived-At: X-Loop: zsh-workers@zsh.org Errors-To: zsh-workers-owner@zsh.org Precedence: list Precedence: bulk Sender: zsh-workers-request@zsh.org X-no-archive: yes List-Id: List-Help: , List-Subscribe: , List-Unsubscribe: , List-Post: List-Owner: List-Archive: If the line is too big for the terminal window, zle prints markers such as ">...." at the beginning or "<...." at the end. There's also other variations. This patch adds support for colour highlighting of these markers with the key "ellipsis" in zle_highlight. Other names could be used, "marker" perhaps? By default, I've gone with blue on a yellow background. We've generally been very conservative in our choices of default attributes but these markers are only rarely seen and probably should stand out more. I'm not inclined to argue hard for any particular choice, however. It might also be nice to be able to configure the exact characters used and substitute in some suitable Unicode characters. I won't be doing that so if someone is looking for ideas, feel free to go ahead. The lack of symmetry in the existing characters seems a little odd to me, why not "....>" as the start? Applying TXT_ERROR as the attributes to zr_sp and zr_zr (' ' and '\0', respectively) in my earlier patch did actually break things somewhat which this patch fixes. Oliver diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo index 60254e828..c622483d7 100644 --- a/Doc/Zsh/zle.yo +++ b/Doc/Zsh/zle.yo @@ -2691,6 +2691,9 @@ for different completions. item(tt(paste))( Following a command to paste text, the characters that were inserted. ) +item(tt(ellipsis))( +Markers used to indicate where the text doesn't fit within the terminal. +) enditem() When tt(region_highlight) is set, the contexts that describe a region DASH()- diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c index b196370dc..a587f696a 100644 --- a/Src/Zle/zle_refresh.c +++ b/Src/Zle/zle_refresh.c @@ -203,12 +203,12 @@ int predisplaylen, postdisplaylen; /* - * Attributes used by default on the command line, and - * attributes for highlighting special (unprintable) characters - * displayed on screen. + * Attributes used by default on the command line, + * for highlighting special (unprintable) characters displayed on screen, + * and for ellipsis continuation markers. */ -static zattr default_attr, special_attr; +static zattr default_attr, special_attr, ellipsis_attr; /* * Array of region highlights, no special termination. @@ -259,8 +259,8 @@ static const REFRESH_ELEMENT zr_cr = { ZWC('\r'), TXT_ERROR }; static const REFRESH_ELEMENT zr_dt = { ZWC('.'), TXT_ERROR }; #endif static const REFRESH_ELEMENT zr_nl = { ZWC('\n'), TXT_ERROR }; -static const REFRESH_ELEMENT zr_sp = { ZWC(' '), TXT_ERROR }; -static const REFRESH_ELEMENT zr_zr = { ZWC('\0'), TXT_ERROR }; +static const REFRESH_ELEMENT zr_sp = { ZWC(' '), 0 }; +static const REFRESH_ELEMENT zr_zr = { ZWC('\0'), 0 }; /* * Constant arrays to be copied into place: these are memcpy'd, @@ -269,10 +269,10 @@ static const REFRESH_ELEMENT zr_zr = { ZWC('\0'), TXT_ERROR }; static const REFRESH_ELEMENT zr_end_ellipsis[] = { { ZWC(' '), 0 }, { ZWC('<'), 0 }, - { ZWC('.'), 0 }, - { ZWC('.'), 0 }, - { ZWC('.'), 0 }, - { ZWC('.'), 0 }, + { ZWC('.'), TXT_ERROR }, + { ZWC('.'), TXT_ERROR }, + { ZWC('.'), TXT_ERROR }, + { ZWC('.'), TXT_ERROR }, { ZWC(' '), 0 }, }; #define ZR_END_ELLIPSIS_SIZE \ @@ -281,16 +281,16 @@ static const REFRESH_ELEMENT zr_end_ellipsis[] = { static const REFRESH_ELEMENT zr_mid_ellipsis1[] = { { ZWC(' '), 0 }, { ZWC('<'), 0 }, - { ZWC('.'), 0 }, - { ZWC('.'), 0 }, - { ZWC('.'), 0 }, - { ZWC('.'), 0 }, + { ZWC('.'), TXT_ERROR }, + { ZWC('.'), TXT_ERROR }, + { ZWC('.'), TXT_ERROR }, + { ZWC('.'), TXT_ERROR }, }; #define ZR_MID_ELLIPSIS1_SIZE \ ((int)(sizeof(zr_mid_ellipsis1)/sizeof(zr_mid_ellipsis1[0]))) static const REFRESH_ELEMENT zr_mid_ellipsis2[] = { - { ZWC('>'), 0 }, + { ZWC('>'), TXT_ERROR }, { ZWC(' '), 0 }, }; #define ZR_MID_ELLIPSIS2_SIZE \ @@ -298,10 +298,10 @@ static const REFRESH_ELEMENT zr_mid_ellipsis2[] = { static const REFRESH_ELEMENT zr_start_ellipsis[] = { { ZWC('>'), 0 }, - { ZWC('.'), 0 }, - { ZWC('.'), 0 }, - { ZWC('.'), 0 }, - { ZWC('.'), 0 }, + { ZWC('.'), TXT_ERROR }, + { ZWC('.'), TXT_ERROR }, + { ZWC('.'), TXT_ERROR }, + { ZWC('.'), TXT_ERROR }, }; #define ZR_START_ELLIPSIS_SIZE \ ((int)(sizeof(zr_start_ellipsis)/sizeof(zr_start_ellipsis[0]))) @@ -321,6 +321,7 @@ zle_set_highlight(void) int isearch_attr_set = 0; int suffix_attr_set = 0; int paste_attr_set = 0; + int ellipsis_attr_set = 0; struct region_highlight *rhp; special_attr = default_attr = 0; @@ -361,6 +362,9 @@ zle_set_highlight(void) } else if (strpfx("paste:", *atrs)) { match_highlight(*atrs + 6, &(region_highlights[3].atr)); paste_attr_set = 1; + } else if (strpfx("ellipsis:", *atrs)) { + match_highlight(*atrs + 9, &ellipsis_attr); + ellipsis_attr_set = 1; } } } @@ -376,6 +380,9 @@ zle_set_highlight(void) region_highlights[2].atr = TXTBOLDFACE; if (!paste_attr_set) region_highlights[3].atr = TXTSTANDOUT; + if (!ellipsis_attr_set) + ellipsis_attr = TXTBGCOLOUR | ((zattr) 3 << TXT_ATTR_BG_COL_SHIFT) | + TXTFGCOLOUR | ((zattr) 4 << TXT_ATTR_FG_COL_SHIFT); allocate_colour_buffer(); } @@ -599,10 +606,8 @@ zwcputc(const REFRESH_ELEMENT *c) VARARR(char, mbtmp, MB_CUR_MAX + 1); #endif - if (c->atr != TXT_ERROR) { - treplaceattrs(c->atr); - applytextattributes(0); - } + treplaceattrs(c->atr); + applytextattributes(0); #ifdef MULTIBYTE_SUPPORT if (c->atr & TXT_MULTIWORD_MASK) { @@ -1479,6 +1484,7 @@ zrefresh(void) } #endif ZR_memcpy(rpms.sen, zr_end_ellipsis, ZR_END_ELLIPSIS_SIZE); + rpms.sen[1].atr = ellipsis_attr; #ifdef MULTIBYTE_SUPPORT /* Extend to the end if we backed off for a wide character */ if (extra_ellipsis) { @@ -1514,6 +1520,7 @@ zrefresh(void) } #endif ZR_memcpy(rpms.sen, zr_mid_ellipsis1, ZR_MID_ELLIPSIS1_SIZE); + rpms.sen[1].atr = ellipsis_attr; rpms.sen += ZR_MID_ELLIPSIS1_SIZE; #ifdef MULTIBYTE_SUPPORT /* Extend if we backed off for a wide character */ @@ -1523,6 +1530,7 @@ zrefresh(void) } #endif ZR_memcpy(rpms.sen, zr_mid_ellipsis2, ZR_MID_ELLIPSIS2_SIZE); + rpms.sen[1].atr = prompt_attr; nbuf[rpms.tosln][winw] = nbuf[rpms.tosln][winw + 1] = zr_zr; } @@ -1555,7 +1563,9 @@ zrefresh(void) t0 = winw - lpromptw; t0 = t0 > ZR_START_ELLIPSIS_SIZE ? ZR_START_ELLIPSIS_SIZE : t0; ZR_memcpy(nbuf[0] + lpromptw, zr_start_ellipsis, t0); + (*nbuf + lpromptw)->atr = ellipsis_attr; ZR_memset(nbuf[0] + lpromptw + t0, zr_sp, winw - t0 - lpromptw); + (*nbuf + lpromptw + t0)->atr = prompt_attr; nbuf[0][winw] = nbuf[0][winw + 1] = zr_zr; } @@ -2514,11 +2524,11 @@ singlerefresh(ZLE_STRING_T tmpline, int tmpll, int tmpcs) } if (winpos) { vbuf[winpos].chr = ZWC('<'); /* line continues to the left */ - vbuf[winpos].atr = 0; + vbuf[winpos].atr = ellipsis_attr; } if ((int)ZR_strlen(vbuf + winpos) > (winw - hasam)) { vbuf[winpos + winw - hasam - 1].chr = ZWC('>'); /* line continues to right */ - vbuf[winpos + winw - hasam - 1].atr = 0; + vbuf[winpos + winw - hasam - 1].atr = ellipsis_attr; vbuf[winpos + winw - hasam] = zr_zr; } ZR_strcpy(nbuf[0], vbuf + winpos); diff --git a/Src/prompt.c b/Src/prompt.c index 4f29a6728..39fcf5eb7 100644 --- a/Src/prompt.c +++ b/Src/prompt.c @@ -1648,6 +1648,9 @@ cleartextattributes(int flags) mod_export void treplaceattrs(zattr newattrs) { + if (newattrs == TXT_ERROR) + return; + if (txtunknownattrs) { /* Set current attributes to the opposite of the new ones * for any that are unknown so that applytextattributes()