wincent / command-t

⌨️ Fast file navigation for Neovim and Vim
BSD 2-Clause "Simplified" License
2.74k stars 317 forks source link

Let wildcards without a period work. #369

Closed twrecked closed 4 years ago

twrecked commented 4 years ago

This fix lets wildcards without a period - ie, *~, Vim's default back up extension - to be hidden from file lists.

wincent commented 4 years ago

It's about several years since I last touched this function, so I'm a bit fuzzy on how strict we should be here. I just remember that the original intent was to be err on the conservative side.

Some things I notice:

If your goal is to ignore files of the form *~ (ie. ending with a tilde) or really any *suffix, I would have expected something like this:

if pattern.match(%r{\A\*\([^*/.]+)\z})
  # *something (match file with suffix at any level)
  '(\A|/)[^/]+' + Regexp.escape($~[1]) + '\z'

(Typed in GitHub, so may be wrong.)

twrecked commented 4 years ago

Your are absolutely correct, I really just wanted to trap *something.

I'll tighten it up and test it again.

Thanks for your input. And thanks for the plugin.

twrecked commented 4 years ago

I just pushed a new commit that fixes the issues you brought up.

wincent commented 4 years ago

Thanks @twrecked. I think this is probably all right now. I'm going to merge it with this additional tweak on top:

diff --git a/ruby/command-t/lib/command-t/vim.rb b/ruby/command-t/lib/command-t/vim.rb
index d8bcffe..f01bda4 100644
--- a/ruby/command-t/lib/command-t/vim.rb
+++ b/ruby/command-t/lib/command-t/vim.rb
@@ -81,7 +81,7 @@ def wildignore_to_regexp(str)
             '\.' + Regexp.escape($~[1]) + '\z'
           elsif pattern.match(%r{\A\*([^/*.][^/*]*)\z})
             # *something (match file with extension without front dot at any level)
-            '[^/]+' +  Regexp.escape($~[1]) + '\z'
+            '(\A|/)' + Regexp.escape($~[1]) + '\z'
           elsif pattern.match(%r{\A\*/([^/]+)/\*\z})
             # */something/* (match directories at any level)
             '(\A|/)' + Regexp.escape($~[1]) + '/.+'

In part for consistency, but also because I think [^/]+ is a bit less precise that the (\A|/) that the other branches use. [^/]+ says "match 1 or more non-slash things" then the rest of the pattern, which means your asking the program to match something without being fully explicit about what that "thing" is; it will work in practice most of the time, I think, but it's still not as direct and literal a translation of your intent as saying "match the pattern at the beginning or after a slash", which is what the other branches do.

wincent commented 4 years ago

Ok, tested it a little bit more and what I said in the last comment isn't quite accurate — it needs to be something more like what I originally suggested (ie. '(\A|/)[^/]+'). Having said that, I think we can go simpler than that. I'll push a commit that explains it.