17

The Vim Ctrlp plugin has a way to globally ignore certain folder names. Eg:

let g:ctrlp_custom_ignore = '\v[\/]\.(git|hg|svn)$'

However, I have an ignore rule that's specific to one project. I would like something more like a .gitignore file.

Is there a way to ignore a specific folder in a specific project without modifying my global configuration?

1
  • Did you try the plugin's issue tracker?
    – romainl
    Sep 24, 2013 at 20:16

5 Answers 5

20

Use a custom listing command

Ctrlp lets you tell it what command to use to get a list of files in the folder. So if you wanted to exclude anything named beets.txt, you could do:

let g:ctrlp_user_command = 'find %s -type f | grep -v "beets.txt"'

That's global, but it starts to point toward the answer: supply your own shell command.

Even better, Ctrlp lets you supply multiple shell commands with markers, meaning "if you see this marker in the root directory, use this command."

I found this in :help ctrlp, and modified slightly based on the author's comment on an issue.

let g:ctrlp_user_command = {
  \ 'types': {
    \ 1: ['.git', 'cd %s && git ls-files --cached --exclude-standard --others'],
    \ 2: ['.hg', 'hg --cwd %s locate -I .'],
    \ },
  \ 'fallback': 'find %s -type f'
  \ }

This means: "If you see .git in the folder, use git ls-files.... Otherwise, if you see .hg, use hg --cwd..., otherwise use a regular find."

So, to ignore a specific folder in one project, devise a command that will ignore that folder, then place a unique marker in that project to let Ctrlp that you want to use your special command here.

(In my case, I actually wanted to ignore files that were in .gitignore, so the git ls-files command above works for me.)

1
  • git -C %s ls-files --cached --exclude-standard --others should work for git. Nov 29, 2015 at 5:15
11

If you are using the Silver Searcher backend for CtrlP (which is far faster), just add an .agignore file to your project directory in the same format as a .gitignore:

.git/
.hg/
.svn/

Alternatively, keep a global ~/.agignore file.

Add the Silver Searcher as the backend with this in your .vimrc

let g:ctrlp_user_command = 'ag %s -l --nocolor --hidden -g ""'
1
  • 1
    Thanks for posting this. To add another data point: I adapted this if executable("ag") let g:ctrlp_user_command = 'ag %s -l --nocolor --depth 8 -g ""' endif . The depth limit is useful for if I accidentally hit ctrl-p while editing a file in my home folder. I found that the hidden flag would include files in .git/
    – Eric Hu
    Aug 13, 2015 at 23:19
6

Specifies intentionally untracked files in a file

To solve this with a file like .gitignore (based in the Nathan grep solution), I created a file named .ctrlpignore and put the patterns that should be ignored, separated by lines:

node_modules/
\.log$
...

And my ctrlp configuration:

let g:ctrlp_user_command = 'find %s -type f | grep -v "`cat .ctrlpignore`"'

Maybe the .gitignore itself can be used to ignore the files in ctrlp, not needing to create a new file to do almost the same thing.

1
  • I added this snippet but it breaks the overal ctrlp behavior, if I type orderscontroller it finds only _spec files, no actual orders_controller.rb file.
    – jedi
    Sep 21, 2019 at 14:30
1

As Wagner Andrade said, using a seperate .ctrlpignore would be a good idea.

A more robust and convenient vim setting is like this:

let g:ctrlp_user_command = 'cd %s;
  \ commonfilter="\.(jpg|bmp|png|jar|7z|zip|tar|gz|tgz|bz)$";
  \ if [ ! -r ".ctrlpignore" ]; then
  \   find . -type f | grep -Evi "$commonfilter";
  \ else
  \   find . -type f | grep -vF "$(cat .ctrlpignore)" | grep -Evi "$commonfilter";
  \ fi'

.ctrlpignore can be put in any dir that would be recognized as a root dir by ctrlp. Here is an example, every line is starting with ./

vim ~/.ctrlpignore

./Desktop
./R
./.vim
./.local/lib
.....

Note:

  1. grep -F will interpret pattern, ex. './.tmp', as a fixed string if you don't want your './ptmp' be filtered out. There are still some trivial bugs: './.tmp' will also filter out './.tmp2'. Forget it, I don't like \.

  2. g:ctrlp_custom_ignore will be ignored if g:ctrlp_user_command is set. Those could be done in a more complex g:ctrlp_user_command

  3. white-list instead of black-list is also possible. More convenient if implemented in a seperate script

0

Using ag, I was able to setup a system like:

    let g:ctrlp_user_command = '
      \ filter="jpg|bmp|png|jar|7z|zip|tar|gz|tgz|bz";
      \ if [ -f "bsconfig.json" ]; then
      \   subfilter="lib"
      \   filter="$filter|$subfilter"
      \ fi;
      \ if [ -f "Cargo.toml" ]; then
      \   subfilter="target"
      \   filter="$filter|$subfilter"
      \ fi;
      \ if [ -f "elm.json" ]; then
      \   subfilter="elm-stuff"
      \   filter="$filter|$subfilter"
      \ fi;
      \ if [ -f "package.json" ]; then
      \   subfilter="node_modules|*.min.js"
      \   filter="$filter|$subfilter"
      \ fi;
      \ ag %s -l --nocolor -g "" --ignore "\.($filter)$"
      \ '

which allows you to mark certain files to ignore based on files found in the directory you launch vim from. For example, in a JS project with package.json, we want to ignore both node_modules and *.min.js, and so on. This worked well for me because I didn't want to duplicate the same .agignore in every JS project, and I want to support handling multiple patterns, like an Elm and JS project in the same directory.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .