zsh-workers
 help / color / mirror / code / Atom feed
* PATCH: 3.1.2-zefram3: history completion
@ 1998-01-16 10:52 pws
  1998-01-16 15:24 ` Andrej Borsenkow
  0 siblings, 1 reply; 5+ messages in thread
From: pws @ 1998-01-16 10:52 UTC (permalink / raw)
  To: Zsh hackers list

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 <pws@ibmth.difi.unipi.it>       Tel: +39 50 911239
WWW:  http://www.ifh.de/~pws/
Gruppo Teorico, Dipartimento di Fisica
Piazza Torricelli 2, 56100 Pisa, Italy


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: PATCH: 3.1.2-zefram3: history completion
  1998-01-16 10:52 PATCH: 3.1.2-zefram3: history completion pws
@ 1998-01-16 15:24 ` Andrej Borsenkow
  1998-01-16 16:02   ` Peter Stephenson
  0 siblings, 1 reply; 5+ messages in thread
From: Andrej Borsenkow @ 1998-01-16 15:24 UTC (permalink / raw)
  To: pws; +Cc: Zsh hackers list

I like the idea, but I totally disagree with implementation (sorry). It
continues the trend to add to base ZSH every feature someone finds to be
useful. I strongly believe, that base zsh must provide general enough
tools to do such sort of things in user space (or as separate module if
anybody will suffer from performance).

Speaking about completion - it should really be redefined to provide

  - completion pure

    It must deal with actual completion in the sense of building list of
    possible matches for a given line. There must exist interface on
    source level (for possible use in modules) and in user space
    (for use with user defined widgets).

  - anything else really belongs to ZLE. After I have list of matches,
    the way they are presented (menu, list or anything else) has 
    nothing to do with completion per se. It also would provide
    a nice way to do selection from user-defined lists (some thing
    I did miss - you cannot defined "context independent" completion.
    E.g. it doesn't make sense to define *all* command which use
    user name as argument - but if I had a way to say "select
    from user list" I could bind it and use with any command).

ZLE should probably provide general purpose widget(s) for selection from
given list (a la existing menu/list/beep completion). Assuming, that
zcomplete does completion returning possible matches and
zle-select-from-list provides user interface to select from matches array,
the whole story would look like

function history-complete-word () {
    set -A matches  $(zcomplete \
      -l $BUFFER           <= current line
      -c $CURSOR           <= current position
      -r '-s "$(fc -l 1 -1 | sed \"s/^[WS TAB]*[0-9]*[WS TAB]*//\")"' \
       ^^^^ actual completion rules (take words from history and select
            matching ones)
      )

    zle zle-select-from-list
        ^^^ takes over TAB if menu completion desired
}

zle -N history-complete-word history-complete-word

bindkey '\M-/' history-complete-word
          
(sed is needed only to strip history numbers).

I hope, the idea is not completely insane ...

-------------------------------------------------------------------------
Andrej Borsenkow 		Fax:   +7 (095) 252 01 05
SNI ITS Moscow			Tel:   +7 (095) 252 13 88

NERV:  borsenkow.msk		E-Mail: borsenkow.msk@sni.de
-------------------------------------------------------------------------







^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: PATCH: 3.1.2-zefram3: history completion
  1998-01-16 15:24 ` Andrej Borsenkow
@ 1998-01-16 16:02   ` Peter Stephenson
  1998-01-16 16:57     ` Bruce Stephens
  0 siblings, 1 reply; 5+ messages in thread
From: Peter Stephenson @ 1998-01-16 16:02 UTC (permalink / raw)
  To: Zsh hackers list

Andrej Borsenkow wrote:
> I like the idea, but I totally disagree with implementation (sorry). It
> continues the trend to add to base ZSH every feature someone finds to be
> useful. I strongly believe, that base zsh must provide general enough
> tools to do such sort of things in user space (or as separate module if
> anybody will suffer from performance).

I certainly agree in principle, but in practice I tend to find that
making the shell general enough to extend makes it much larger than
it was when it was handling lots of little things itself (even if the
changes allow modularality --- and remember we're talking about changes
to the zle module here), takes much longer, and makes the shell more
complex, and consequently less usable for the 99% of users who just want
to push a button to do what they want.  This is what I was referring to
when I suggested having a widget associated with a particular compctl (or,
equivalently, allowing a direct form of compctl in a zle function).  If it
happens (which means if Zefram has time to do it) it will require fiddling
through the manual before use, and consequently 99% of users will never
know it exists, some fraction of which would otherwise have used it.  Sad
but true.  Compare this with the dozen or two lines of functional code
in the patch I sent, available now, not next year, instantly usable,
not requiring a half hour with a manual, and doing the most commonly
requested form of ad hoc completion.  On balance, I'd prefer a more
general solution, too, but I've a strong feeling I may be wrong.

-- 
Peter Stephenson <pws@ifh.de>       Tel: +39 50 911239
WWW:  http://www.ifh.de/~pws/
Gruppo Teorico, Dipartimento di Fisica
Piazza Torricelli 2, 56100 Pisa, Italy


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: PATCH: 3.1.2-zefram3: history completion
  1998-01-16 16:02   ` Peter Stephenson
@ 1998-01-16 16:57     ` Bruce Stephens
  1998-01-16 17:26       ` Andrew Main
  0 siblings, 1 reply; 5+ messages in thread
From: Bruce Stephens @ 1998-01-16 16:57 UTC (permalink / raw)
  To: Zsh hackers list

pws@ifh.de said:
> This is what I was referring to when I suggested having a widget
> associated with a particular compctl (or, equivalently, allowing a
> direct form of compctl in a zle function).  If it happens (which means
> if Zefram has time to do it) it will require fiddling through the
> manual before use, and consequently 99% of users will never know it
> exists, some fraction of which would otherwise have used it.

Indeed.  There's a (minimal) danger that things split (like emacs/xemacs), 
with some people feeling that the base installation ought to be relatively 
small but very configurable, and others feeling that the default installation 
ought to present users with a more functionally rich product.

I think there's a bit of a danger with the minimalist view that zsh OOTB might 
look identical to ksh, in which case why would users bother to look further?  
On the other hand, there's a danger that zsh might be horribly slow as a 
scripting shell because of all the wacky features that are nice for 
interactive users, or where it's just about impossible to remove the default 
features that annoy you without removing everything.

Presumably there's some compromise where people can build/install zsh and get 
a nice shell with some useful completions, useful zle behaviour, and possibly 
even a useful prompt.  Maybe a graphical/menu driven configuration tool for 
newish users which helps to set up template .zsh* files.  (I think there 
already is such a tool somewhere or other; if it's any good maybe the zsh docs 
should point at it.)

A (probably graphical) tool which introduced all of the features of zsh, and 
automatically configured those chosen would be quite nice.  Every now and 
again I read through the docs, and notice some unexpected feature I didn't 
know about.  Imagine how daunting zsh must be to users used to csh, or 
COMMAND.COM.



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: PATCH: 3.1.2-zefram3: history completion
  1998-01-16 16:57     ` Bruce Stephens
@ 1998-01-16 17:26       ` Andrew Main
  0 siblings, 0 replies; 5+ messages in thread
From: Andrew Main @ 1998-01-16 17:26 UTC (permalink / raw)
  To: Bruce Stephens; +Cc: zsh-workers

Bruce Stephens wrote:
>Indeed.  There's a (minimal) danger that things split (like emacs/xemacs), 
>with some people feeling that the base installation ought to be relatively 
>small but very configurable, and others feeling that the default installation 
>ought to present users with a more functionally rich product.

There's nothing stopping us doing both -- have a small(ish), highly
configurable base, and have it OOTB be configured to be functionally rich.
We already do this to some extent, for example having several useful
options enabled by default.

>                       Maybe a graphical/menu driven configuration tool for 
>newish users which helps to set up template .zsh* files.

Putting more useful configuration into the startup files in the
distribution might help too.

-zefram


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~1998-01-16 17:36 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1998-01-16 10:52 PATCH: 3.1.2-zefram3: history completion pws
1998-01-16 15:24 ` Andrej Borsenkow
1998-01-16 16:02   ` Peter Stephenson
1998-01-16 16:57     ` Bruce Stephens
1998-01-16 17:26       ` Andrew Main

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).