about summary refs log tree commit diff
path: root/Src
diff options
context:
space:
mode:
Diffstat (limited to 'Src')
-rw-r--r--Src/Zle/zle_main.c7
-rw-r--r--Src/Zle/zle_refresh.c4
-rw-r--r--Src/Zle/zle_tricky.c24
-rw-r--r--Src/glob.c64
-rw-r--r--Src/init.c1
-rw-r--r--Src/mkbltnmlst.sh2
-rw-r--r--Src/module.c34
7 files changed, 98 insertions, 38 deletions
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index 7a5d0d7db..4d9c99f87 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -579,12 +579,7 @@ execzlefunc(Thingy func)
 
 	if(!(wflags & ZLE_KEEPSUFFIX))
 	    removesuffix();
-	if(!(wflags & ZLE_MENUCMP) ||
-	   ((wflags & WIDGET_NCOMP) && compwidget != w)) {
-	    /* If we are doing a special completion, and the widget
-	     * is not the one currently in use for special completion,
-	     * we are starting a new completion.
-	     */
+	if(!(wflags & ZLE_MENUCMP)) {
 	    fixsuffix();
 	    invalidatelist();
 	}
diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c
index 1f1063b8d..6b0239961 100644
--- a/Src/Zle/zle_refresh.c
+++ b/Src/Zle/zle_refresh.c
@@ -327,7 +327,7 @@ zrefresh(void)
             vcs = 0;
         else if (!clearflag && lpromptbuf[0]) {
             zputs(lpromptbuf, shout);
-	    if (lpromptw == 0)
+	    if (lpromptw == 0 && lprompth == 1)
 		zputs("\n", shout);	/* works with both hasam and !hasam */
 	}
 	if (clearflag) {
@@ -947,7 +947,7 @@ tc_rightcurs(int cl)
 		zputc('\r', shout);
 	    tc_upcurs(lprompth - 1);
 	    zputs(lpromptbuf, shout);
-	    if (lpromptw == 0)
+	    if (lpromptw == 0 && lprompth == 1)
 		zputs("\n", shout);	/* works with both hasam and !hasam */
 	}
 	i = lpromptw;
diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c
index 1f13d55b4..92b167cfe 100644
--- a/Src/Zle/zle_tricky.c
+++ b/Src/Zle/zle_tricky.c
@@ -72,6 +72,10 @@ static int wb, we;
 
 static int offs;
 
+/* the last completion widget called */
+
+static Widget lastcompwidget;
+
 /* These control the type of completion that will be done.  They are      *
  * affected by the choice of ZLE command and by relevant shell options.   *
  * usemenu is set to 2 if we have to start automenu and 3 if we have to   *
@@ -756,10 +760,12 @@ docomplete(int lst)
 
     /* If we are doing a menu-completion... */
 
-    if (menucmp && lst != COMP_LIST_EXPAND) {
+    if (menucmp && lst != COMP_LIST_EXPAND && compwidget &&
+	compwidget == lastcompwidget) {
 	do_menucmp(lst);
 	return;
     }
+    lastcompwidget = compwidget;
 
     /* We may have to reset the cursor to its position after the   *
      * string inserted by the last completion. */
@@ -6970,10 +6976,20 @@ do_single(Cmatch m)
 		t = 1;
 	    else {
 		/* Build the path name. */
-		p = (char *) zhalloc(strlen(prpre) + strlen(str) +
+		if (m->ripre && !*psuf) {
+		    int ne = noerrs;
+
+		    p = (char *) zhalloc(strlen(m->ripre) + strlen(str) + 1);
+		    sprintf(p, "%s%s", m->ripre, str);
+		    noerrs = 1;
+		    parsestr(p);
+		    singsub(&p);
+		    noerrs = ne;
+		} else {
+		    p = (char *) zhalloc(strlen(prpre) + strlen(str) +
 				 strlen(psuf) + 3);
-		sprintf(p, "%s%s%s", (prpre && *prpre) ? prpre : "./", str, psuf);
-
+		    sprintf(p, "%s%s%s", (prpre && *prpre) ? prpre : "./", str, psuf);
+		}
 		/* And do the stat. */
 		t = (!(sr = ztat(p, &buf, 0)) && S_ISDIR(buf.st_mode));
 	    }
diff --git a/Src/glob.c b/Src/glob.c
index 0d6d4d778..47ca1d659 100644
--- a/Src/glob.c
+++ b/Src/glob.c
@@ -625,6 +625,36 @@ getglobflags(void)
     return 0;
 }
 
+/**/
+static void
+parse_charset(void)
+{
+    /* Character set: brackets had better match */
+    if (pptr[1] == Outbrack)
+	*++pptr = ']';
+    else if ((pptr[1] == Hat || pptr[1] == '^' || pptr[1] == '!') &&
+	     pptr[2] == Outbrack)
+	*(pptr += 2) = ']';
+    while (*++pptr && *pptr != Outbrack) {
+	if (itok(*pptr)) {
+	    /* POSIX classes: make sure it's a real one,
+	     * leave the Inbrack tokenised if so.
+	     * We need to untokenize the Outbrack since otherwise
+	     * it might look like we got to the end of the range without
+	     * matching; we also need to accept ']' instead of
+	     * Outbrack in case this has already happened.
+	     */
+	    char *nptr;
+	    if (*pptr == Inbrack && pptr[1] == ':'
+		&& (nptr = strchr(pptr+2, ':')) && 
+		(*++nptr == Outbrack || *nptr == ']'))
+		*(pptr = nptr) = ']';
+	    else
+		*pptr = ztokens[*pptr - Pound];
+	}
+    }
+}
+
 /* enum used with ksh-like patterns, @(...) etc. */
 
 enum { KF_NONE, KF_AT, KF_QUEST, KF_STAR, KF_PLUS, KF_NOT };
@@ -853,24 +883,7 @@ parsecomp(int gflag)
 	    if (*pptr != Outang)
 		return NULL;
 	} else if (*pptr == Inbrack) {
-	    /* Character set: brackets had better match */
-	    if (pptr[1] == Outbrack)
-		*++pptr = ']';
-	    else if ((pptr[1] == Hat || pptr[1] == '^' || pptr[1] == '!') &&
-		     pptr[2] == Outbrack)
-		*(pptr += 2) = ']';
-	    while (*++pptr && *pptr != Outbrack) {
-		if (itok(*pptr)) {
-		    /* POSIX classes: make sure it's a real one, *
-		     * leave the Inbrack tokenised if so.        */
-		    char *nptr;
-		    if (*pptr == Inbrack && pptr[1] == ':'
-			&& (nptr = strchr(pptr+2, ':')) && 
-			*++nptr == Outbrack)
-			pptr = nptr;
-		    *pptr = ztokens[*pptr - Pound];
-		}
-	    }
+	    parse_charset();
 	    if (*pptr != Outbrack)
 		return NULL;
 	} else if (itok(*pptr) && *pptr != Star && *pptr != Quest)
@@ -912,7 +925,20 @@ parsecompsw(int gflag)
 		break;
 	    else if (*sptr == Bar && !pct)
 		break;
-	    else if (*sptr == Tilde && !pct) {
+	    else if (*sptr == Inbrack) {
+		/*
+		 * Character classes can have tokenized characters in,
+		 * so we have to parse them properly.
+		 */
+		char *bstart = pptr;
+
+		pptr = sptr;
+		parse_charset();
+		sptr = pptr;
+		pptr = bstart;
+		if (*sptr != Outbrack)
+		    break;
+	    } else if (*sptr == Tilde && !pct) {
 		tail = NULL;
 		break;
 	    }
diff --git a/Src/init.c b/Src/init.c
index 9fc4a81fb..6ad1e5100 100644
--- a/Src/init.c
+++ b/Src/init.c
@@ -559,6 +559,7 @@ setupvals(void)
     module_path = mkarray(ztrdup(MODULE_DIR));
     modules = newlinklist();
 #endif
+    bltinmodules = newlinklist();
 
     /* Set default prompts */
     if(unset(INTERACTIVE)) {
diff --git a/Src/mkbltnmlst.sh b/Src/mkbltnmlst.sh
index efaa803ad..b58d1e1dd 100644
--- a/Src/mkbltnmlst.sh
+++ b/Src/mkbltnmlst.sh
@@ -61,6 +61,6 @@ for bin_mod in $bin_mods; do
 		exit 1 ;;
 	esac
     done
-    echo "    mod.nam = \"$bin_mod\"; setup_$bin_mod(&mod); boot_$bin_mod(&mod);"
+    echo "    register_module(mod.nam = \"$bin_mod\"); setup_$bin_mod(&mod); boot_$bin_mod(&mod);"
     done_mods="$done_mods$bin_mod "
 done
diff --git a/Src/module.c b/Src/module.c
index 1117571a4..ff386c630 100644
--- a/Src/module.c
+++ b/Src/module.c
@@ -30,6 +30,12 @@
 #include "zsh.mdh"
 #include "module.pro"
 
+/* List of builtin modules. */
+
+/**/
+LinkList bltinmodules;
+
+
 /* The `zsh' module contains all the base code that can't actually be built *
  * as a separate module.  It is initialised by main(), so there's nothing   *
  * for the boot function to do.                                             */
@@ -48,6 +54,17 @@ boot_zsh(Module m)
     return 0;
 }
 
+/* This registers a builtin module.                                   */
+
+/**/
+void
+register_module(char *n)
+{
+    PERMALLOC {
+	addlinknode(bltinmodules, n);
+    } LASTALLOC;
+}
+
 /* addbuiltin() can be used to add a new builtin.  It returns zero on *
  * success, 1 on failure.  The only possible type of failure is that  *
  * a builtin with the specified name already exists.  An autoloaded   *
@@ -573,29 +590,34 @@ load_module(char const *name)
  * about trying to load a module with a full path name in restricted mode.
  * The last argument should be non-zero if this function should signal an
  * error if the module is already loaded.
- * The return value is the module of NULL if the module couldn't be loaded. */
+ * The return value is non-zero if the module was found or loaded. */
 
 /**/
-Module
+int
 require_module(char *nam, char *module, int res, int test)
 {
     Module m = NULL;
     LinkNode node;
 
+    /* First see if the module is linked in. */
+    for (node = firstnode(bltinmodules); node; incnode(node)) {
+	if (!strcmp((char *) getdata(node), nam))
+	    return 1;
+    }
     node = find_module(module);
     if (node && (m = ((Module) getdata(node)))->handle &&
 	!(m->flags & MOD_UNLOAD)) {
 	if (test) {
 	    zwarnnam(nam, "module %s already loaded.", module, 0);
-	    return NULL;
+	    return 0;
 	}
     } else if (res && isset(RESTRICTED) && strchr(module, '/')) {
 	zwarnnam(nam, "%s: restricted", module, 0);
-	return NULL;
+	return 0;
     } else
-	return load_module(module);
+	return !!load_module(module);
 
-    return m;
+    return 1;
 }
 
 /**/