completion: add a debugpathcomplete command
The bash_completion code uses "hg status" to generate a list of
possible completions for commands that operate on files in the
working directory. In a large working directory, this can result
in a single tab-completion being very slow (several seconds) as a
result of checking the status of every file, even when there is no
need to check status or no possible matches.
The new debugpathcomplete command gains performance in a few simple
ways:
* Allow completion to operate on just a single directory. When used
to complete the right commands, this considerably reduces the
number of completions returned, at no loss in functionality.
* Never check the status of files. For completions that really must
know if a file is modified, it is faster to use status:
hg status -nm 'glob:myprefix**'
Performance:
Here are the commands used by bash_completion to complete, run in
the root of the mozilla-central working dir (~77,000 files) and
another repo (~165,000 files):
All "normal state" files (used by e.g. remove, revert):
mozilla other
status -nmcd 'glob:**' 1.77 4.10 sec
debugpathcomplete -f -n 0.53 1.26
debugpathcomplete -n 0.17 0.41
("-f" means "complete full paths", rather than the current directory)
Tracked files matching "a":
mozilla other
status -nmcd 'glob:a**' 0.26 0.47
debugpathcomplete -f -n a 0.10 0.24
debugpathcomplete -n a 0.10 0.22
We should be able to further improve completion performance once
the critbit work lands. Right now, our performance is limited by
the need to iterate over all keys in the dirstate.
# this is hack to make sure no escape characters are inserted into the output
import os
if 'TERM' in os.environ:
del os.environ['TERM']
import doctest
import mercurial.util
doctest.testmod(mercurial.util)
# Only run doctests for the current platform
doctest.testmod(mercurial.util.platform)
import mercurial.changelog
doctest.testmod(mercurial.changelog)
import mercurial.dagparser
doctest.testmod(mercurial.dagparser, optionflags=doctest.NORMALIZE_WHITESPACE)
import mercurial.match
doctest.testmod(mercurial.match)
import mercurial.store
doctest.testmod(mercurial.store)
import mercurial.ui
doctest.testmod(mercurial.ui)
import mercurial.url
doctest.testmod(mercurial.url)
import mercurial.encoding
doctest.testmod(mercurial.encoding)
import mercurial.hgweb.hgwebdir_mod
doctest.testmod(mercurial.hgweb.hgwebdir_mod)
import hgext.convert.cvsps
doctest.testmod(hgext.convert.cvsps)
import mercurial.revset
doctest.testmod(mercurial.revset)
import mercurial.minirst
doctest.testmod(mercurial.minirst)
import mercurial.templatefilters
doctest.testmod(mercurial.templatefilters)