Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 10 Feb 1999 00:33:24 GMT
From:      marko@uk.radan.com
To:        FreeBSD-gnats-submit@FreeBSD.ORG
Subject:   bin/9990: Enhancement to filename completeion in csh(1)
Message-ID:  <199902100033.AAA01188@marder-1.>

next in thread | raw e-mail | index | archive | help

>Number:         9990
>Category:       bin
>Synopsis:       Enhancement to filename completeion in csh(1)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Tue Feb  9 16:40:00 PST 1999
>Closed-Date:
>Last-Modified:
>Originator:     Mark Ovens
>Release:        FreeBSD 2.2.8-RELEASE i386
>Organization:
>Environment:

	FreeBSD marder-1 2.2.8-RELEASE FreeBSD 2.2.8-RELEASE #0:
	Sun Jan  3 20:07:20 GMT 1999
	root@marder-1:/usr/src/sys/compile/MARDER-1_PnP_SCSI  i386


>Description:

	Filename completion in csh(1) isn't fully functional if
	filenames contain spaces. Not really a problem on Unix
	boxes, but as many FreeBSD users also have Windows installed
	on their PCs it can be a pain.

>How-To-Repeat:

	Running csh, ensure filename completion is enabled (``set
	filec'') and there are some paths with directory names
	containing spaces. Then try to ``cd'' to a directory below
	a directory with space(s) in its name using completion. It
	will complete the first name containing spaces but won't
	work on subsequent ones in the same command, even using
	quotes or escaping the spaces with ``\''.


>Fix:
	
	Apply the following patches and remake csh. The modification
	causes the shell to escape spaces with ``\'' when expanding,
	and also correctly interprets escaped spaces in the existing
	path on the command line, whether typed by the user or
	added by expansion.


----- start included file. file.c.diff-------------------------

*** file.c.orig	Sat Feb  6 15:52:31 1999
--- file.c	Sat Feb  6 17:03:41 1999
***************
*** 100,105 ****
--- 100,107 ----
  static int	 is_prefix __P((Char *, Char *));
  static int	 is_suffix __P((Char *, Char *));
  static int	 ignored __P((Char *));
+ static void	 add_bkslsh __P((Char *));
+ static void	 rm_bkslsh __P((Char *));
  
  /*
   * Put this here so the binary can be patched with adb to enable file
***************
*** 161,166 ****
--- 163,169 ----
      Char   *string;
  {
      Char *p;
+     Char temp[BUFSIZ];
      struct termios tty, tty_normal;
      int     omask;
      char    c;
***************
*** 442,447 ****
--- 445,451 ----
      Char    tilded_dir[MAXPATHLEN + 1], dir[MAXPATHLEN + 1];
      Char    name[MAXNAMLEN + 1], extended_name[MAXNAMLEN + 1];
      Char   *entry;
+     Char    temp[BUFSIZ];
  
  #define MAXITEMS 1024
  
***************
*** 518,523 ****
--- 522,531 ----
  	    copyn(word, dir, max_word_length);
  	/* add extended name */
  	catn(word, extended_name, max_word_length);
