zsh-workers
 help / color / mirror / code / Atom feed
* On the quoting of braces
@ 2011-12-06 22:16 Christian Neukirchen
  2011-12-07 20:31 ` Peter Stephenson
  0 siblings, 1 reply; 8+ messages in thread
From: Christian Neukirchen @ 2011-12-06 22:16 UTC (permalink / raw)
  To: zsh-workers

Hi,

comparing different shells, I noticed zsh is overly careful for unquoted
braces:

ksh93$ echo {}
{}
ksh93$ echo {foo}
{foo}
ksh93$ echo {foo,bar}
foo bar
ksh93$ echo { foo,bar }
{ foo,bar }

bash4$ echo {}
{}
bash4$ echo {foo}
{foo}
bash4$ echo {foo,bar}
foo bar
bash4$ echo { foo,bar }
{ foo,bar }

zsh% echo {}
{}
zsh% echo {foo}
{foo}
zsh% echo {foo,bar}
foo bar
zsh% echo { foo,bar }
zsh: parse error near `}'

Why does this error appear?  The only way to disable it seems to be
IGNORE_BRACES, which completely disables (the much used) brace expansion.
("disable -r '}'" would break "{ cmd; cmd2 }")

Thanks,
-- 
Christian Neukirchen  <chneukirchen@gmail.com>  http://chneukirchen.org


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

* Re: On the quoting of braces
  2011-12-06 22:16 On the quoting of braces Christian Neukirchen
@ 2011-12-07 20:31 ` Peter Stephenson
  2011-12-07 20:43   ` Mikael Magnusson
                     ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Peter Stephenson @ 2011-12-07 20:31 UTC (permalink / raw)
  To: zsh-workers

