backtick should not be matched to wildignore.

232 views
Skip to first unread message

mattn

unread,
Jun 15, 2012, 9:09:54 AM6/15/12
to vim...@googlegroups.com
Try following.

:set wildignore+=*.bak
:e `="foo.bak"`
E480: No match: `="foo.bak"`

I think, this should be matched to wildignore. Also :e `ls foo.c`.

https://gist.github.com/2936402

Bram, please check.

BTW, fnameescape() have bugs that wasn't fixed yet on windows.

https://groups.google.com/forum/?fromgroups#!msg/vim_dev/sTfkV2vcBoI/CckA_gxvYQsJ

On windows, we can't open file or directory that contains !, [][] in filename.

mattn

unread,
Jun 15, 2012, 9:15:17 AM6/15/12
to vim...@googlegroups.com
> I think, this should be matched to wildignore. Also :e `ls foo.c`.

Sorry typo.


I think, this should NOT be matched to wildignore.

Ingo Karkat

unread,
Jun 15, 2012, 9:35:05 AM6/15/12
to vim...@googlegroups.com
On 15-Jun-2012 06:09:54 -0700 (PDT), mattn wrote:

> Try following.
>
> :set wildignore+=*.bak
> :e `="foo.bak"`
> E480: No match: `="foo.bak"`
>
> I think, this should be matched to wildignore. Also :e `ls foo.c`.

I have the opinion that having 'wildignore' apply (they way it is now) is more
consistent with the behavior of file completion, glob expansion (:arg foo*), and
interactive use of Vim. This is mostly from a consistency / mental model point
of view; I have rarely used backtick expansion so far, anyhow.

The issue is that some plugin writers have used backtick expansion as a
workaround for the mentioned bugs in fnameescape(). I think these bug(s) should
rather be addressed, and fnameescape() should be the canonical way for use in
scripts, as intended. (I also find it way more expressive that the backtick hack.)

> BTW, fnameescape() have bugs that wasn't fixed yet on windows.
>
> https://groups.google.com/forum/?fromgroups#!msg/vim_dev/sTfkV2vcBoI/CckA_gxvYQsJ
>
> On windows, we can't open file or directory that contains !, [][] in filename.

-- regards, ingo

Ingo Karkat

unread,
Jun 15, 2012, 10:59:03 AM6/15/12
to vim...@googlegroups.com
On 15-Jun-2012 15:35:05 +0200, Ingo Karkat wrote:

> The issue is that some plugin writers have used backtick expansion as
> a workaround for the mentioned bugs in fnameescape().

I think the help text could also be more clear about 'wildignore'; I only found
out about this behavior by chance.

-- regards, ingo

diff -r ca39f14c1ec3 runtime/doc/editing.txt
--- a/runtime/doc/editing.txt Thu Jun 14 20:59:25 2012 +0200
+++ b/runtime/doc/editing.txt Fri Jun 15 17:05:30 2012 +0200
@@ -377,8 +377,9 @@
embedded spaces must be escaped with a backslash.

*wildcard* *wildcards*
-Wildcards in {file} are expanded. Which wildcards are supported depends on
-the system. These are the common ones:
+Wildcards in {file} are expanded, but as with file completion, 'wildignore'
+and 'suffixes' apply. Which wildcards are supported depends on the system.
+These are the common ones:
? matches one character
* matches anything, including nothing
** matches anything, including nothing, recurses into directories
@@ -422,9 +423,10 @@
external command, by using the syntax `={expr}` e.g.: >
:e `=tempname()`
The expression can contain just about anything, thus this can also be used to
-avoid the special meaning of '"', '|', '%' and '#'. Names are to be separated
-with line breaks. When the result is a |List| then each item is used as a
-name. Line breaks also separate names.
+avoid the special meaning of '"', '|', '%' and '#', but 'wildignore' still
+applies. Use |fnameescape()| together with |:execute| to open arbitrary
+files. Names are to be separated with line breaks. When the result is a
+|List| then each item is used as a name. Line breaks also separate names.

