From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22976 invoked from network); 16 Jan 1998 11:43:19 -0000 Received: from math.gatech.edu (list@130.207.146.50) by ns1.primenet.com.au with SMTP; 16 Jan 1998 11:43:19 -0000 Received: (from list@localhost) by math.gatech.edu (8.8.5/8.8.5) id GAA17230; Fri, 16 Jan 1998 06:29:28 -0500 (EST) Resent-Date: Fri, 16 Jan 1998 06:29:28 -0500 (EST) From: pws@ibmth.difi.unipi.it Message-Id: <9801161052.AA45436@ibmth.difi.unipi.it> To: zsh-workers@math.gatech.edu (Zsh hackers list) Subject: PATCH: 3.1.2-zefram3: history completion Date: Fri, 16 Jan 98 11:52:35 +0100 Resent-Message-ID: <"au-X91.0.6D4.NIqlq"@math> Resent-From: zsh-workers@math.gatech.edu X-Mailing-List: archive/latest/3718 X-Loop: zsh-workers@math.gatech.edu Precedence: list Resent-Sender: zsh-workers-request@math.gatech.edu Here's a patch to do completion from the history list as a special command. This is definitely useful when completing a long path name if filename completion is also an option; you can choose whether to complete chunk by chunk or to look for some long name which has already been typed. It's bound by default to M-/ in emacs mode, just like in emacs itself. I implemented it in a fairly simple way, just by forcing the completion structure to an appropriate value, so the changes aren't big. Most of the rest of the patch is just book-keeping. You could generalise this, allowing a particular binding to specify completion with an ad hoc compctl; probably Zefram could do this with widgets, e.g. a new option to either zle or compctl would remember the completion list as a widget; binding it would do completion with the given compctl. On the other hand, it's nice to have this particular version bound by default which is messy the other way. I had to invent a new flag ZLE_HISTCOMP for use with menu completion: the point is that you may, for example, complete a path prefix with ordinary completion then decide to switch to history completion to get a long filename starting with that. At this point, the history completion needs to know the previous command was ordinary completion so it doesn't just mindlessly cycle the same choices. On the other hand, I haven't done it the other way, so that after you type M-/, TAB will still cycle the possibilities just produced (which is what it usually does no matter how the list was produced). I hope this is rational. I also moved the COMP_ flags to an enum; these are now widely used elsewhere in the code. *** Doc/Zsh/zle.yo.histcomp Fri Jan 16 12:13:34 1998 --- Doc/Zsh/zle.yo Fri Jan 16 12:13:49 1998 *************** *** 794,799 **** --- 794,805 ---- item(tt(complete-word))( Attempt completion on the current word. ) + tindex(history-complete-word) + item(tt(history-complete-word) (ESC-/) (unbound) (unbound))( + Attempt completion on the current word using words on the history list + as possibilities. This is useful, for example, when completing a long + path name which has already been used. + ) tindex(delete-char-or-list) item(tt(delete-char-or-list) (^D) (unbound) (unbound))( Delete the character under the cursor. If the cursor *************** *** 919,924 **** --- 925,931 ---- tt(list-choices), tt(delete-char-or-list), tt(complete-word), + tt(history-complete-word), tt(accept-line), tt(expand-or-complete) and tt(expand-or-complete-prefix). *** Src/Zle/iwidgets.list.histcomp Fri Jan 16 10:33:02 1998 --- Src/Zle/iwidgets.list Fri Jan 16 11:59:03 1998 *************** *** 59,64 **** --- 59,65 ---- "gosmacs-transpose-chars", gosmacstransposechars, 0 "history-beginning-search-backward", historybeginningsearchbackward, 0 "history-beginning-search-forward", historybeginningsearchforward, 0 + "history-complete-word", historycompleteword, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_HISTCOMP "history-incremental-search-backward", historyincrementalsearchbackward, 0 "history-incremental-search-forward", historyincrementalsearchforward, 0 "history-search-backward", historysearchbackward, 0 *** Src/Zle/widgets.list.histcomp Fri Jan 16 10:33:02 1998 --- Src/Zle/widgets.list Fri Jan 16 11:59:13 1998 *************** *** 52,57 **** --- 52,58 ---- W(0, t_gosmacstransposechars, gosmacstransposechars) W(0, t_historybeginningsearchbackward, historybeginningsearchbackward) W(0, t_historybeginningsearchforward, historybeginningsearchforward) + W(ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_HISTCOMP, t_historycompleteword, historycompleteword) W(0, t_historyincrementalsearchbackward, historyincrementalsearchbackward) W(0, t_historyincrementalsearchforward, historyincrementalsearchforward) W(0, t_historysearchbackward, historysearchbackward) *** Src/Zle/zle.h.histcomp Fri Jan 16 11:50:23 1998 --- Src/Zle/zle.h Fri Jan 16 11:58:53 1998 *************** *** 58,63 **** --- 58,64 ---- #define ZLE_LASTCOL (1<<5) /* command maintains lastcol correctly */ #define ZLE_KILL (1<<6) #define ZLE_KEEPSUFFIX (1<<9) /* DON'T remove added suffix */ + #define ZLE_HISTCOMP (1<<10) /* Last completion was from history */ /* thingies */ *** Src/Zle/zle_bindings.c.histcomp Fri Jan 16 11:04:12 1998 --- Src/Zle/zle_bindings.c Fri Jan 16 11:04:27 1998 *************** *** 171,177 **** /* M-, */ z_undefinedkey, /* M-- */ z_negargument, /* M-. */ z_insertlastword, ! /* M-/ */ z_undefinedkey, /* M-0 */ z_digitargument, /* M-1 */ z_digitargument, /* M-2 */ z_digitargument, --- 171,177 ---- /* M-, */ z_undefinedkey, /* M-- */ z_negargument, /* M-. */ z_insertlastword, ! /* M-/ */ z_historycompleteword, /* M-0 */ z_digitargument, /* M-1 */ z_digitargument, /* M-2 */ z_digitargument, *** Src/Zle/zle_misc.c.histcomp Fri Jan 16 11:01:22 1998 --- Src/Zle/zle_misc.c Fri Jan 16 11:01:37 1998 *************** *** 658,663 **** --- 658,664 ---- if (cmd == Th(z_listchoices) || cmd == Th(z_deletecharorlist) || cmd == Th(z_expandorcomplete) || cmd == Th(z_completeword) || cmd == Th(z_expandorcompleteprefix) || cmd == Th(z_vicmdmode) || + cmd == Th(z_historycompleteword) || cmd == Th(z_acceptline) || c == ' ' || c == '\t') { cmdambig = 100; *** Src/Zle/zle_tricky.c.histcomp Fri Jan 16 10:33:01 1998 --- Src/Zle/zle_tricky.c Fri Jan 16 11:59:01 1998 *************** *** 215,226 **** return 1; } ! #define COMP_COMPLETE 0 ! #define COMP_LIST_COMPLETE 1 ! #define COMP_SPELL 2 ! #define COMP_EXPAND 3 ! #define COMP_EXPAND_COMPLETE 4 ! #define COMP_LIST_EXPAND 5 #define COMP_ISEXPAND(X) ((X) >= COMP_EXPAND) /**/ --- 215,228 ---- return 1; } ! enum { COMP_COMPLETE, ! COMP_LIST_COMPLETE, ! COMP_HIST_COMPLETE, ! COMP_SPELL, ! COMP_EXPAND, ! COMP_EXPAND_COMPLETE, ! COMP_LIST_EXPAND }; ! #define COMP_ISEXPAND(X) ((X) >= COMP_EXPAND) /**/ *************** *** 235,240 **** --- 237,260 ---- docomplete(COMP_COMPLETE); } + extern int lastcmd; + + /**/ + void + historycompleteword(void) + { + usemenu = isset(MENUCOMPLETE); + useglob = isset(GLOBCOMPLETE); + if ((lastcmd & (ZLE_MENUCMP|ZLE_HISTCOMP)) == ZLE_MENUCMP) { + /* if we just did a completion but it wasn't from the history, + * act as if that completion was finished. + */ + fixsuffix(); + invalidatelist(); + } + docomplete(COMP_HIST_COMPLETE); + } + /**/ void menucomplete(void) *************** *** 1764,1769 **** --- 1784,1790 ---- cc_dummy.mask = CC_PARAMS; ret = &cc_dummy; cc_dummy.refc = 10000; + cc_dummy.hpat = NULL; } else if (inwhat == IN_COND) { /* We try to be clever here: in conditions we complete option * * names after a `-o', file names after `-nt', `-ot', and `-ef' * *************** *** 1777,1782 **** --- 1798,1804 ---- (CC_FILES | CC_PARAMS); ret = &cc_dummy; cc_dummy.refc = 10000; + cc_dummy.hpat = NULL; } else if (incmd) ret = &cc_compos; /* And in redirections or if there is no command name (and we are * *************** *** 2171,2177 **** pushheap(); /* Make sure we have the completion list and compctl. */ ! if(makecomplist(s, incmd, &delit, &compadd, untokenized)) { /* Error condition: feeeeeeeeeeeeep(). */ feep(); goto compend; --- 2193,2199 ---- pushheap(); /* Make sure we have the completion list and compctl. */ ! if(makecomplist(s, incmd, &delit, &compadd, untokenized, lst)) { /* Error condition: feeeeeeeeeeeeep(). */ feep(); goto compend; *************** *** 2239,2245 **** /**/ static int ! makecomplist(char *s, int incmd, int *delit, int *compadd, int untokenized) { Compctl cc = NULL; int oloffs = offs, owe = we, owb = wb, ocs = cs, oll = ll, isf = 1; --- 2261,2268 ---- /**/ static int ! makecomplist(char *s, int incmd, int *delit, int *compadd, ! int untokenized, int lst) { Compctl cc = NULL; int oloffs = offs, owe = we, owb = wb, ocs = cs, oll = ll, isf = 1; *************** *** 2275,2280 **** --- 2298,2310 ---- matches = newlinklist(); fmatches = newlinklist(); + if (lst == COMP_HIST_COMPLETE) { + cc = ccmain = &cc_dummy; + cc->hpat = ""; + cc->refc = 10000; + cc->mask = 0; + } + /* If we don't have a compctl definition yet or we have a compctl * * with extended completion, get it (or the next one, resp.). */ if (!cc || cc->ext) *************** *** 2402,2407 **** --- 2432,2438 ---- cc = ccmain = &cc_dummy; cc_dummy.refc = 10000; cc_dummy.mask = CC_PARAMS | CC_ENVVARS; + cc_dummy.hpat = NULL; } } ooffs = offs; -- Peter Stephenson Tel: +39 50 911239 WWW: http://www.ifh.de/~pws/ Gruppo Teorico, Dipartimento di Fisica Piazza Torricelli 2, 56100 Pisa, Italy