I'm working with large number of files, which I keep in a directory. Every time I go in to that directory and accidentally press Tab twice, it takes too long (may be over a minutes) to show files that match the pattern, and I'm quite annoyed with this behavior.
For example, my directory structure is:
my-project/
├── docs/
├── data/ <---- contains around 200k files.
└── analyser/
Since I still love completion, is there anyway to disable this feature only at the data/
directory? Like set timeout for 5 sec, or a script that automatically switch off completion when inside specific directory?
Best Answer
This isn't perfect, but then again bash completion is quite a tricky thing...
The very simplest way is on a per-command basis, it's slightly more flexible than
FIGNORE
, you can do:This instructs autocomplete that completion for
vi
is for files, and to remove patterns matching the-X
filter. The downside is that the pattern isn't normalised, so../data
and variations won't match.The next best thing might be a custom
PROMPT_COMMAND
function:This disables completion (completely) when you are in the directory, but it disables it for every path not just files in that directory.
It would be more generally useful to selectively disable this for defined paths, but I believe the only way is to use a default completion function (bash-4.1 and later with
complete -D
) and a lot of messing about.This should work for you, but it may have unintended side effects (i.e. changes to the expected completion in some cases):
This works for completion of
vi
, other commands can be added as needed. It should stop completion for files in the named directories regardless of path or working directory.I believe the general approach with
complete -D
is to dynamically add completion functions for each command as it is encountered. One might also need to addcomplete -E
(completion of command name when input buffer is empty).Update Here's a hybrid version of the
PROMPT_COMMAND
and completion function solutions, it's a little easier to understand and hack I think:This prompt function sets the
nocomplete
variable when you enter one of the configured directories. The modified completion behaviour only kicks in when that variable is non-blank and only when you try completing from an empty string, thus allowing completion of partial names (remove the-z "$cur"
condition to prevent completion altogether). Comment out the twoprintf
lines for silent operation.Other options include a per-directory
.noautocomplete
flag file that you cantouch
in a directory as needed; and guessing of directory size using GNUstat
. You can use any or all of those three options.(The
stat
method is only a guess, the reported directory size grows with its contents, it's a "high water mark" that won't usually shrink when files are deleted without some administrative intervention. It's cheaper than determining the real contents of a potentially large directory. Precise behaviour and increment per file depends on underlying filesystem. I find it a reliable indicator on linux ext2/3/4 systems at least.)bash adds an extra space even when an empty completion is returned (this only occurs when completing at the end of a line). You can add
-o nospace
to thecomplete
command to prevent this.One remaining niggle is that if you back up the cursor to the start of a token and hit tab, the default completion will kick in again. Consider it a feature ;-)
(Or you could futz around with
${COMP_LINE:$COMP_POINT-1:1}
if you like over-engineering, but I find bash itself fails to set the completion variables reliably when you back up and attempt completion in the middle of a command.)