I ran into a bug with autocompletion. This is on fish 1.23.1. I
downloaded the trunk sources but there doesn't seem to be any
difference in the relevant source files, so I assume it's still there.
To reproduce:
mkdir "x("
cd x\(<tab>
This gives a whole screen of error messages, including twice the help
of 'begin'. The whole error message is reported below. It appears to
happen with any filename that contains a brace, including names like
"foo (1)", "foo (2)". It turns out to be caused in __fish_complete_cd.
The completion function calls "command -ct", which expands all
escapes, including the \( escape. The result is passed to eval, which
causes a syntax error. A workaround is to re-quote all special
characters that come out of "command -ct", I've attached a patch which
does that. (But I'm not certain I got all the shell metacharacters right.)
But, I think this patch is a bit ugly, because you never really /know/
what the user entered, it could have been quoted in several differen
ways. Right now, `commandline` gives back exactly the same thing
whether I have `(` on my prompt or `\(`, but those make quite a bit of
a difference! An architecturally cleaner way would I think be to add a
way to retrieve the unprocessed command line, like a flag on
`commandline` that stops it from expanding escapes.
=====
workaround:
content of __fish_quote_specials.fish:
function __fish_quote_specials
sed 's/[<>^|()$*?]/\\\\&/g'
end
patch for __fish_complete_cd.fish:
23c23
< eval printf '\%s\\tDirectory\\n' (commandline -ct)\*/
---
> eval printf '\%s\\tDirectory\\n' (commandline -ct |
> __fish_quote_specials)\*/
36c36
< eval printf '"%s\tDirectory in "'$i'"\n"' (commandline
-ct)\*/
---
> eval printf '"%s\tDirectory in "'$i'"\n"' (commandline
> -ct | __fish_quote_specials)\*/
===============
the error it gives:
fish: Tokenizer error: “Unexpected end of string, parenthesis do not match”
/usr/local/share/fish/functions/__fish_complete_cd.fish (line 2):
begin; printf "%s\tDirectory in "."\n" x(*/ ;end eval2_inner <&3 3<&-
^
in . (source) call of file “-”,
called on line 22 of file
“/usr/local/share/fish/functions/__fish_complete_cd.fish”,
in function “__fish_complete_cd”,
called on standard input,
in command substitution
called on standard input,
fish: Tokenizer error: “Unexpected end of string, parenthesis do not match”
/usr/local/share/fish/functions/__fish_complete_cd.fish (line 2):
begin; printf "%s\tDirectory in "."\n" x(*/ ;end eval2_inner <&3 3<&-
^
in . (source) call of file “-”,
called on line 22 of file
“/usr/local/share/fish/functions/__fish_complete_cd.fish”,
in function “__fish_complete_cd”,
called on standard input,
in command substitution
called on standard input,
fish: Could not locate end of block. The “end” command is missing,
misspelled or a “;” is missing.
/usr/local/share/fish/functions/__fish_complete_cd.fish (line 2):
begin; printf "%s\tDirectory in "."\n" x(*/ ;end eval2_inner <&3 3<&-
^
in . (source) call of file “-”,
called on line 22 of file
“/usr/local/share/fish/functions/__fish_complete_cd.fish”,
in function “__fish_complete_cd”,
called on standard input,
in command substitution
called on standard input,
begin - start a new block of code
Synopsis
begin; [COMMANDS...;] end
Description
The begin builtin is used to create a new block of code. The block is
unconditionally executed. begin; ...; end is equivalent to if true;
...; end. The begin command is used to group any number of commands
into a block. The reason for doing so is usually either to introduce a
new variable scope, to redirect the input or output of a set of
commands as a group, or to specify precedence when using the
conditional commands like and.
The begin command does not change the current exit status.
Example
The following code sets a number of variables inside of a block scope.
Since the variables are set inside the block and have local scope, they
will be automatically deleted when the block ends.
begin
set -l PIRATE Yarrr
...
end
# This will not output anything, since the PIRATE variable went out
# of scope at the end of the block
echo $PIRATE
In the following code, all output is redirected to the file out.html.
begin
echo $xml_header
echo $html_header
if test -e $file
...
end
...
end > out.html
.: Error while reading file “<stdin>”
fish: Tokenizer error: “Unexpected end of string, parenthesis do not match”
/usr/local/share/fish/functions/__fish_complete_cd.fish (line 2):
begin; printf "%s\tDirectory in "/home/jan"\n" x(*/ ;end eval2_inner
<&3 3<&-
^
in . (source) call of file “-”,
called on line 22 of file
“/usr/local/share/fish/functions/__fish_complete_cd.fish”,
in function “__fish_complete_cd”,
called on standard input,
in command substitution
called on standard input,
fish: Tokenizer error: “Unexpected end of string, parenthesis do not match”
/usr/local/share/fish/functions/__fish_complete_cd.fish (line 2):
begin; printf "%s\tDirectory in "/home/jan"\n" x(*/ ;end eval2_inner
<&3 3<&-
^
in . (source) call of file “-”,
called on line 22 of file
“/usr/local/share/fish/functions/__fish_complete_cd.fish”,
in function “__fish_complete_cd”,
called on standard input,
in command substitution
called on standard input,
fish: Could not locate end of block. The “end” command is missing,
misspelled or a “;” is missing.
/usr/local/share/fish/functions/__fish_complete_cd.fish (line 2):
begin; printf "%s\tDirectory in "/home/jan"\n" x(*/ ;end eval2_inner
<&3 3<&-
^
in . (source) call of file “-”,
called on line 22 of file
“/usr/local/share/fish/functions/__fish_complete_cd.fish”,
in function “__fish_complete_cd”,
called on standard input,
in command substitution
called on standard input,
begin - start a new block of code
Synopsis
begin; [COMMANDS...;] end
Description
The begin builtin is used to create a new block of code. The block is
unconditionally executed. begin; ...; end is equivalent to if true;
...; end. The begin command is used to group any number of commands
into a block. The reason for doing so is usually either to introduce a
new variable scope, to redirect the input or output of a set of
commands as a group, or to specify precedence when using the
conditional commands like and.
The begin command does not change the current exit status.
Example
The following code sets a number of variables inside of a block scope.
Since the variables are set inside the block and have local scope, they
will be automatically deleted when the block ends.
begin
set -l PIRATE Yarrr
...
end
# This will not output anything, since the PIRATE variable went out
# of scope at the end of the block
echo $PIRATE
In the following code, all output is redirected to the file out.html.
begin
echo $xml_header
echo $html_header
if test -e $file
...
end
...
end > out.html
.: Error while reading file “<stdin>”
------------------------------------------------------------------------------
OpenSolaris 2009.06 is a cutting edge operating system for enterprises
looking to deploy the next generation of Solaris that includes the latest
innovations from Sun and the OpenSource community. Download a copy and
enjoy capabilities such as Networking, Storage and Virtualization.
Go to: http://p.sf.net/sfu/opensolaris-get
_______________________________________________
Fish-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/fish-users