zsh-workers
 help / color / mirror / code / Atom feed
* Re: Revised dohistexpand()
       [not found] <24456.199508101254@stone.dcs.warwick.ac.uk>
@ 1995-08-10 14:08 ` P.Stephenson
  0 siblings, 0 replies; 7+ messages in thread
From: P.Stephenson @ 1995-08-10 14:08 UTC (permalink / raw)
  To: Zsh hackers list

Thanks for the comments, but Zoltan's objections about magic space
with single quotes probably mean this patch won't get used.  (I
realise now there's another problem: I haven't arranged for !" to be
handled.  That's another thing that's hard without the lexer.)  Still,

A.Main@dcs.warwick.ac.uk wrote:
> Peter wrote:
> >Still, now I've found out what all this code does, maybe I can work
> >around it some other way.  I'm hoping, eventually, to modify the
> >history code so that only the lines actually typed are stored, with
> >the word separation in a list of numbers
> 
> I like this idea.  Much of the expansion/completion code could benefit
> from having the parser point out word beginnings to it.  This would be
> a great aid to consistency in complex quoting (e.g. "a b" "`a b`" "`'a
> b'`" etc.).  It would similarly help to have nesting indicated in this
> way, to help with command/process substitution.

I hadn't thought of that, but you're right, it might help simplify the
some other of the lexical horrors in zle_tricky.c.  I don't think I'm
going to be tackling that myself, but there's no point crossing that
bridge yet.

> I note that you confine history expansion to the current word.  This
> has the rather nice effect that typing "!!^V abc<magic-space>" won't
> expand the initial !!, which is helpful for those of us using
> magic-space.  However, it has some problems associated with it.  Does
> extended completion work after (in a separate word from) a history
> reference, bearing in mind that the history reference could expand to
> several words?

I believe this wouldn't a problem since the line that returns to the
completion code from the lexical already can have all manner of
changes to it (e.g. alias expansion, which is treated very much like
history expansion), but I haven't investigated in detail.

