In my python project root folder, there are multiple directories, some of which contain hidden sub-directories specifying python virtual environments. I want to open all my python files recursively from the root directory except the ones that lie along any path containing a hidden folder. This is because I don't want to load any virtual environment specific python files as there are thousands of them - I only want to load my project's python files.

I tried running :n [^.]**/*.py but it doesn't work, it still opens all python files.

I also tried reading about the ** wildcard in the docs, but I couldn't find how to make it match folders whose name matches a specific pattern (namely not starting with a .).

  • As pointed out by @D Ben Knobole, Maybe you need a fuzzy file opener like fzf.vim or leaderf. Better, use language server protocol and navigate your code easily. I am sure you do not need to open all your project files.
    – jdhao
    Commented Nov 17, 2020 at 7:36

1 Answer 1


Vim paths in that context are more like shell-globs than regular-expressions.

A simple solution in a *nix shell would be

$ vim **/*.py

(This needs extglob in bash, I think, but should work out of the box in zsh.)

Inside of vim, I'm surprised it would match hidden files in the first place, though :help wildcard is clear that it matches "anything."

If you can narrow down the patter, that might help (e.g., src/**/*.py).

Otherwise, you could use a more complex command:

:next `find . -not -path .env -name '*.py'`
:next `git ls-files '*.py'`


You could create a mapping, if you like:

nnoremap <keys> :next `find . -not -path '*/.*' -type f -name '*.'`<Left><Left>


These commands can become quite complex, depending on what you're doing, so I won't show all the variations here.

I'll just note as an addendum that I don't generally open all my project files at once; I focus on one or two, and sometimes over a long session (or over a persistent ) lots of files accumulate.

It can be handy to add lots of things to the arglist, however, to allow :argdo or :vimgrep /.../ ##. Depending on the case, using the quickfix (combined with :grep or similar) and :cdo/:Cfilter, etc., can be more useful/less invasive/easier to setup.

@filbranden points out wildignore, which you could probably set to include .* to avoid matching hidden things.

In all honesty, though, I can't really reproduce the issue. In a directory like this:

├── .env
│   ├── a.py
│   ├── b.py
│   └── c.py
├── a.py
├── b.py
└── c.py

1 directory, 6 files

Running vim -u NONE --noplugin --clean, I have

:next **/*.py
[a.py] b.py c.py
  • On zsh vim **/*.py doesn't ignore hidden files actually. The next command works, but I need to tweak it a bit to not include any hidden folder automatically (without specifying the name). I didn't know it can be paired with the find command. I'll make this modification and edit and accept your answer when I get the chance. Thanks!
    – WalksB
    Commented Nov 16, 2020 at 20:07
  • 1
    @ZaidGharaybeh it does for me in zsh; could be different options or something.
    – D. Ben Knoble
    Commented Nov 16, 2020 at 20:08
  • @ZaidGharaybeh See :help 'wildignore'
    – filbranden
    Commented Nov 16, 2020 at 23:25
  • @ZaidGharaybeh I rejected your edit only because I felt you substantially modified some of the points I was making. I did try to include some of your points, though; if you feel you need to expound further on what exactly your solution was, you can write another answer. Edits are generally for improvement, and while I agree that some of your changes improved the post, others did not (IMO).
    – D. Ben Knoble
    Commented Nov 17, 2020 at 14:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.