*++opt* *[++opt]*
The [++opt] argument can be used to force the value of 'fileformat',
diff -r ca39f14c1ec3 runtime/doc/options.txt
--- a/runtime/doc/options.txt Thu Jun 14 20:59:25 2012 +0200
+++ b/runtime/doc/options.txt Fri Jun 15 17:05:30 2012 +0200
@@ -7841,9 +7841,9 @@
{not available when compiled without the |+wildignore|
feature}
A list of file patterns. A file that matches with one of these
- patterns is ignored when completing file or directory names, and
- influences the result of |expand()|, |glob()| and |globpath()| unless
- a flag is passed to disable this.
+ patterns is ignored when expanding |wildcards|, completing file or
+ directory names, and influences the result of |expand()|, |glob()| and
+ |globpath()| unless a flag is passed to disable this.
The pattern is used like with |:autocmd|, see |autocmd-patterns|.
Also see 'suffixes'.
Example: >

Yasuhiro MATSUMOTO

unread,
Jun 15, 2012, 12:18:24 PM6/15/12
to vim...@googlegroups.com
No. Currentry, `=foo` is a just only way that can specify argument
without escaping, and can specify non-valid filename. This is usefull
to make buffer with especially name. ex: "[##My Buffer##]".
If applies wildignore or suffixes for this, we must avoid to match to
them with that backup and specify empty to wildignore like following.

:let old_wildignore = &wildignore
:set wildignore=
:so `=script_name_that_may_change_value_of_wildignore_option`
:let &wildignore = old_wildignore
" the change of wildignore is not arrlied

I think, fnameescape() is not best way to specify argument for any
commands. Because edit command treat argument as pattern.

:e [a-z]

If fnameescape() escape this,

:e \[a-z\]

When you run below on windows:

