wincent / command-t

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

Sometimes particular files aren't shown in CommandT open file popup #167

Closed daniel-abramov closed 9 years ago

daniel-abramov commented 9 years ago

I don't know why, but sometimes some particular files are not displayed at Command-T open file popup. I don't have any ideas why, I've got this bug twice. About a month ago the whole directory was not shown at Command-T popup, I had to delete it and create new directory for that purpose. At the moment 2 files (C++ header and corresponding .cpp file) are not displayed inside Command-T popup.

I tried different Command-T options, different parameters but it still cannot fix the problem.

Is there any way to fix or debug that? Can I place any additional logs in Command-T sources?

My Command-T configuration:

let g:CommandTMaxHeight = 30
let g:CommandTMatchWindowReverse = 1 " shows results in reverse order
let g:CommandTFileScanner = 'find'
let g:CommandTTraverseSCM = 'pwd'
set wildignore+=*.o,*.obj,.git,*.pyc,*.so,blaze*,READONLY,llvm,Library*
set wildignore+=CMakeFiles,packages/*,**/packages/*,**/node_modules/*
let g:CommandTWildIgnore=&wildignore

Thanks.

wincent commented 9 years ago

Thanks for the report.

There are a bunch of reasons why stuff might not show up in Command-T, but I am not aware of any bugs right now. Possible reasons:

As to your question about debugging, it's tricky. The Command-T UI is built up by (ab)using Vim's display in creative ways (ie. a buffer for the match listing, and using the command line as a "prompt" area). This limits the possibilities for displaying additional information (you can't really print anything to the screen without disrupting the UI). Additionally, Command-T is all about speed, so I don't want to clog it up with debugging code; as such, the only way to really know what's going on inside it is to hack the source code and add some logging statements of your own. When I need to do this, I use some ghastly Ruby snippet like: File.open('/tmp/command-t-debug.log', 'a') { |f| f.puts 'my debugging info here' }.

daniel-abramov commented 9 years ago

The number of files in the tree is greater than g:CommandTMaxFiles (this setting applies to all scanners except the Watchman scanner).

I'm 100% sure that it's not my case. I have only ~100 files here.

There is s circular path (due to a bad symlink) that causes the max file limit to get hit even though the actual number of files in the hierarchy is less.

Same as previous (not my case).

If you're using the Git-based file scanner, the files you're looking for are not tracked in the repo.

I use 'find' as a file scanner.

The files were added after Command-T has scanned (and cached) the file system; to flush the cache you can run :CommandTFlush or just hit from inside the match listing itself.

I tried to restart vim, terminals etc., but the bug is still present.

The 'wildignore' settings may be misconfigured; this can be subtle and the behavior does vary depending on the scanner you're using, so see :h command-t-wildignore for an explanation.

I've read the documentation but my file name is ok, it doesn't match any wildignore pattern.

The g:CommandTTraverseSCM setting can lead you to search in a directory other than the one you might think you're searching (probably not the case for you, because you're using 'pwd', which is the simplest and most predictable setting, involving no actual traversal; see :h

Command-T finds other files which are placed in the same directory. Interesting thing, it doesn't see both header and cpp file. Header file is named something like "CRtmpPoint.h", while cpp file has name "api_CRtmpPoint.cpp", they are placed in 2 different directories (header is placed inside "include" directory, cpp file inside "src" directory).

As to your question about debugging, it's tricky. The Command-T UI is built up by (ab)using Vim's display in creative ways (ie. a buffer for the match listing, and using the command line as a "prompt" area). This limits the possibilities for displaying additional information (you can't really print anything to the screen without disrupting the UI). Additionally, Command-T is all about speed, so I don't want to clog it up with debugging code; as such, the only way to really know what's going on inside it is to hack the source code and add some logging statements of your own. When I need to do this, I use some ghastly Ruby snippet like: File.open('/tmp/command-t-debug.log', 'a') { |f| f.puts 'my debugging info here' }.

Yeah, I understand that the source code should not contain any redundant logs. I'm thinking about using additional logs only for debugging purposes. After I find a bug, I will be able to fix it and commit it to the repository (without my debugging logs).

Anyway, thanks for your suggestions about logging.

wincent commented 9 years ago

Another thing I forgot to mention: searches may be case sensitive, if you use at least one uppercase character in you search (and you have 'smartcase' turned on).

Can you provide any more details, like the output of tree or find . as well as the exact search string, especially if you can repro this reliably?

On Wed, Jul 15, 2015 at 11:31 AM Daniel Abramov notifications@github.com wrote:

The number of files in the tree is greater than g:CommandTMaxFiles (this setting applies to all scanners except the Watchman scanner).

I'm 100% sure that it's not my case. I have only ~100 files here.

There is s circular path (due to a bad symlink) that causes the max file limit to get hit even though the actual number of files in the hierarchy is less.

Same as previous (not my case).

If you're using the Git-based file scanner, the files you're looking for are not tracked in the repo.

I use 'find' as a file scanner.

The files were added after Command-T has scanned (and cached) the file system; to flush the cache you can run :CommandTFlush or just hit from inside the match listing itself.

I tried to restart vim, terminals etc., but the bug is still present.

The 'wildignore' settings may be misconfigured; this can be subtle and the behavior does vary depending on the scanner you're using, so see :h command-t-wildignore for an explanation.

I've read the documentation but my file name is ok, it doesn't match any wildignore pattern.

The g:CommandTTraverseSCM setting can lead you to search in a directory other than the one you might think you're searching (probably not the case for you, because you're using 'pwd', which is the simplest and most predictable setting, involving no actual traversal; see :h

Command-T finds other files which are placed in the same directory. Interesting thing, it doesn't see both header and cpp file. Header file is named something like "CRtmpPoint.h", while cpp file has name "api_CRtmpPoint.cpp", they are placed in 2 different directories (header is placed inside "include" directory, cpp file inside "src" directory).

As to your question about debugging, it's tricky. The Command-T UI is built up by (ab)using Vim's display in creative ways (ie. a buffer for the match listing, and using the command line as a "prompt" area). This limits the possibilities for displaying additional information (you can't really print anything to the screen without disrupting the UI). Additionally, Command-T is all about speed, so I don't want to clog it up with debugging code; as such, the only way to really know what's going on inside it is to hack the source code and add some logging statements of your own. When I need to do this, I use some ghastly Ruby snippet like: File.open('/tmp/command-t-debug.log', 'a') { |f| f.puts 'my debugging info here' }.

Yeah, I understand that the source code should not contain any redundant logs. I'm thinking about using additional logs only for debugging purposes. After I find a bug, I will be able to fix it and commit it to the repository (without my debugging logs).

Anyway, thanks for your suggestions about logging.

— Reply to this email directly or view it on GitHub https://github.com/wincent/command-t/issues/167#issuecomment-121705800.

daniel-abramov commented 9 years ago

Another thing I forgot to mention: searches may be case sensitive, if you use at least one uppercase character in you search (and you have 'smartcase' turned on).

I tried both variants, neither of them worked.

Can you provide any more details, like the output of tree or find . as well as the exact search string, especially if you can repro this reliably?

Sure.

developer@arch-desktop > Development > libs > api $ tree
.
├── include
│   └── api
│       ├── CBroadcast.h
│       ├── CClient.h
│       ├── CApi.h
│       ├── CRtmpPoint.h
│       └── CConfig.h
└── src
    ├── api_CClient.cpp
    ├── api_CRtmpPoint.cpp
    └── Makefile
wincent commented 9 years ago

What's the output of set wildignore? for you? (Wondering if you've got something "tmp" in there which is causing those to be filtered out.)

daniel-abramov commented 9 years ago
wildignore=*/tmp/*,*.so,*.swp,*.zip,*\tmp\*,*.swp,*.zip,*.exe,*.o,*.obj,.git,*.pyc,*.so,blaze*,READONLY,llvm,Library*,CMakeFiles,packages/*,**/packages/*,**/node_modules/*
wincent commented 9 years ago

I'm able to repro this with:

let g:CommandTWildIgnore='*\tmp\*'

Because *\tmp\* expands to *tmp*. If you:echo g:CommandTWildIgnore, you'll see it in its expanded form (ie. *tmp*):

*/tmp/*,*.so,*.swp,*.zip,*tmp*,*.swp,*.zip,*.exe,*.o,*.obj,.git,*.pyc,*.so,blaze*,READONLY,llvm,Library*,CMakeFiles,packages/*,**/packages/*,**/node_modules/*

Simpler example:

:set wildignore=*.zip,*\tmp\*,*.swp
:echo &wildignore " *.zip,*tmp*,*.swp
:set wildignore? " wildignore=*.zip,*tmp*,*.swp

I'm not sure what you're trying to achieve with the *\tmp\* entry. Can you change your 'wildignore' config to use something like */tmp/* instead? I don't seem to be able to escape the backslashes either.

daniel-abramov commented 9 years ago

Sorry for the long response.

Thank you for the explanations, they helped and actually fixed the problem. I used \tmp\ for Windows-like paths, but probably I should find a better solution for such pattern on Windows.

I believe that those rules caused the problem:

set wildignore+=*/tmp/*,*.so,*.swp,*.zip     " MacOSX/Linux
set wildignore+=*\\tmp\\*,*.swp,*.zip,*.exe  " Windows

Command-T somehow appended wildignore contents to CommandTWildIgnore.

Anyway, thanks for your help.

Should we close the issue?

wincent commented 9 years ago

Command-T somehow appended wildignore contents to CommandTWildIgnore.

g:CommandTWildignore was being set to the value of 'wildignore' due to this line in your config:

let g:CommandTWildIgnore=&wildignore

BTW, you could consider gating your Windows-specific config with an if:

if has("win32")
  set wildignore+=*\\tmp\\*,*.swp,*.zip,*.exe
endif

Should we close the issue?

Yep, let's do it.