aboutsummaryrefslogtreecommitdiff
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;
}
/**/