mkdir C:\[a-
mkdir C:\[a-\]

How to specify argument to edit this?
> --
> You received this message from the "vim_dev" maillist.
> Do not top-post! Type your reply below the text you are replying to.
> For more information, visit http://www.vim.org/maillist.php
>


--
- Yasuhiro Matsumoto

Bram Moolenaar

unread,
Jun 15, 2012, 2:31:27 PM6/15/12
to mattn, vim...@googlegroups.com
Thanks, I'll look into it.

--
Everyone has a photographic memory. Some don't have film.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

Ingo Karkat

unread,
Jun 15, 2012, 3:45:39 PM6/15/12
to vim...@googlegroups.com
On 16-Jun-2012 01:18:24 +0900, Yasuhiro MATSUMOTO wrote:

> No. Currentry, `=foo` is a just only way that can specify argument
> without escaping, and can specify non-valid filename. This is usefull
> to make buffer with especially name. ex: "[##My Buffer##]".

fnameescape() will properly escape that. The problem is that when specifying a
name that can be interpreted as a glob, like [a-z], it is opened as that literal
text when the glob doesn't yield a match, but will open a file (e.g. "q") if
such a match exists. (Or, in the case of single-argument commands like :edit and
multiple matches, will even complain about too many filenames!)

> I think, fnameescape() is not best way to specify argument for any
> commands. Because edit command treat argument as pattern.

Though all those filenames that can be interpreted as a glob are rare and
therefore can be categorized as pathological cases, I tend to agree. The problem
is that the help for fnameescape() in particular recommends its use for such cases:
#v+
Example: >
:let fname = '+some str%nge|name'
:exe "edit " . fnameescape(fname)
< results in executing: >
edit \+some\ str\%nge\|name
#v-

I have seen most plugins use fnameescape() in this way. In fact, some
(especially older) plugins use no or some DIY escaping, yet there seem to be few
complaints. Are we really talking about an actual issue here? Should we continue
recommending the use of fnameescape(), even though it's slightly broken? I think
the help for fnameescape() should mention the backtick-expansion alternative,
and give clear guidelines when to use what. This is complex stuff, and we can't
expect plugin authors to find out and learn about the intricacies all on their
own! See, I have been using fnameescape() and thought I was safe, you used the
backtick-expansion trick and didn't know about the effect of 'wildignore'.

> :e [a-z]
>
> If fnameescape() escape this,
>
> :e \[a-z\]
>
> When you run below on windows:
>
> mkdir C:\[a-
> mkdir C:\[a-\]
>
> How to specify argument to edit this?

For me, fnameescape('[a-z]') yields "[a-z]" on Windows and "\[a-z]" on Linux,
but never "\[a-z\]". I guess this is because Windows doesn't understand the
glob, so it doesn't need to be escaped. Strangely, :e [a-z] will edit an
existing file named q. Does Vim perform this globbing?


While fiddling around, I think I also found a bug in backtick-expansion:
:edit `='*'`
On Linux (Vim 7.3.535, BIG version with GTK2 GUI), this correctly edits a new
file named "*".
On Windows (GVIM 7.3.540, HUGE version with GUI, taken from Cream), I get:
E480: No match: `='*'`
Shouldn't the backtick-expansion result always be taken literally? It looks like
it mistakenly performs a glob here!

-- regards, ingo

PS: Please bottom-post on this list.

mattn

unread,
Jun 16, 2012, 12:23:26 PM6/16/12
to vim...@googlegroups.com
<snip>

My change doesn't break behavior of expanding. Just fix(not change) of applying wildignore. When backtick is expanded as filenames, it should be that you wanted. I think backtick is not completion, so wildignore shouldn't affect to backtick. I want to separate expanding and completion. You are talking about completion. I agree that completion should be applied wildignore. But user-own expanding shouldn't be applied.

I don't think, that backtick is applied to wildignore doesn't have any merit to users.
When user want to use backtick, they don't expected the behavior.

> E480: No match: `='*'`
> Shouldn't the backtick-expansion result always be taken literally? It looks like
> it mistakenly performs a glob here!

My fix will solve this.

> PS: Please bottom-post on this list.

I sent e-mail from my handy phone via gmail. So I couldn't change that order. Sorry.

Ingo Karkat

unread,
Jun 16, 2012, 2:56:47 PM6/16/12
to vim...@googlegroups.com
On 16-Jun-2012 09:23:26 -0700 (PDT), mattn wrote:

> [5 sentences deleted]
> You are talking about completion. I agree that completion
> should be applied wildignore. But user-own expanding shouldn't be
> applied.

Well, actually 'wildignore' applies not just to file completion (with <Tab>),
but also to expansion of globs like foo* (e.g. when using :args). The help on
'wildignore' is a little short on information, that's what my patch to the
documentation in this thread was about.
I understand this option as: When I put a pattern in there, Vim commands will
never open matching files. However, plugins may want to defy this user order;
that's why functions like glob() have an option to disable wildignore for it.

> I don't think, that backtick is applied to wildignore doesn't have any
> merit to users. When user want to use backtick, they don't expected
> the behavior.

As I said, I have no strong opinion here, other than my desire for consistency
in operation (and your proposed change would affect that consistency!). I have
hardly ever used backtick-expansion interactively, and I guess most Vim users
don't even know about this feature.

What I do care about is advice for plugin writers. I think just changing the
behavior of backtick expansion via your patch doesn't cut it. We need a clear
demarcation between
:edit `=file`
and
:execute 'edit' fnameescape(file)
Right now, the help unequivocally recommends use of fnameescape(). Based on what
I learned through our discussion, this is bad advice for cases where the file
name may be interpreted as a file glob, like [a-z]. In case there's a matching
file, the first will correctly open the strange file, but the second will open
the match or even cause an error.

>> E480: No match: `='*'`
>> Shouldn't the backtick-expansion result always be taken literally? It
>> looks like it mistakenly performs a glob here!
>
> My fix will solve this.

Well sure, you mask the problem by ignoring 'wildignore', which is related to
globbing. I just hope that there's not still a deeper underlying problem.

-- regards, ingo

Bram Moolenaar

unread,
Jul 6, 2012, 11:24:10 AM7/6/12
to mattn, vim...@googlegroups.com

Yasuhiro Matsumoto wrote:

> Try following.
>
> :set wildignore+=*.bak
> :e `="foo.bak"`
> E480: No match: `="foo.bak"`
>
> I think, this should be matched to wildignore. Also :e `ls foo.c`.
>
> https://gist.github.com/2936402
>
> Bram, please check.

This does not appear to be the right solution. It also affects a
command like ":n foo*" even though that should obey 'wildignore'.

Your example is about passing a literal string. But it might as well be
an expression that returns a list of file names. Again, 'wildignore'
should apply then.

Currently one would use :exe to edit a file with a name that comes from
an expression:
:exe ":e " .. "foo.bak"

Why would the user want to use backticks instead?

> BTW, fnameescape() have bugs that wasn't fixed yet on windows.
>
> https://groups.google.com/forum/?fromgroups#!msg/vim_dev/sTfkV2vcBoI/CckA_gxvYQsJ
>
> On windows, we can't open file or directory that contains !, [][] in filename.

This is on the todo list. I have not seen a patch yet.

--
I AM THANKFUL...
...for the mess to clean after a party because it means I have
been surrounded by friends.

thinca

unread,
Jul 8, 2012, 11:34:29 PM7/8/12
to vim...@googlegroups.com
2012/7/7 Bram Moolenaar <Br...@moolenaar.net>:

> This does not appear to be the right solution. It also affects a
> command like ":n foo*" even though that should obey 'wildignore'.

Backtick can avoid any special characters, including wildcard.
Thus, there is no reason for applying 'wildignore'.
":n foo*" does not relate on this discussion. This is not escaped by backtick.


> Your example is about passing a literal string. But it might as well be
> an expression that returns a list of file names. Again, 'wildignore'
> should apply then.

A list of file names is not a wildcard.

:args `=['a.txt', 'b.bak', 'c.txt']`

This should be equal to:

:args a.txt b.bak c.txt

Not the following.

:args a.txt c.txt


> Why would the user want to use backticks instead?

For example, I want to open a new file "file[a].txt".

:e file[a].txt

This is often successful. But, if file "filea.txt" exists, Vim opens it.
I try to avoid it by escape.

:e file\[a].txt

However, this doesn't work well on MS Windows. "\" is treated as a
directory separator.
Like this, the escape by "\" does not work. fnameescape() is useless.
I try escape according to advice of ":help wildcard".

:e file\[[]a].txt

But, this also doesn't work. I don't know the reason.
Additionally, this way is too complex.
So, I use backtick to avoid this problem.

:e `='file[a].txt'`

This works well.


Thanks.

--
thinca <thi...@gmail.com>

Bram Moolenaar

unread,
Jul 10, 2012, 6:31:05 AM7/10/12
to thinca, vim...@googlegroups.com
You are misusing backticks. The normal use is something like:

:e `glob(pattern)`

Vim can't really make a difference for what expression you use inside
the backticks. That would be too complicated.

If we want something to take the expression literally we would need
another mechanism. Perhaps a command modifier that disables wildcard
expansion, something like:

:nowild e file[a].txt

--
hundred-and-one symptoms of being an internet addict:
98. The Alta Vista administrators ask you what sites are missing
in their index files.

mattn

unread,
Jul 10, 2012, 6:48:18 AM7/10/12
to vim...@googlegroups.com, thinca
> You are misusing backticks. The normal use is something like:
>
> :e `glob(pattern)`

Really? :help `= says following:

*`=*
You can have the backticks expanded as a Vim expression, instead of an


external command, by using the syntax `={expr}` e.g.: >
:e `=tempname()`
The expression can contain just about anything, thus this can also be used to

avoid the special meaning of '"', '|', '%' and '#'. Names are to be separated

with line breaks. When the result is a |List| then each item is used as a

mattn

unread,
Mar 4, 2013, 8:51:08 AM3/4/13
to vim...@googlegroups.com, thinca
I wrote a patch for nowild.

https://gist.github.com/mattn/5079965

How about this?

Bram Moolenaar

unread,
Mar 4, 2013, 5:32:43 PM3/4/13
to mattn, vim...@googlegroups.com, thinca
With this help:

*:now* *:nowild*
:now[ild] {command}

Execute {command} with 'wildignore' option disabled.
This will be useful to ignore 'wildignroe' option
raise error. For example, it can avoid to escape
filenames to open with |`=| : >
:set wildignore=*.tmp
:nowild e `=tempname()`

I think it makes sense. There needs to be a hint in the 'wildignore'
help about this as well.

--
How To Keep A Healthy Level Of Insanity:
1. At lunch time, sit in your parked car with sunglasses on and point
a hair dryer at passing cars. See if they slow down.
Reply all
Reply to author
Forward
0 new messages