New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parser: fish fails to traverse pipes across newlines. #1285

Closed
geoff-codes opened this Issue Feb 5, 2014 · 10 comments

Comments

Projects
None yet
5 participants
@geoff-codes
Copy link
Contributor

geoff-codes commented Feb 5, 2014

I believe in any other shell that uses the pipeline syntax fish inherits, it is allowed to break the statement at the pipe itself. That is, if echo foo | cat - | cat is valid syntax, so is:

echo foo |
cat - |  # Tab space comments.
cat

foo

But in fish, the newline must be escaped:

Expected a command, but instead found end of the statement
echo foo |
          ^

Seems... buggish.

@zanchey

This comment has been minimized.

Copy link
Member

zanchey commented Feb 5, 2014

Is there other syntax which can break across lines? Quoted strings can; brace expansion, redirection, command substitutions, and control statements can't.

@geoff-codes

This comment has been minimized.

Copy link
Contributor

geoff-codes commented Feb 5, 2014

The other ones are the boolean operators.
These are VERY useful though, thanks for reminding me.

Can be used to order a non-branching logical secuence quite effectively.

#!/usr/bin/env sh
                                          cat "$0"; sleep 2; echo; echo

[ 1 -eq 0 ] && [ 0 -eq 1 ] && [ a = b ] && [ 1 -eq 10 ] && [ a = b ] &&
                                                          return 42  ||
                                           [ 0 -lt 10 ] && [ a = a ] &&
[ 2 -eq 2 ] && [ 1 -eq 1 ] && [ a = a ] &&


                       we=2 && too=to          #|/#/#*/|/##*
                  tea=to && test 2 != $we  ||#/####/
           echo we $we sit to have tea $tea | ##|
           cat  - |                     tee && #\
              echo now we $tea | cat - && #\ #\#\*##*>
                  echo $too who\? $too     we||:; echo>&2

Or you can write a fish haiku!

Same error in fish though, yep.

true; and
fish: Expected a command name, got token of type 'End of command'
true; and
         ^
@xfix

This comment has been minimized.

Copy link
Member

xfix commented Feb 5, 2014

Boolean operators are pretty much functions with special parsing. Just write it like this instead, with new line instead of semicolon.

true
and false
@geoff-codes

This comment has been minimized.

Copy link
Contributor

geoff-codes commented Feb 5, 2014

Oops. Right, duh. @zanchey darn you distracting me! Ha.

Correct me if I'm wrong x, but to be specific, they are (builtin) functions, which conditionally execute their arguments based of the return value of the prior statement.

... so anyway, just the issue in the title. Pipes.

@xfix

This comment has been minimized.

Copy link
Member

xfix commented Feb 5, 2014

@g-nix: To be exact, those are keywords, not builtin functions. They are specificially parsed, so something like this works.

true
and begin
    echo Hello, world.
end

To be honest, I don't like how it works, but well, it's a keyword.

@geoff-codes

This comment has been minimized.

Copy link
Contributor

geoff-codes commented Feb 5, 2014

... Interesting. It seems (from an analytic standpoint) it would work exactly the same as a function. But I'm sure implementation-wise its the way it is for some reason.

I can't see any logical reason why any function for which one or more argument is required, and further arguments are still needed, needs to be treated any differently than a block that has not seen its end statement. That is, to require not just whitespace to separate arguments, but literally to require code point 20 (or 8, tab), and allow multiple runs of these, but disallow a newline. Its all whitespace. For example,

if       #  if     \
  [      #     [   \
    x    #       a \
    =    #       = \
    x    #       a \
  ]      #     ]
  echo x #     echo a
end      #   end

is invalid on the left, but valid of the right. It's not like there's any ambiguity here — there's no possibility of it "getting it wrong" by completing the statement too soon. In each case if the correct number of arguments are not given, you get an error.

Also I just turned up another bug I think in testing that — while I can still command [ in the new parser, it tells me almost anywhere I put it on the command line, "unexpected end of string, square brackets do not match" if I call /bin/[, and if I disregard the syntax highlighting (red, straight through), "Unknown command '/bin/[ foo ]'.

@ridiculousfish

This comment has been minimized.

Copy link
Member

ridiculousfish commented Feb 5, 2014

We should consider the experience of novice users. I remember in bash I would often do something (like paste a string containing a backtick or other sigil) that would get me "lost" in a sequence of '>' prompts, where I had to know to ctrl-C out of it.

Good catch on the /bin/[ bug!

@geoff-codes

This comment has been minimized.

Copy link
Contributor

geoff-codes commented Feb 6, 2014

@ridiculousfish no contention there — same thing happened to me — but I actually had an analogous experience with fish as well, something to this effect:

~> if true
       _   # < Um, where am I? What's going on here?
~> if true
       echo 1
       _   # < Ok I get it now.

The next time, I remember there's some type of automatic handling of interactive multiline statements, but I forgot that it's if [condition], not just if, and so I try to type something like

~> if
    true

and I get:

~> if
fish: Expected a command name, got token of type 'End of command'
if
  ^
~> 

and so I guess (maybe I'm just weird) I find (found) this to be a quite confusing distinction.

@ridiculousfish

This comment has been minimized.

Copy link
Member

ridiculousfish commented Feb 6, 2014

Thanks, cataloging those sort of experiences is quite useful.

@ridiculousfish

This comment has been minimized.

Copy link
Member

ridiculousfish commented Feb 18, 2018

This got fixed in #4712 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment