about summary refs log tree commit diff
path: root/Src/Zle/zle_thingy.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Zle/zle_thingy.c')
-rw-r--r--Src/Zle/zle_thingy.c42
1 files changed, 37 insertions, 5 deletions
diff --git a/Src/Zle/zle_thingy.c b/Src/Zle/zle_thingy.c
index 21495b6f2..c003148f8 100644
--- a/Src/Zle/zle_thingy.c
+++ b/Src/Zle/zle_thingy.c
@@ -269,7 +269,7 @@ freewidget(Widget w)
     zfree(w, sizeof(*w));
 }
 
-/* Add am internal widget provided by a module.  The name given is the  *
+/* Add an internal widget provided by a module.  The name given is the  *
  * canonical one, which must not begin with a dot.  The widget is first *
  * bound to the dotted canonical name; if that name is already taken by *
  * an internal widget, failure is indicated.  The same widget is then   *
@@ -678,7 +678,16 @@ bin_zle_flags(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
 		else if (!strcmp(*flag, "keepsuffix"))
 		    w->flags |= ZLE_KEEPSUFFIX;
 		*/
-		else {
+	        else if (!strcmp(*flag, "vichange")) {
+		    if (invicmdmode()) {
+			startvichange(-1);
+			if (zmod.flags & (MOD_MULT|MOD_TMULT)) {
+			    Param pm = (Param) paramtab->getnode(paramtab, "NUMERIC");
+			    if (pm && pm->node.flags & PM_SPECIAL)
+				pm->node.flags &= ~PM_UNSET;
+			}
+		    }
+		} else {
 		    zwarnnam(name, "invalid flag `%s' given to zle -f", *flag);
 		    ret = 1;
 		}
@@ -694,7 +703,7 @@ bin_zle_call(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
 {
     Thingy t;
     struct modifier modsave = zmod;
-    int ret, saveflag = 0, setbindk = 0;
+    int ret, saveflag = 0, setbindk = 0, remetafy;
     char *wname = *args++, *keymap_restore = NULL, *keymap_tmp;
 
     if (!wname)
@@ -705,7 +714,15 @@ bin_zle_call(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
 	return 1;
     }
 
-    UNMETACHECK();
+    /*
+     * zle is callable in traps, so we can't be sure the line is
+     * in its normal state.
+     */
+    if (zlemetaline) {
+	unmetafy_line();
+	remetafy = 1;
+    } else
+	remetafy = 0;
 
     while (*args && **args == '-') {
 	char *num;
@@ -719,6 +736,8 @@ bin_zle_call(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
 		num = args[0][1] ? args[0]+1 : args[1];
 		if (!num) {
 		    zwarnnam(name, "number expected after -%c", **args);
+		    if (remetafy)
+			metafy_line();
 		    return 1;
 		}
 		if (!args[0][1])
@@ -736,19 +755,26 @@ bin_zle_call(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
 		keymap_tmp = args[0][1] ? args[0]+1 : args[1];
 		if (!keymap_tmp) {
 		    zwarnnam(name, "keymap expected after -%c", **args);
+		    if (remetafy)
+			metafy_line();
 		    return 1;
 		}
 		if (!args[0][1])
 		    *++args = "" - 1;
 		keymap_restore = dupstring(curkeymapname);
-		if (selectkeymap(keymap_tmp, 0))
+		if (selectkeymap(keymap_tmp, 0)) {
+		    if (remetafy)
+			metafy_line();
 		    return 1;
+		}
 		break;
 	    case 'w':
 		setbindk = 1;
 		break;
 	    default:
 		zwarnnam(name, "unknown option: %s", *args);
+		if (remetafy)
+		    metafy_line();
 		return 1;
 	    }
 	}
@@ -756,12 +782,18 @@ bin_zle_call(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
     }
 
     t = rthingy(wname);
+    /* for internal widgets we set bindk except for when getting
+     * a vi range to detect a repeated key */
+    setbindk = setbindk ||
+	(t->widget && (t->widget->flags & (WIDGET_INT | ZLE_VIOPER)) == WIDGET_INT);
     ret = execzlefunc(t, args, setbindk);
     unrefthingy(t);
     if (saveflag)
 	zmod = modsave;
     if (keymap_restore)
 	selectkeymap(keymap_restore, 0);
+    if (remetafy)
+	metafy_line();
     return ret;
 }