+ 
+ 	add_bkslsh(word);		/* Escape any spaces with ``\''	*/
+ 					/* before retyping command line	*/
+ 	
  	return (numitems);
      }
      else {			/* LIST */
***************
*** 635,643 ****
  	 * is one Character past it.
  	 */
  	for (word_start = str_end; word_start > inputline; --word_start)
! 	    if (Strchr(delims, word_start[-1]))
! 		break;
  	space_left = inputline_size - (word_start - inputline) - 1;
  	numitems = tsearch(word_start, command, space_left);
  
  	if (command == RECOGNIZE) {
--- 643,668 ----
  	 * is one Character past it.
  	 */
  	for (word_start = str_end; word_start > inputline; --word_start)
! 	    {
! 					/* Check if any spaces found	*/
! 					/* are preceded by ``\''. If so	*/
! 					/* assume the space is part of	*/
! 					/* the dir/file name and not a	*/
! 					/* word separator.		*/
! 	    if (word_start[-1] == ' ')
! 		{
! 		if (word_start[-2] != '\\')	/* Must be start of word */
! 			break;
! 		}
! 	    else
! 		if (Strchr(delims, word_start[-1]))
!                     break;
! 	    }
! 
  	space_left = inputline_size - (word_start - inputline) - 1;
+ 
+ 	rm_bkslsh(word_start);		/* Strip any \'s from pathname	*/
+ 
  	numitems = tsearch(word_start, command, space_left);
  
  	if (command == RECOGNIZE) {
***************
*** 658,664 ****
--- 683,693 ----
  	    should_retype = TRUE;
  	}
  	if (command == LIST)	/* Always retype after a LIST */
+ 	    {
+             add_bkslsh(word_start);	/* Escape any spaces with ``\''	*/
+ 					/* before retyping command line	*/
  	    should_retype = TRUE;
+             }
  	if (should_retype)
  	    printprompt();
  	pushback(inputline);
***************
*** 684,686 ****
--- 713,770 ----
      return (FALSE);
  }
  #endif				/* FILEC */
+ 
+ /*
+ * Adds ``\'' in front of any spaces to escape them. Allows filename
+ * completion to work with file/dir names containing spaces.
+ */
+ 
+ static void add_bkslsh(Char *word)
+ 	{
+ 	int i = 0, j = 0;
+ 	Char temp[BUFSIZ];
+ 
+ 	if (Strchr(word, ' '))
+ 		{
+ 		Strcpy(temp, word);
+ 
+ 		while (temp[i] != '\0')
+ 			{
+ 			if (temp[i] != ' ')
+ 				word[j++] = temp[i++];
+ 			else
+ 				{
+ 				word[j++] = '\\';
+ 				word[j++] = temp[i++];
+ 				}
+ 			}
+ 
+ 		word[j] = '\0';
+ 		}
+ 	}
+ 
+ /*
+ * Removes any ``\'' from in front of spaces. Allows filename completion
+ * to work with file/dir names containing spaces.
+ */
+ 
+ static void rm_bkslsh(Char *word)
+ 	{
+ 	int i = 0, j = 0;
+ 	Char temp[BUFSIZ];
+ 
+ 	if (Strchr(word, '\\'))
+ 		{
+ 		Strcpy(temp, word);
+ 
+ 		while (temp[i] != '\0')
+ 			{
+ 			if (temp[i] != '\\')
+ 				word[j++] = temp[i++];
+ 			else
+ 				i++;
+ 			}
+ 
+ 		word[j] = '\0';
+ 		}
+ 	}


----- end included file. file.c.diff-------------------------

----- start included file. csh.1.diff-------------------------

--- csh.1.orig	Sat Feb  6 16:05:37 1999
+++ csh.1	Sat Feb  6 16:21:54 1999
@@ -389,6 +389,18 @@
 and will sound the terminal bell to indicate that the expansion is
 incomplete, since there are two file names matching the prefix ``D''.
 .Pp
+If the matching filename contains a space
+.Nm
+will escape the space with a backslash. For example, in the directory
+listing above, if ``bench'' was ``bench mark'' instead then
+.Pp
+.Dl % vi be<escape>
+.Pp
+.Nm
+would expand the input to
+.Pp
+.Dl % vi bench\e mark
+.Pp
 If a partial file name is followed by the end-of-file character
 (usually control-D), then, instead of completing the name,
 .Nm
@@ -402,6 +414,9 @@
 .Dl DSC.NEW	DSC.OLD
 .Pp
 while the input line remains unchanged.
+.Pp
+Note, that in the case of filenames containing spaces, the list
+will not show the spaces escaped with a backslash.
 .Pp
 The same system of escape and end-of-file can also be used to
 expand partial user names, if the word to be completed

----- end included file. csh.1.diff-------------------------

>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199902100033.AAA01188>