On Tue, 06 Dec 2011 23:16:35 +0100
Christian Neukirchen <chneukirchen@gmail.com> wrote:
> comparing different shells, I noticed zsh is overly careful for unquoted
> braces:
> zsh% echo { foo,bar }
> zsh: parse error near `}'
> 
> Why does this error appear?

zsh allows a "}" to appear other than in command position at the end of
a shell construct or a function definition:

{ echo }

and

fn() { echo }

aren't complete statements in other shells.  So this means a "}" is
treated as special everywhere on the command line.

> The only way to disable it seems to be
> IGNORE_BRACES, which completely disables (the much used) brace expansion.

Yes, this is really a different thing, since it doesn't involve a brace
on its own as an argument.  They shouldn't really be tied together.  In
fact, it looks like this additional effect of IGNORE_BRACES isn't even
documented.

Here's an option IGNORE_CLOSE_BRACES that only disables the first effect.

> ("disable -r '}'" would break "{ cmd; cmd2 }")

More to the point it would break "}" everywere, even in command
position, i.e. "{ cmd; cmd2; }" too.  If you want the shell to treat
close braces as ordinary characters you'll need the semicolon after
"cmd2".

Index: Doc/Zsh/options.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/options.yo,v
retrieving revision 1.103
diff -p -u -r1.103 options.yo
--- Doc/Zsh/options.yo	18 May 2011 01:54:36 -0000	1.103
+++ Doc/Zsh/options.yo	7 Dec 2011 20:28:41 -0000
@@ -548,7 +548,32 @@ cindex(disabling brace expansion)
 cindex(brace expansion, disabling)
 cindex(expansion, brace, disabling)
 item(tt(IGNORE_BRACES) (tt(-I)) <S>)(
-Do not perform brace expansion.
+Do not perform brace expansion.  For historical reasons this
+also includes the effect of the tt(IGNORE_CLOSE_BRACES) option.
+)
+pindex(IGNORE_CLOSE_BRACES)
+pindex(NO_IGNORE_CLOSE_BRACES)
+pindex(IGNORECLOSEBRACES)
+pindex(NOIGNORECLOSEBRACES)
+item(tt(IGNORE_CLOSE_BRACES))(
+When neither this option no tt(IGNORE_BRACES) is set, a sole
+close brace character `tt(})' is syntactically significant at any
+point on a command line.  This has the effect that no semicolon
+or newline is necessarry before the brace terminating a function
+or current shell construct.  When either option is set, a closing brace
+is syntactically significant only in command position.  Unlike
+tt(IGNORE_BRACES), this option does not disable brace expansion.
+
+For example, with both options unset a function may be defined
+in the following fashion:
+
+example(args() { echo $# })
+
+while if either option is set, this does not work and something
+equivalent to the following is required:
+
+example(args() { echo $#; })
+
 )
 pindex(KSH_GLOB)
 pindex(NO_KSH_GLOB)
Index: Src/lex.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/lex.c,v
retrieving revision 1.69
diff -p -u -r1.69 lex.c
--- Src/lex.c	3 Dec 2011 17:24:46 -0000	1.69
+++ Src/lex.c	7 Dec 2011 20:28:41 -0000
@@ -1857,7 +1857,8 @@ exalias(void)
 
 	    /* Then check for a reserved word */
 	    if ((incmdpos ||
-		 (unset(IGNOREBRACES) && zshlextext[0] == '}' && !zshlextext[1])) &&
+		 (unset(IGNOREBRACES) && unset(IGNORECLOSEBRACES) &&
+		  zshlextext[0] == '}' && !zshlextext[1])) &&
 		(rw = (Reswd) reswdtab->getnode(reswdtab, zshlextext))) {
 		tok = rw->token;
 		if (tok == DINBRACK)
Index: Src/options.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/options.c,v
retrieving revision 1.57
diff -p -u -r1.57 options.c
--- Src/options.c	22 Nov 2010 11:42:47 -0000	1.57
+++ Src/options.c	7 Dec 2011 20:28:41 -0000
@@ -159,6 +159,7 @@ static struct optname optns[] = {
 {{NULL, "histverify",	      0},			 HISTVERIFY},
 {{NULL, "hup",		      OPT_EMULATE|OPT_ZSH},	 HUP},
 {{NULL, "ignorebraces",	      OPT_EMULATE|OPT_SH},	 IGNOREBRACES},
+{{NULL, "ignoreclosebraces",  0},			 IGNORECLOSEBRACES},
 {{NULL, "ignoreeof",	      0},			 IGNOREEOF},
 {{NULL, "incappendhistory",   0},			 INCAPPENDHISTORY},
 {{NULL, "interactive",	      OPT_SPECIAL},		 INTERACTIVE},
Index: Src/zsh.h
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/zsh.h,v
retrieving revision 1.177
diff -p -u -r1.177 zsh.h
--- Src/zsh.h	14 Aug 2011 18:34:28 -0000	1.177
+++ Src/zsh.h	7 Dec 2011 20:28:41 -0000
@@ -2005,6 +2005,7 @@ enum {
     HISTVERIFY,
     HUP,
     IGNOREBRACES,
+    IGNORECLOSEBRACES,
     IGNOREEOF,
     INCAPPENDHISTORY,
     INTERACTIVE,
Index: Test/E01options.ztst
===================================================================
RCS file: /cvsroot/zsh/zsh/Test/E01options.ztst,v
retrieving revision 1.25
diff -p -u -r1.25 E01options.ztst
--- Test/E01options.ztst	1 Jul 2011 15:23:03 -0000	1.25
+++ Test/E01options.ztst	7 Dec 2011 20:28:41 -0000
@@ -256,6 +256,8 @@
 ?next one should fail
 ?(eval):1: parse error near `end'
 
+# ` emacs deconfusion
+
   setopt cshjunkiequotes
   print this should cause an error >&2
   eval "print 'line one
@@ -271,6 +273,8 @@
 ?(eval):1: unmatched '
 ?this should not
 
+# ' emacs deconfusion
+
   nullcmd() { print '$NULLCMD run'; }
   readnullcmd() { print 'Running $READNULLCMD'; cat; }
   NULLCMD=nullcmd
@@ -901,6 +905,8 @@
 ?(eval):exec:6: ls: restricted
 ?(eval):unsetopt:7: can't change option: restricted
 
+# ' emacs deconfusion
+
   fn() {
     print =ls ={ls,}
     local foo='=ls'
@@ -1081,3 +1087,12 @@
 ?+(eval):4> fn
 ?+fn:0> print message
 ?+(eval):5> unsetopt xtrace
+
+  setopt ignoreclosebraces
+  eval "icb_test() { echo this is OK; }"
+  icb_test
+  icb_args() { print $#; }
+  eval "icb_args { this, is, ok, too }"
+0:IGNORE_CLOSE_BRACES option
+>this is OK
+>6


-- 
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/


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

* Re: On the quoting of braces
  2011-12-07 20:31 ` Peter Stephenson
@ 2011-12-07 20:43   ` Mikael Magnusson
  2011-12-23 19:34   ` Christian Neukirchen
  2012-02-23 16:06   ` Christian Neukirchen
  2 siblings, 0 replies; 8+ messages in thread
From: Mikael Magnusson @ 2011-12-07 20:43 UTC (permalink / raw)
  To: zsh-workers

On 2011-12-07, Peter Stephenson <p.w.stephenson@ntlworld.com> wrote:
> On Tue, 06 Dec 2011 23:16:35 +0100
> Christian Neukirchen <chneukirchen@gmail.com> wrote:
>> comparing different shells, I noticed zsh is overly careful for unquoted
>> braces:
>> zsh% echo { foo,bar }
>> zsh: parse error near `}'
>>
>> Why does this error appear?
>
> zsh allows a "}" to appear other than in command position at the end of
> a shell construct or a function definition:
>
> { echo }
>
> and
>
> fn() { echo }
>
> aren't complete statements in other shells.  So this means a "}" is
> treated as special everywhere on the command line.
>
>> The only way to disable it seems to be
>> IGNORE_BRACES, which completely disables (the much used) brace expansion.
>
> Yes, this is really a different thing, since it doesn't involve a brace
> on its own as an argument.  They shouldn't really be tied together.  In
> fact, it looks like this additional effect of IGNORE_BRACES isn't even
> documented.

Under "RESERVED WORDS" we say:
       Additionally, `}' is recognized in any position if the
IGNORE_BRACES option
       is not set.

So maybe we should change that section too.

[...]
> Index: Doc/Zsh/options.yo
> ===================================================================
> RCS file: /cvsroot/zsh/zsh/Doc/Zsh/options.yo,v
> retrieving revision 1.103
> diff -p -u -r1.103 options.yo
> --- Doc/Zsh/options.yo	18 May 2011 01:54:36 -0000	1.103
> +++ Doc/Zsh/options.yo	7 Dec 2011 20:28:41 -0000
> @@ -548,7 +548,32 @@ cindex(disabling brace expansion)
>  cindex(brace expansion, disabling)
>  cindex(expansion, brace, disabling)
>  item(tt(IGNORE_BRACES) (tt(-I)) <S>)(
> -Do not perform brace expansion.
> +Do not perform brace expansion.  For historical reasons this
> +also includes the effect of the tt(IGNORE_CLOSE_BRACES) option.
> +)
> +pindex(IGNORE_CLOSE_BRACES)
> +pindex(NO_IGNORE_CLOSE_BRACES)
> +pindex(IGNORECLOSEBRACES)
> +pindex(NOIGNORECLOSEBRACES)
> +item(tt(IGNORE_CLOSE_BRACES))(
> +When neither this option no tt(IGNORE_BRACES) is set, a sole
                            ^^ nor

-- 
Mikael Magnusson


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

* Re: On the quoting of braces
  2011-12-07 20:31 ` Peter Stephenson
  2011-12-07 20:43   ` Mikael Magnusson
@ 2011-12-23 19:34   ` Christian Neukirchen
  2011-12-23 21:15     ` Bart Schaefer
  2012-01-04 17:17     ` Peter Stephenson
  2012-02-23 16:06   ` Christian Neukirchen
  2 siblings, 2 replies; 8+ messages in thread
From: Christian Neukirchen @ 2011-12-23 19:34 UTC (permalink / raw)
  To: zsh-workers

Peter Stephenson <p.w.stephenson@ntlworld.com> writes:

> Here's an option IGNORE_CLOSE_BRACES that only disables the first effect.

I'm sorry I only got around testing this now.

First, I noticed setting IGNORE_CLOSE_BRACES corrupts all my single line
definitions in .zshrc, but that was kind of intended and can be fixed by
using ";}" of course.  Therefore, I put it at the end of .zshrc for now.

However, it also breaks completion code, making the new feature rather
unusable:

juno ~% zsh --version
zsh 4.3.15 (x86_64-unknown-linux-gnu)
juno ~% vim /
_main_complete:60: parse error near `fi'

Curiously, this doesn't happen when I set the option from the command line.

When I force _main_complete to be loaded *before* setting
IGNORE_CLOSE_BRACES with

  autoload +X -Uz _main_complete

it works, even though _comp_options specifies NO_ignoreclosebraces, so
this option shouldn't even be set in _main_complete.

Hope that helps,
-- 
Christian Neukirchen  <chneukirchen@gmail.com>  http://chneukirchen.org


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

* Re: On the quoting of braces
  2011-12-23 19:34   ` Christian Neukirchen
@ 2011-12-23 21:15     ` Bart Schaefer
  2012-01-04 17:17     ` Peter Stephenson
  1 sibling, 0 replies; 8+ messages in thread
From: Bart Schaefer @ 2011-12-23 21:15 UTC (permalink / raw)
  To: zsh-workers

On Dec 23,  8:34pm, Christian Neukirchen wrote:
}
} When I force _main_complete to be loaded *before* setting
} IGNORE_CLOSE_BRACES with
} 
}   autoload +X -Uz _main_complete
} 
} it works, even though _comp_options specifies NO_ignoreclosebraces, so
} this option shouldn't even be set in _main_complete.

