about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMikael Magnusson <mikachu@gmail.com>2015-09-06 22:25:21 +0200
committerMikael Magnusson <mikachu@gmail.com>2015-09-27 02:28:41 +0200
commit72f7f904e8734c2ee73b77e35e60ecb86148bc60 (patch)
tree3ffa1b53e5fe68ca59dedfe356e69a7d9ded4eae
parent8ab150a867ff9ab87d2efdf5cfce919614f2ddbb (diff)
downloadzsh-mikachu/redrawhook.tar.gz
zsh-mikachu/redrawhook.tar.xz
zsh-mikachu/redrawhook.zip
Add match-bracket widget that takes a position and/or parameter to store result, and does no weird vi stuff mikachu/redrawhook
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
-rw-r--r--Src/Zle/iwidgets.list1
-rw-r--r--Src/Zle/zle_move.c74
2 files changed, 75 insertions, 0 deletions
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
@@ -591,6 +591,80 @@ vigotocolumn(UNUSED(char **args))
 
 /**/
 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))
 {
     int ocs = zlecs, dir, ct;