Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: PATCH: expand-or-complete-prefix



On Feb 20,  3:00pm, Peter Stephenson wrote:
} Subject: PATCH: expand-or-complete-prefix
}
} I've rewritten it as part of the standard repertoire of hacks.
} 
} (There are some useless hunks because somehow some whitespace got
} trimmed.  It seemed silly to put it back in specially.)

Here's the patch against 3.0.5, with some whitespace differences cleaned
up -- I had to hand-apply Peter's patch, hopefully this one doesn't have
that problem.

Index: Src/zle_tricky.c
===================================================================
*** zle_tricky.c	1997/11/19 16:40:31	1.6
--- zle_tricky.c	1998/02/20 17:07:25
***************
*** 166,172 ****
  static int ab, ae, fab, fae;
  
  /* This variable says what we are currently adding to the list of matches. */
!    
  static int addwhat;
  
  /* firstm hold the first match we found, shortest contains the shortest *
--- 166,172 ----
  static int ab, ae, fab, fae;
  
  /* This variable says what we are currently adding to the list of matches. */
! 
  static int addwhat;
  
  /* firstm hold the first match we found, shortest contains the shortest *
***************
*** 189,199 ****
  
  static int amenu;
  
- /* This is used by expandorcompleteprefix to save the position of the *
-  * inserted space (so that we can remove it later).                   */
- 
- static int remove_at = -1;
- 
  /* Find out if we have to insert a tab (instead of trying to complete). */
  
  /**/
--- 189,194 ----
***************
*** 505,511 ****
  	do_menucmp(lst);
  	return;
      }