As you discovered, because the option affects parsing, it has to be
off during the loading of the completion system (or any of the other
functions written for native zsh).  Similarly teh options SHORT_LOOPS,
RC_QUOTES, various CSH_JUNKIE_ options, POSIX_ALIASES, POSIX_STRINGS,
POSIX_IDENTIFIERS, and likely C_PRECEDENCES and OCTAL_ZEROES, must be
set to their default values to avoid parsing problems.

It might be worth adding an option to autoload that works like -z but
extends to the whole set of options covered by "emulate -R".  Of course
you can get that with

    emulate -R zsh -c 'autoload -Uz ...'

but that's a bit inconvenient.


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

* Re: On the quoting of braces
  2011-12-23 19:34   ` Christian Neukirchen
  2011-12-23 21:15     ` Bart Schaefer
@ 2012-01-04 17:17     ` Peter Stephenson
  2012-01-04 17:19       ` Geoff Raye
  1 sibling, 1 reply; 8+ messages in thread
From: Peter Stephenson @ 2012-01-04 17:17 UTC (permalink / raw)
  To: zsh-workers

This fixes _main_complete so it doesn't depend on ignore_close_braces
being unset when run.  The option will be set in time to autoload any
further completion function.

Index: Completion/Base/Core/_main_complete
===================================================================
RCS file: /cvsroot/zsh/zsh/Completion/Base/Core/_main_complete,v
retrieving revision 1.14
diff -p -u -r1.14 _main_complete
--- Completion/Base/Core/_main_complete	13 Dec 2011 17:43:01 -0000	1.14
+++ Completion/Base/Core/_main_complete	4 Jan 2012 17:15:53 -0000
@@ -3,6 +3,10 @@
 # The main loop of the completion code. This is what is called when 
 # completion is attempted from the command line.
 
