mirror of
https://github.com/certbot/certbot.git
synced 2026-08-03 03:41:53 +02:00
Added completer.py and tests for FileDisplay
This commit is contained in:
@@ -0,0 +1,51 @@
|
|||||||
|
"""Provides tab autocompletion when prompting users for a path."""
|
||||||
|
import glob
|
||||||
|
import readline
|
||||||
|
|
||||||
|
|
||||||
|
class Completer(object):
|
||||||
|
"""Provides tab autocompletion when prompting users for a path.
|
||||||
|
|
||||||
|
This class is meant to be used with readline to provide tab
|
||||||
|
autocompletion for users entering paths. The complete method can
|
||||||
|
be passed to readline.set_completer directly, however, this function
|
||||||
|
works best as a context manager. For example:
|
||||||
|
|
||||||
|
with Completer():
|
||||||
|
raw_input()
|
||||||
|
|
||||||
|
In this example, tab autocompletion will be available during
|
||||||
|
the call to raw_input above, however, readline will be restored to
|
||||||
|
its previous state when exiting the body of the with statement.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self._completer = self._delims = self._iter = None
|
||||||
|
|
||||||
|
def complete(self, text, state):
|
||||||
|
"""Provides path autocompletion for use with readline.
|
||||||
|
|
||||||
|
:param str text: text to offer completions for
|
||||||
|
:param int state: which completion to return
|
||||||
|
|
||||||
|
:returns: possible completion for text or ``None`` if all
|
||||||
|
completions have been returned
|
||||||
|
:rtype: str
|
||||||
|
|
||||||
|
"""
|
||||||
|
if state == 0:
|
||||||
|
self._iter = glob.iglob(text + '*')
|
||||||
|
return next(self._iter, None)
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
self._completer = readline.get_completer()
|
||||||
|
self._delims = readline.get_completer_delims()
|
||||||
|
|
||||||
|
readline.set_completer(self.complete)
|
||||||
|
readline.set_completer_delims(' \t\n;')
|
||||||
|
readline.parse_and_bind('tab: complete')
|
||||||
|
|
||||||
|
def __exit__(self, unused_type, unused_value, unused_traceback):
|
||||||
|
readline.set_completer_delims(self._delims)
|
||||||
|
readline.set_completer(self._completer)
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
"""Test letsencrypt.display.completer."""
|
||||||
|
import os
|
||||||
|
import readline
|
||||||
|
import shutil
|
||||||
|
import string
|
||||||
|
import tempfile
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
|
||||||
|
class CompleterTest(unittest.TestCase):
|
||||||
|
"""Test letsencrypt.display.completer.Completer."""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.temp_dir = tempfile.mkdtemp()
|
||||||
|
|
||||||
|
# directories must end with os.sep for completer to
|
||||||
|
# search inside the directory for possible completions
|
||||||
|
if self.temp_dir[-1] != os.sep:
|
||||||
|
self.temp_dir += os.sep
|
||||||
|
|
||||||
|
self.paths = []
|
||||||
|
# create some files and directories in temp_dir
|
||||||
|
for c in string.ascii_lowercase:
|
||||||
|
path = os.path.join(self.temp_dir, c)
|
||||||
|
self.paths.append(path)
|
||||||
|
if ord(c) % 2:
|
||||||
|
os.mkdir(path)
|
||||||
|
else:
|
||||||
|
with open(path, 'w'):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
shutil.rmtree(self.temp_dir)
|
||||||
|
|
||||||
|
def test_context_manager(self):
|
||||||
|
from letsencrypt.display import completer
|
||||||
|
|
||||||
|
original_completer = readline.get_completer()
|
||||||
|
original_delims = readline.get_completer_delims()
|
||||||
|
|
||||||
|
with completer.Completer():
|
||||||
|
pass
|
||||||
|
|
||||||
|
self.assertEqual(readline.get_completer(), original_completer)
|
||||||
|
self.assertEqual(readline.get_completer_delims(), original_delims)
|
||||||
|
|
||||||
|
def test_complete(self):
|
||||||
|
from letsencrypt.display import completer
|
||||||
|
|
||||||
|
my_completer = completer.Completer()
|
||||||
|
num_paths = len(self.paths)
|
||||||
|
|
||||||
|
for i in range(num_paths):
|
||||||
|
completion = my_completer.complete(self.temp_dir, i)
|
||||||
|
self.assertTrue(completion in self.paths)
|
||||||
|
self.paths.remove(completion)
|
||||||
|
|
||||||
|
self.assertFalse(self.paths)
|
||||||
|
completion = my_completer.complete(self.temp_dir, num_paths)
|
||||||
|
self.assertEqual(completion, None)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main() # pragma: no cover
|
||||||
Reference in New Issue
Block a user