diff options
Diffstat (limited to 'Src')
-rw-r--r-- | Src/Zle/zle_main.c | 7 | ||||
-rw-r--r-- | Src/Zle/zle_refresh.c | 4 | ||||
-rw-r--r-- | Src/Zle/zle_tricky.c | 24 | ||||
-rw-r--r-- | Src/glob.c | 64 | ||||
-rw-r--r-- | Src/init.c | 1 | ||||
-rw-r--r-- | Src/mkbltnmlst.sh | 2 | ||||
-rw-r--r-- | Src/module.c | 34 |
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; } /**/ |