+# Note that this function is parsed before $_comp_setup is evaluated,
+# so that it should make conservative assumptions about the setting
+# of the various options that affect parsing.
+
 # In case non-standard separators are in use.
 local IFS=$' \t\n\0'
 
@@ -52,9 +56,12 @@ if [[ ( "$tmp" = *pending(|[[:blank:]]*)
 fi
 
 if [[ "$compstate[insert]" = tab* ]]; then
-  { [[ "$tmp" = (|*[[:blank:]])(yes|true|on|1)(|[[:blank:]]*) ]] &&
-    { [[ "$curcontext" != :* || -z "$compstate[vared]" ]] ||
-        zstyle -t ":completion:vared${curcontext}:" insert-tab } } && return 0
+  if [[ "$tmp" = (|*[[:blank:]])(yes|true|on|1)(|[[:blank:]]*) ]]; then
+    if [[ "$curcontext" != :* || -z "$compstate[vared]" ]] ||
+      zstyle -t ":completion:vared${curcontext}:" insert-tab; then
+      return 0
+    fi
+  fi
 
   compstate[insert]="${compstate[insert]//tab /}"
 fi

-- 
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/


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

* Re: On the quoting of braces
  2012-01-04 17:17     ` Peter Stephenson
@ 2012-01-04 17:19       ` Geoff Raye
  0 siblings, 0 replies; 8+ messages in thread
From: Geoff Raye @ 2012-01-04 17:19 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: zsh-workers

[Peter Stephenson]
> This fixes _main_complete so it doesn't depend on ignore_close_braces
> being unset when run.  The option will be set in time to autoload any
> further completion function.
> 
> Index: Completion/Base/Core/_main_complete
> ===================================================================
> RCS file: /cvsroot/zsh/zsh/Completion/Base/Core/_main_complete,v
> retrieving revision 1.14
> diff -p -u -r1.14 _main_complete
> --- Completion/Base/Core/_main_complete	13 Dec 2011 17:43:01 -0000
> 	1.14
> +++ Completion/Base/Core/_main_complete	4 Jan 2012 17:15:53 -0000
> @@ -3,6 +3,10 @@
>  # The main loop of the completion code. This is what is called when 
>  # completion is attempted from the command line.
>  
> +# Note that this function is parsed before $_comp_setup is evaluated,
> +# so that it should make conservative assumptions about the setting
> +# of the various options that affect parsing.
> +
>  # In case non-standard separators are in use.
>  local IFS=$' \t\n\0'
>  
> @@ -52,9 +56,12 @@ if [[ ( "$tmp" = *pending(|[[:blank:]]*)
>  fi
>  
>  if [[ "$compstate[insert]" = tab* ]]; then
> -  { [[ "$tmp" = (|*[[:blank:]])(yes|true|on|1)(|[[:blank:]]*) ]] &&
> -    { [[ "$curcontext" != :* || -z "$compstate[vared]" ]] ||
> -        zstyle -t ":completion:vared${curcontext}:" insert-tab } } && return
>  0
> +  if [[ "$tmp" = (|*[[:blank:]])(yes|true|on|1)(|[[:blank:]]*) ]]; then
> +    if [[ "$curcontext" != :* || -z "$compstate[vared]" ]] ||
> +      zstyle -t ":completion:vared${curcontext}:" insert-tab; then
> +      return 0
> +    fi
> +  fi
>  
>    compstate[insert]="${compstate[insert]//tab /}"
>  fi
> 
> -- 
> Peter Stephenson <p.w.stephenson@ntlworld.com>
> Web page now at http://homepage.ntlworld.com/p.w.stephenson/


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

* Re: On the quoting of braces
  2011-12-07 20:31 ` Peter Stephenson
  2011-12-07 20:43   ` Mikael Magnusson
  2011-12-23 19:34   ` Christian Neukirchen
@ 2012-02-23 16:06   ` Christian Neukirchen
  2 siblings, 0 replies; 8+ messages in thread
From: Christian Neukirchen @ 2012-02-23 16:06 UTC (permalink / raw)
  To: zsh-workers

Peter Stephenson <p.w.stephenson@ntlworld.com> writes:

> Here's an option IGNORE_CLOSE_BRACES that only disables the first effect.

After using this for a few weeks, I've come to the conclusion that it
sucks in real world usage.

Too often, I'm defining single line functions and forget to type ";}"
or short loops ala "for f ({1..3}) { echo $f }".

Also, it broke various zsh libraries.

Anyone using it and liking it?
-- 
Christian Neukirchen  <chneukirchen@gmail.com>  http://chneukirchen.org


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

end of thread, other threads:[~2012-02-23 16:22 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-12-06 22:16 On the quoting of braces Christian Neukirchen
2011-12-07 20:31 ` Peter Stephenson
2011-12-07 20:43   ` Mikael Magnusson
2011-12-23 19:34   ` Christian Neukirchen
2011-12-23 21:15     ` Bart Schaefer
2012-01-04 17:17     ` Peter Stephenson
2012-01-04 17:19       ` Geoff Raye
2012-02-23 16:06   ` Christian Neukirchen

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