> On magic-space: it shouldn't expand history when the cursor is in a
> history reference (e.g. !{a<magic-space>).  At the moment
> doexpandhist() removes the word; it should feep and leave the word
> unchanged.  The same applies to expand-history, which also calls
> doexpandhist().  I also think an error should be flagged when
> attempting to expand an invalid history reference, rather than removing
> it (this would accurately reflect how zsh treats the bad history
> reference in a completed line).

This actually works in my patch (though I didn't get magicspace to
feep), since the error status from the history expansion is looked at.
(There's a problem with substitutions which actually comes from the
history code itself, since something like "!!:s/f" doesn't cause an
error, so if you magic-space after it it gets expanded straight away.
Changing the history code to flag an error on this kind of thing would
fix it.)

> Magic-space also ought to do no history expansion immediately after a
> backslash.  This is already fixed in the hzoli releases.

I didn't try that, but it could be added.

> Finally, I think this new patch reintroduces an old bug.  (I don't have
> hzoli10.2 to check it, but I'm fairly certain.)  Prior to the patch the
> code contains a statement that resets the vi beginning-of-insertion
> pointer to the beginning of the line when expanding history, because
> that's where expansion starts from.  After the patch, there is no such
> code.  The pointer ought to move back to the beginning of the word
> being expanded, as it is with other forms of expansion.

I don't use vi-mode, but I was careful in the patch to do all the line
changing with existing editor commands (backdel, spaceinline), so that
only the expanded code is changed.  This should mean that all this
kind of thing is automatically satisfied.  The current code just
copies the expanded line to the editor line, which is why it needs
extra code.  That's the kind of thing that made me take against the
current code (but don't take all my hyperbole too seriously).

-- 
Peter Stephenson <P.Stephenson@swansea.ac.uk>  Tel: +44 1792 205678 extn. 4461
WWW:  http://python.swan.ac.uk/~pypeters/      Fax: +44 1792 295324
Department of Physics, University of Wales, Swansea,
Singleton Park, Swansea, SA2 8PP, U.K.


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

* Re: Revised dohistexpand()
  1995-08-10 12:54     ` Zefram
@ 1995-08-10 20:19       ` Zoltan Hidvegi
  0 siblings, 0 replies; 7+ messages in thread
From: Zoltan Hidvegi @ 1995-08-10 20:19 UTC (permalink / raw)
  To: zsh-workers

> 
> Peter wrote:
> >Still, now I've found out what all this code does, maybe I can work
> >around it some other way.  I'm hoping, eventually, to modify the
> >history code so that only the lines actually typed are stored, with
> >the word separation in a list of numbers
> 
> I like this idea.  Much of the expansion/completion code could benefit
> from having the parser point out word beginnings to it.  This would be
> a great aid to consistency in complex quoting (e.g. "a b" "`a b`" "`'a
> b'`" etc.).  It would similarly help to have nesting indicated in this
> way, to help with command/process substitution.

Yes, this would be really nice.  I have already modified the lexer to supply
the start and end of backquote and $(...) and <(...) set. substitutions.
Together with that I completely rewore get_comp_string() in zle_tricky.c which
is much shorter, simpler now.  But it can be further improved I think.

> On magic-space: it shouldn't expand history when the cursor is in a
> history reference (e.g. !{a<magic-space>).  At the moment
> doexpandhist() removes the word; it should feep and leave the word
> unchanged.  The same applies to expand-history, which also calls

I think my release doesn't do this. It doesn feep, just silently inserts the
space. In fact even the old beta10 code tried to do that but it did not work
since it tested errflag after lexrestore().

> doexpandhist().  I also think an error should be flagged when
> attempting to expand an invalid history reference, rather than removing
> it (this would accurately reflect how zsh treats the bad history
> reference in a completed line).

The error is flagged but the reference (together with the trailing part of the
line) is removed.  But zle_tricky.c stores the old line so it can check the
error and restore the original line.

Zoltan


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

* Re: Revised dohistexpand()
  1995-08-09 17:11   ` P.Stephenson
@ 1995-08-10 12:54     ` Zefram
  1995-08-10 20:19       ` Zoltan Hidvegi
  0 siblings, 1 reply; 7+ messages in thread
From: Zefram @ 1995-08-10 12:54 UTC (permalink / raw)
  To: P.Stephenson

Peter wrote:
>Still, now I've found out what all this code does, maybe I can work
>around it some other way.  I'm hoping, eventually, to modify the
>history code so that only the lines actually typed are stored, with
>the word separation in a list of numbers

I like this idea.  Much of the expansion/completion code could benefit
from having the parser point out word beginnings to it.  This would be
a great aid to consistency in complex quoting (e.g. "a b" "`a b`" "`'a
b'`" etc.).  It would similarly help to have nesting indicated in this
way, to help with command/process substitution.

I note that you confine history expansion to the current word.  This
has the rather nice effect that typing "!!^V abc<magic-space>" won't
expand the initial !!, which is helpful for those of us using
magic-space.  However, it has some problems associated with it.  Does
extended completion work after (in a separate word from) a history
reference, bearing in mind that the history reference could expand to
several words?

On magic-space: it shouldn't expand history when the cursor is in a
history reference (e.g. !{a<magic-space>).  At the moment
doexpandhist() removes the word; it should feep and leave the word
unchanged.  The same applies to expand-history, which also calls
doexpandhist().  I also think an error should be flagged when
attempting to expand an invalid history reference, rather than removing
it (this would accurately reflect how zsh treats the bad history
reference in a completed line).

Magic-space also ought to do no history expansion immediately after a
backslash.  This is already fixed in the hzoli releases.

Finally, I think this new patch reintroduces an old bug.  (I don't have
hzoli10.2 to check it, but I'm fairly certain.)  Prior to the patch the
code contains a statement that resets the vi beginning-of-insertion
pointer to the beginning of the line when expanding history, because
that's where expansion starts from.  After the patch, there is no such
code.  The pointer ought to move back to the beginning of the word
being expanded, as it is with other forms of expansion.

-zefram


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

* Re: Revised dohistexpand()
  1995-08-09 15:21 ` Zoltan Hidvegi
@ 1995-08-09 17:11   ` P.Stephenson
  1995-08-10 12:54     ` Zefram
  0 siblings, 1 reply; 7+ messages in thread
From: P.Stephenson @ 1995-08-09 17:11 UTC (permalink / raw)
  To: Zsh hackers list

hzoli@cs.elte.hu wrote:
> To summarize my opinion, I do not like this patch very much.  It
> doesn't fixe s any bugs but it introduces one.  I normally bind
> magic-space to space so each time I hit space the whole line I typed
> so far goes through the lexer but the time spet there is unnoticable
> even on a slow 386/DX40 system (which I still use at home).

I'm not insistent on this patch, but anyway here's my response...

Your magic-space problems with single quotes are certainly real ---
you'd have to use \!, which does work properly in the patch (perhaps I
didn't make that clear enough) --- but if you really don't consider
expanding previous history references when trying to complete a
subsequent word a bug, our views differ substantially.  In fact, for
people not using magic-space (me, obviously --- I should guess most
people, since expansion is just a tab away, but I expect I'm about to
generate volumes of irate mail from magic-spacers) it's a lot more
important.  Unfortunately there's no easy way to reconcile the two ---
and if there is a way, I have a feeling I'd rather not see it.

Clearly people's priorities differ, but if I really have to put up
with increasing amounts of interpenetrating cruft when trying to clean
up the code, I have to say I'm rapidly going to lose interest.  To use
one call to the lexer in zle_tricky.c might be regarded as a
misfortune; to use two looks like carelessness (as Oscar Wilde put
it).

Still, now I've found out what all this code does, maybe I can work
around it some other way.  I'm hoping, eventually, to modify the
history code so that only the lines actually typed are stored, with
the word separation in a list of numbers (this uses less space since
there are not separate lexical and literal histories, while you get
all the benefits of both, and I hate HISTSPACE, and I'd like zsh to be
8-bit clean) --- maybe we can combine this so that the new history
line becomes the editing line after history expansion, so you can call
the lexer but don't need the addtoline() bits.  (It still won't fix
the expanding-in-the-wrong-word bug, though.)

-- 
Peter Stephenson <P.Stephenson@swansea.ac.uk>  Tel: +44 1792 205678 extn. 4461
WWW:  http://python.swan.ac.uk/~pypeters/      Fax: +44 1792 295324
Department of Physics, University of Wales, Swansea,
Singleton Park, Swansea, SA2 8PP, U.K.


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

* Re: Revised dohistexpand()
  1995-08-09 13:44 P.Stephenson
  1995-08-09 14:35 ` P.Stephenson
@ 1995-08-09 15:21 ` Zoltan Hidvegi
  1995-08-09 17:11   ` P.Stephenson
  1 sibling, 1 reply; 7+ messages in thread
From: Zoltan Hidvegi @ 1995-08-09 15:21 UTC (permalink / raw)
  To: zsh-workers

Peter Stephenson wrote:
> One of the bits I like least about the history code (and that's a bold
> statement) is the zle history expansion.  The problem is that it
> relies on calling the lexer, and via that the history code, and those
> together build up a new editing line directly.  This is one more
> reason why the history code is hard to maintain, and is also very
> wasteful:  neither the resulting tokens nor the resulting history line
> are used.

I think that these few additional line for building the expanded line do not
make the history code much more difficult to maintain.  I agree that it is a
bit tricky, but once you understand it it is quite obvious.  And after your
history rearrangement it become a bit simpler that it used to be.  Also I
wrote long comments about this staff in hist.c to make understanding easier.
If something is still unclear ask me and hopefully I can explain it.

> This revised version eliminates the lexer and uses hgetc() to get
> history expansion directly.  As most of the work is now done specially
> in doexpandhist(), it was possible to rewrite it so that only history
> expansions in the current word are expanded, which is now in keeping
> with other forms of expansion and completion.  This alone should make
> it all worthwhile.  For example,
>   % cmd !!:1 z<TAB>
> will now do completion on the second argument, as you would expect;
> formerly it would expand the previous history reference first.

This doesn't really a problem if you use magic-space.  !!:1 is already
expanded when you try to expand z.

> There are a couple of drawbacks: single quotes don't hide this form of
> expansion (though again that's just like glob expansion: try typing
> '*' and then tab), and complex substitutions like !:s/a b/c d/ will
> sometimes be mishandled (though usually you get what you deserve,
> particularly if you've just finished typing the whole expression).  I
> don't think either of these is at all significant.  I have also made
> sure that magic-space still works.

That's my main problem.  Magic space is unusable if it expands single quoted
history references.  E.g. you couldn't type 'Hello!' (followed by a space).
And without the lexer there is no way to get it right as there are so many
cases: '!$', "'!$'", "`'!$'`" etc.  The other thing you mention that '*' is
turned to * after TAB is an other bug and it does not justify the bogous
behaviour of single-quoted bangs.

Also before beta5 (or beta6) doexpandhist() did not call the lexer.  But
before beta4 (as I remember) single quotes did not quote history references
either.  doexpandhist() was changed by Sven exactly because single quotes
disabled history expansion.

> There is still some small collusion with the history code: when
> expanding, the history line is not modified and the pair \! is left as
> it is instead of being turned into !.  These are algorithmically

That is the way it should work.  \! should remain unchanged.  Otherwise if you
type \!$<magic-space> it would turn to !$ and after RETURN it would change to
the last word of the previous line.

> simple and self-contained, however.  It may also be possible to
> simplify the qbang logic in hist.c (it's now not needed at all when
> expanding), but I don't know enough about that (yet).

This qbang is not too important in the stock beta10 as I remember, but it is
important for my releases to fix a bug when >\!foo expanded history (or
something like that).

To summarize my opinion, I do not like this patch very much.  It doesn't fixes
any bugs but it introduces one.  I normally bind magic-space to space so each
time I hit space the whole line I typed so far goes through the lexer but the
time spet there is unnoticable even on a slow 386/DX40 system (which I still
use at home).

Zoltan


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

* Re: Revised dohistexpand()
  1995-08-09 13:44 P.Stephenson
@ 1995-08-09 14:35 ` P.Stephenson
  1995-08-09 15:21 ` Zoltan Hidvegi
  1 sibling, 0 replies; 7+ messages in thread
From: P.Stephenson @ 1995-08-09 14:35 UTC (permalink / raw)
  To: Zsh hackers list

Minor addition to that patch:  I just discovered there's a function
which does three of my lines.  This doesn't make any difference to
anything.

*** Src/zle_tricky.c.he2	Wed Aug  9 15:32:23 1995
--- Src/zle_tricky.c	Wed Aug  9 15:30:19 1995
***************
*** 3777,3788 ****
  	if (test) {
  	    /* The right bit changed:  set cursor to end of it, */
  	    cs = endptr - (char *)line;
! 	    /* delete it, */
  	    backdel(endptr - startptr);
  	    /* and insert the new stuff. */
! 	    spaceinline(newcount);
! 	    memcpy(line+cs, newline, newcount);
! 	    cs += newcount;
  
  	    ret = 1;
  	}
--- 3777,3786 ----
  	if (test) {
  	    /* The right bit changed:  set cursor to end of it, */
  	    cs = endptr - (char *)line;
! 	    /* delete old stuff, */
  	    backdel(endptr - startptr);
  	    /* and insert the new stuff. */
! 	    inststrlen(newline, 1, newcount);
  
  	    ret = 1;
  	}

-- 
Peter Stephenson <P.Stephenson@swansea.ac.uk>  Tel: +44 1792 205678 extn. 4461
WWW:  http://python.swan.ac.uk/~pypeters/      Fax: +44 1792 295324
Department of Physics, University of Wales, Swansea,
Singleton Park, Swansea, SA2 8PP, U.K.


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

* Revised dohistexpand()
@ 1995-08-09 13:44 P.Stephenson
  1995-08-09 14:35 ` P.Stephenson
  1995-08-09 15:21 ` Zoltan Hidvegi
  0 siblings, 2 replies; 7+ messages in thread
From: P.Stephenson @ 1995-08-09 13:44 UTC (permalink / raw)
  To: Zsh hackers list

Here's another step on the way to rationalising the history code.
It's for hzoli10.2, simply because that's the latest generally
available version:  there have been so many patches that I don't dare
to patch the official version at the moment.  I'll revise this when
2.6-beta11 comes out.

One of the bits I like least about the history code (and that's a bold
statement) is the zle history expansion.  The problem is that it
relies on calling the lexer, and via that the history code, and those
together build up a new editing line directly.  This is one more
reason why the history code is hard to maintain, and is also very
wasteful:  neither the resulting tokens nor the resulting history line
are used.

This revised version eliminates the lexer and uses hgetc() to get
history expansion directly.  As most of the work is now done specially
in doexpandhist(), it was possible to rewrite it so that only history
expansions in the current word are expanded, which is now in keeping
with other forms of expansion and completion.  This alone should make
it all worthwhile.  For example,
  % cmd !!:1 z<TAB>
will now do completion on the second argument, as you would expect;
formerly it would expand the previous history reference first.

There are a couple of drawbacks: single quotes don't hide this form of
expansion (though again that's just like glob expansion: try typing
'*' and then tab), and complex substitutions like !:s/a b/c d/ will
sometimes be mishandled (though usually you get what you deserve,
particularly if you've just finished typing the whole expression).  I
don't think either of these is at all significant.  I have also made
sure that magic-space still works.

There is still some small collusion with the history code: when
expanding, the history line is not modified and the pair \! is left as
it is instead of being turned into !.  These are algorithmically
simple and self-contained, however.  It may also be possible to
simplify the qbang logic in hist.c (it's now not needed at all when
expanding), but I don't know enough about that (yet).

*** Src/globals.h.he	Mon Jul 24 18:08:29 1995
--- Src/globals.h	Tue Aug  8 23:10:45 1995
***************
*** 124,133 ****
  
  EXTERN int expanding;
  
- /* these are used to modify the cursor position during expansion */
- 
- EXTERN int excs, exlast;
- 
  /* if != 0, this is the first line of the command */
   
  EXTERN int isfirstln;
--- 124,129 ----
*** Src/hist.c.he	Wed Jul 19 18:00:26 1995
--- Src/hist.c	Wed Aug  9 12:31:40 1995
***************
*** 66,98 ****
      }
  }
  
- /* This function adds a character to the zle input line. It is used when *
-  * zsh expands history (see doexpandhist() in zle_tricky.c). It also     *
-  * calculates the new cursor position after the expansion. It is called  *
-  * from hgetc() and from gettok() in lex.c for characters in comments.   */
-  
  /**/
- void
- addtoline(int c)
- {
-     if (qbang && c == bangchar && stophist < 2) {
- 	exlast--;
- 	spaceinline(1);
- 	line[cs++] = '\\';
-     }
-     if (excs > cs) {
- 	excs += 1 + inbufct - exlast;
- 	if (excs < cs)
- 	    /* this case could be handled better but it is    *
- 	     * so rare that it does not worth it              */
- 	    excs = cs;
-     }
-     exlast = inbufct;
-     spaceinline(1);
-     line[cs++] = itok(c) ? ztokens[c - Pound] : c;
- }
- 
- /**/
  int
  hgetc(void)
  {
--- 66,72 ----
***************
*** 101,106 ****
--- 75,88 ----
      qbang = 0;
      if (!stophist && !alstackind) {
  	/* If necessary, expand history characters. */
+ 	if (expanding == 2) {
+ 	    /* If only expanding history, leave \! pairs alone.
+ 	     * We marked a \! pair and returned the \, but the ! should
+ 	     * still be treated as quoted.
+ 	     */
+ 	    expanding = 1;
+ 	    return c;
+ 	}
  	c = histsubchar(c);
  	if (c < 0) {
  	    errflag = lexstop = 1;
***************
*** 126,136 ****
  	 * history is disabled with NOBANGHIST or by someone else (e.g.  *
  	 * when the lexer scans single quoted text).                     */
  	qbang = c == bangchar && (stophist < 2);
!     hwaddc(c);
  
-     if (expanding && !lexstop)
- 	addtoline(c);
- 
      return c;
  }
  
--- 108,116 ----
  	 * history is disabled with NOBANGHIST or by someone else (e.g.  *
  	 * when the lexer scans single quoted text).                     */
  	qbang = c == bangchar && (stophist < 2);
!     if (!expanding)
! 	hwaddc(c);
  
      return c;
  }
  
***************
*** 203,208 ****
--- 183,193 ----
  	    if (g != bangchar)
  		safeinungetc(g);
  	    else {
+ 		if (expanding == 1) {
+ 		    expanding = 2; /* flag to return literal ! next */
+ 		    inungetc(g);
+ 		    return '\\';
+ 		}
  		qbang = 1;
  		return bangchar;
  	    }
***************
*** 490,500 ****
  	return;
  
    escape:
-     if (expanding) {
- 	cs--;
- 	ll--;
- 	exlast++;
-     }
      if (hlastw) {
  	if (hlastw == hptr)
  	    zerr("hungetc attempted at buffer start", NULL, 0);
--- 475,480 ----
*** Src/lex.c.he	Tue Aug  1 10:12:24 1995
--- Src/lex.c	Tue Aug  8 17:34:02 1995
***************
*** 374,380 ****
  
      if (c == hashchar &&
  	(isset(INTERACTIVECOMMENTS) ||
! 	 (!zleparse && !expanding && (!interact || unset(SHINSTDIN) || strin)))) {
      /* History is handled here to prevent extra newlines
  		 * being inserted into the history.
  		 *
--- 374,380 ----
  
      if (c == hashchar &&
  	(isset(INTERACTIVECOMMENTS) ||
! 	 (!zleparse && (!interact || unset(SHINSTDIN) || strin)))) {
      /* History is handled here to prevent extra newlines
  		 * being inserted into the history.
  		 *
***************
*** 394,406 ****
  	    else {
  		while (nsp) {
  		    hwaddc(' ');
- 		    if (expanding)
- 			addtoline(' ');
  		    --nsp;
  		}
  		hwaddc(c);
- 		if (expanding)
- 		    addtoline(c);
  	    }
  	}
  	if (errflag)
--- 394,402 ----
***************
*** 409,420 ****
  	    hwadd();
  	    hwbegin();
  	    hwaddc('\n');
- 	    if (expanding) {
- 		while (nsp--)
- 		    addtoline(' ');
- 		if (!lexstop)
- 		    addtoline('\n');
- 	    }
  	    peek = NEWLIN;
  	}
  	return peek;
--- 405,410 ----
*** Src/zle_tricky.c.he	Mon Jul 24 18:14:04 1995
--- Src/zle_tricky.c	Wed Aug  9 12:38:48 1995
***************
*** 3691,3758 ****
  int
  doexpandhist(void)
  {
!     unsigned char *ol;
!     int oll = ll, ocs = cs, ne = noerrs, err;
  
!     heapalloc();
!     pushheap();
!     ol = (unsigned char *)dupstring((char *)line);
!     expanding = 1;
!     excs = cs;
!     ll = cs = 0;
!     lexsave();
!     inpush(UTOSCP(ol), 0);  /* We push ol as it will remain unchanged */
!     strinbeg();
!     noaliases = 1;
      noerrs = 1;
!     exlast = inbufct;
!     do {
! 	ctxtlex();
      }
!     while (tok != ENDINPUT && tok != LEXERR);
!     stophist = 2;
!     while (!lexstop)
! 	hgetc();
!     /* We have to save errflags because it's reset in lexrestore. Since
!      * noerrs was set to 1 errflag is true if there was a habort() which
!      * means that the expanded string is unusable */
!     err = errflag;
!     noerrs = ne;
!     noaliases = 0;
!     strinend();
!     inpop();
!     zleparse = 0;
!     lexrestore();
!     expanding = 0;
!     popheap();
!     permalloc();
  
!     if (!err) {
! 	cs = excs;
! 	if (strcmp((char *)line, (char *)ol)) {
! 	    /* For vi mode -- reset the beginning-of-insertion pointer to the
! 	     * beginning of the line.  This seems a little silly, if we are,
! 	     * for example, expanding "exec !!". */
! 	    if (viinsbegin > findbol())
! 		viinsbegin = findbol();
! 	    return 1;
  	}
      }
  
!     strcpy((char *)line, (char *)ol);
!     ll = oll;
!     cs = ocs;
  
!     return 0;
  }
  
  /**/
  void
  magicspace(void)
  {
      c = ' ';
      selfinsert();
-     doexpandhist();
  }
  
  /**/
--- 3691,3815 ----
  int
  doexpandhist(void)
  {
!     int newsz = linesz, newchar, newcount;
!     int ls = lexstop, sh = stophist, ifc = isfirstch, ne = noerrs;
!     int hd = histdone, ret = 0, test, offs, foundbang;
!     char *newline, *newptr, *startptr, *endptr, *spaceptr, sav;
  
!     if (isset(NOBANGHIST))
! 	return 0;
! 
!     endptr = startptr = (char *)line + cs;
! 
!     foundbang = 0;
!     while (*endptr && *endptr != ' ') {
! 	if (*endptr == bangchar)
! 	    foundbang = 1;
! 	endptr++;
!     }
! 
!     spaceptr = NULL;
!     if (!foundbang) {
! 	/* We still need to go back far enough to find a bang.
! 	 * This is to handle stuff like !!:s/a b/c d/, though you
! 	 * still have to be after the last space for it to work.
! 	 * Spaceptr will point to the first character after the space
! 	 * before the cursor.  We require that something between
! 	 * here and endptr has changed to accept the expansion.
! 	 */
! 	while (startptr > (char *)line && *startptr != bangchar) {
! 	    startptr--;
! 	    if (*startptr == ' ' && !spaceptr)
! 		spaceptr = startptr;
! 	}
! 	if (*startptr != '^' && *startptr != bangchar)
! 	    return 0;
!     }
! 
!     if (startptr == endptr) {
! 	/* If no characters here, don't try expansion */
! 	return 0;
!     }
! 
!     /* Either we found a bangchar, or a ^ at the beginning of the line. */
! 
!     /* Make sure we get complete word. */
!     while (startptr > (char *)line && startptr[-1] != ' ')
! 	startptr--;
!     sav = *endptr;
!     *endptr = '\0';
! 
!     newptr = newline = malloc(newsz);
! 
!     inpush(startptr, 0);
!     lexstop = 0;
!     strin = 1;
!     stophist = 0;
!     isfirstch = (startptr == (char *)line);
      noerrs = 1;
!     expanding = 1;
!     /* What about the alias stack? */
! 
!     for (newcount = 0;; newcount++) {
! 	if (newcount == newsz) {
! 	    newline = (char *)realloc(newline, (newsz *= 4));
! 	    newptr = newline + newcount;
! 	}
! 	newchar = hgetc();
! 	if (errflag || lexstop)
! 	    break;
! 
! 	*newptr++ = newchar;
      }
!     *newptr = '\0';
!     *endptr = sav;
! 
!     if (!errflag) {
! 	/* We've now expanded from startptr to newptr; see if it's
! 	 * changed.  If we set spaceptr, we want to make sure the
! 	 * text after that was changed, else the expansion wasn't in
! 	 * the current word and we reject it.
! 	 */
! 	if (spaceptr && (offs = newcount - (endptr - spaceptr)) > 0) {
! 	    test = strcmp(spaceptr, newline + offs);
! 	} else
! 	    test = strcmp(startptr, newline);
! 	if (test) {
! 	    /* The right bit changed:  set cursor to end of it, */
! 	    cs = endptr - (char *)line;
! 	    /* delete it, */
! 	    backdel(endptr - startptr);
! 	    /* and insert the new stuff. */
! 	    spaceinline(newcount);
! 	    memcpy(line+cs, newline, newcount);
! 	    cs += newcount;
  
! 	    ret = 1;
  	}
      }
+     zfree(newline, newsz);
  
!     expanding = 0;
!     noerrs = ne;
!     isfirstch = ifc;
!     stophist = sh;
!     strin = 0;
!     lexstop = ls;
!     histdone = hd;
!     inpop();
  
!     errflag = 0;
! 
!     return ret;
  }
  
  /**/
  void
  magicspace(void)
  {
+     doexpandhist();
      c = ' ';
      selfinsert();
  }
  
  /**/

-- 
Peter Stephenson <P.Stephenson@swansea.ac.uk>  Tel: +44 1792 205678 extn. 4461
WWW:  http://python.swan.ac.uk/~pypeters/      Fax: +44 1792 295324
Department of Physics, University of Wales, Swansea,
Singleton Park, Swansea, SA2 8PP, U.K.


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

end of thread, other threads:[~1995-08-10 20:28 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <24456.199508101254@stone.dcs.warwick.ac.uk>
1995-08-10 14:08 ` Revised dohistexpand() P.Stephenson
1995-08-09 13:44 P.Stephenson
1995-08-09 14:35 ` P.Stephenson
1995-08-09 15:21 ` Zoltan Hidvegi
1995-08-09 17:11   ` P.Stephenson
1995-08-10 12:54     ` Zefram
1995-08-10 20:19       ` Zoltan Hidvegi

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).