From 72f7f904e8734c2ee73b77e35e60ecb86148bc60 Mon Sep 17 00:00:00 2001 From: Mikael Magnusson Date: Sun, 6 Sep 2015 22:25:21 +0200 Subject: Add match-bracket widget that takes a position and/or parameter to store result, and does no weird vi stuff I use this in my zle-line-pre-redraw hook, local -a hackcol=(red cyan) local mpos cpos off for off in 0 1; do (( cpos = CURSOR - off )) if (( cpos >= 0 )) && zle .match-bracket $cpos mpos; then region_highlight+=("$((cpos)) $((cpos+1)) bold,bg=${hackcol[2]},fg=black" "$((mpos)) $((mpos+1)) bold,bg=${hackcol[1]},fg=black") break fi done --- Src/Zle/iwidgets.list | 1 + Src/Zle/zle_move.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/Src/Zle/iwidgets.list b/Src/Zle/iwidgets.list index 2b2654c5d..183d75c17 100644 --- a/Src/Zle/iwidgets.list +++ b/Src/Zle/iwidgets.list @@ -83,6 +83,7 @@ "list-choices", listchoices, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL | ZLE_ISCOMP "list-expand", listexpand, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL "magic-space", magicspace, ZLE_KEEPSUFFIX | ZLE_MENUCMP +"match-bracket", matchbracket, ZLE_KEEPSUFFIX | ZLE_MENUCMP "menu-complete", menucomplete, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_ISCOMP "menu-expand-or-complete", menuexpandorcomplete, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_ISCOMP "neg-argument", negargument, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL | ZLE_NOTCOMMAND diff --git a/Src/Zle/zle_move.c b/Src/Zle/zle_move.c index 155fda80d..1a2ab2e00 100644 --- a/Src/Zle/zle_move.c +++ b/Src/Zle/zle_move.c @@ -589,6 +589,80 @@ vigotocolumn(UNUSED(char **args)) return 0; } +/**/ +int +matchbracket(char **args) +{ + int ocs = zlecs, dir, ct; + unsigned char oth, me; + + if (*args) { + char *end = NULL; + zlecs = zstrtol(*args, &end, 10); + if (end && end != *args && *end == '\0') + args++; + else + zlecs = ocs; + } + + if (zlecs == zlell || zleline[zlecs] == '\n') { + zlecs = ocs; + return 1; + } + switch (me = zleline[zlecs]) { + case '{': + dir = 1; + oth = '}'; + break; + case /*{*/ '}': + dir = -1; + oth = '{'; /*}*/ + break; + case '(': + dir = 1; + oth = ')'; + break; + case ')': + dir = -1; + oth = '('; + break; + case '[': + dir = 1; + oth = ']'; + break; + case ']': + dir = -1; + oth = '['; + break; + default: + zlecs = ocs; + return 1; + } + ct = 1; + while (zlecs >= 0 && zlecs < zlell && ct) { + if (dir < 0) + DECCS(); + else + INCCS(); + if (zleline[zlecs] == oth) + ct--; + else if (zleline[zlecs] == me) + ct++; + } + if (zlecs < 0 || zlecs >= zlell) { + zlecs = ocs; + return 1; + } + + if (*args) { + char digs[100]; + sprintf(digs, "%d", zlecs); + zlecs = ocs; + setsparam(*args, ztrdup(digs)); + } + return 0; +} + /**/ int vimatchbracket(UNUSED(char **args)) -- cgit 1.4.1