!     
      /* Check if we have to start a menu-completion (via automenu). */
  
      if ((amenu = (isset(AUTOMENU) &&
--- 500,506 ----
  	do_menucmp(lst);
  	return;
      }
! 
      /* Check if we have to start a menu-completion (via automenu). */
  
      if ((amenu = (isset(AUTOMENU) &&
***************
*** 765,770 ****
--- 760,768 ----
  /* 1 if we are completing in a string */
  int instring;
  
+ /* 1 if we are completing the prefix */
+ static int comppref;
+ 
  /* This function inserts an `x' in the command line at the cursor position. *
   *                                                                          *
   * Oh, you want to know why?  Well, if completion is tried somewhere on an  *
***************
*** 774,795 ****
   * command we are completing and such things).  So we temporarily add a `x' *
   * (any character without special meaning would do the job) at the cursor   *
   * position, than the lexer gives us the word `x' and its beginning and end *
!  * positions and we can remove the `x'.                                     */
  
  /**/
  void
  addx(char **ptmp)
  {
      if (!line[cs] || line[cs] == '\n' ||
  	(iblank(line[cs]) && (!cs || line[cs-1] != '\\')) ||
  	line[cs] == ')' || line[cs] == '`' ||
! 	(instring && (line[cs] == '"' || line[cs] == '\''))) {
  	*ptmp = (char *)line;
! 	line = (unsigned char *)halloc(strlen((char *)line) + 3);
  	memcpy(line, *ptmp, cs);
  	line[cs] = 'x';
! 	strcpy((char *)line + cs + 1, (*ptmp) + cs);
! 	addedx = 1;
      } else {
  	addedx = 0;
  	*ptmp = NULL;
--- 772,805 ----
   * command we are completing and such things).  So we temporarily add a `x' *
   * (any character without special meaning would do the job) at the cursor   *
   * position, than the lexer gives us the word `x' and its beginning and end *
!  * positions and we can remove the `x'.                                     *
!  *									    *
!  * If we are just completing the prefix (comppref set), we also insert a    *
!  * space after the x to end the word.  We never need to remove the space:   *
!  * anywhere we are able to retrieve a word for completion it will be	    *
!  * discarded as whitespace.  It has the effect of making any suffix	    *
!  * referrable to as the next word on the command line when indexing	    *
!  * from a completion function.                                              */
  
  /**/
  void
  addx(char **ptmp)
  {
+     int addspace = 0;
+ 
      if (!line[cs] || line[cs] == '\n' ||
  	(iblank(line[cs]) && (!cs || line[cs-1] != '\\')) ||
  	line[cs] == ')' || line[cs] == '`' ||
! 	(instring && (line[cs] == '"' || line[cs] == '\'')) ||
! 	(addspace = (comppref && !iblank(line[cs])))) {
  	*ptmp = (char *)line;
! 	line = (unsigned char *)halloc(strlen((char *)line) + 3 + addspace);
  	memcpy(line, *ptmp, cs);
  	line[cs] = 'x';
! 	if (addspace)
! 	    line[cs+1] = ' ';
! 	strcpy((char *)line + cs + 1 + addspace, (*ptmp) + cs);
! 	addedx = 1 + addspace;
      } else {
  	addedx = 0;
  	*ptmp = NULL;
***************
*** 953,959 ****
  		tt = tokstr ? dupstring(tokstr) : NULL;
  		/* If we added a `x', remove it. */
  		if (addedx && tt)
! 		    chuck(tt + cs - wb - 1);
  		tt0 = tok;
  		/* Store the number of this word. */
  		clwpos = i;
--- 963,969 ----
  		tt = tokstr ? dupstring(tokstr) : NULL;
  		/* If we added a `x', remove it. */
  		if (addedx && tt)
! 		    chuck(tt + cs - wb);
  		tt0 = tok;
  		/* Store the number of this word. */
  		clwpos = i;
***************
*** 987,994 ****
  	    /* If this is the word the cursor is in and we added a `x', *
  	     * remove it.                                               */
  	    if (clwpos == i++ && addedx)
! 		chuck(&clwords[i - 1][((cs - wb - 1) >= sl) ?
! 				     (sl - 1) : (cs - wb - 1)]);
  	} while (tok != LEXERR && tok != ENDINPUT &&
  		 (tok != SEPER || (zleparse && !tt0)));
  	/* Calculate the number of words stored in the clwords array. */
--- 997,1004 ----
  	    /* If this is the word the cursor is in and we added a `x', *
  	     * remove it.                                               */
  	    if (clwpos == i++ && addedx)
! 		chuck(&clwords[i - 1][((cs - wb) >= sl) ?
! 				     (sl - 1) : (cs - wb)]);
  	} while (tok != LEXERR && tok != ENDINPUT &&
  		 (tok != SEPER || (zleparse && !tt0)));
  	/* Calculate the number of words stored in the clwords array. */
***************
*** 1001,1008 ****
  	strinend();
  	inpop();
  	errflag = zleparse = 0;
- 	if (addedx)
- 	    wb++;
  	if (parbegin != -1) {
  	    /* We are in command or process substitution */
  	    if (parend >= 0 && !tmp)
--- 1011,1016 ----
***************
*** 1211,1219 ****
  void
  gotword(void)
  {
!     we = ll + 1 - inbufct;
      if (cs <= we) {
! 	wb = ll - wordbeg;
  	zleparse = 0;
      }
  }
--- 1219,1227 ----
  void
  gotword(void)
  {
!     we = ll + 1 - inbufct + (addedx == 2 ? 1 : 0);
      if (cs <= we) {
! 	wb = ll - wordbeg + addedx;
  	zleparse = 0;
      }
  }
***************
*** 1232,1239 ****
  	len = strlen(str);
      spaceinline(len);
      strncpy((char *)(line + cs), str, len);
-     if (remove_at >= cs)
-         remove_at += len;
      if (move)
  	cs += len;
  }
--- 1240,1245 ----
***************
*** 3503,3519 ****
      nboff = ispattern && psuf && *psuf &&
  	!(haswhat & (HAS_MISC | HAS_PATHPAT)) ? niceztrlen(psuf) : 0;
  
-     /* When called from expandorcompleteprefix, we probably have to
-        remove a space now. */
-     if (remove_at >= 0) {
- 	int ocs = cs;
- 
- 	cs = remove_at;
- 	deletechar();
- 	remove_at = -1;
- 	cs = ocs;
-     }
- 
      /* Set the cursor below the prompt. */
      trashzle();
      ct = nmatches;
--- 3509,3514 ----
***************
*** 3946,3971 ****
  void
  expandorcompleteprefix(void)
  {
!     /* global c is the current character typed. */
!     int csafe = c;
! 
!     /* insert a space and backspace. */
!     c = ' ';
!     selfinsert();		/* insert the extra character */
!     forwardchar();		/* move towards beginning */
!     
!     remove_at = cs;
! 
!     /* do the expansion/completion. */
!     c = csafe;
!     zmult = 1;
!     expandorcomplete();		/* complete. */
!     zmult = -1;
! 
!     /* remove the inserted space. */
!     if (remove_at >= 0) {
! 	backwardchar();		/* move towards ends */
! 	deletechar();		/* delete the added space. */
!     }
!     remove_at = -1;
  }
--- 3941,3947 ----
  void
  expandorcompleteprefix(void)
  {
!     comppref = 1;
!     expandorcomplete();
!     comppref = 0;
  }

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com



Messages sorted by: Reverse Date, Date, Thread, Author