Commit 58b55c35 authored by Satwik Kansal's avatar Satwik Kansal Committed by Satwik Kansal

FilePathCompleter: Implement autocompletion

Adds a class named `FilePathCompleter` which can
be used to suggest and autocomplete paths according
to the globs entered by the user in CLI via the ``input``
method.

Closes #38
parent b808a923
Pipeline #11004656 passed with stages
in 2 minutes and 49 seconds
import glob
import os
import readline
def path_completer(text, state):
"""
Completer method for system paths.
"""
return [x if os.path.isfile(x) else (x + os.sep)
for x in glob.glob(text + '*')][state]
class FilePathCompleter:
"""
Provides tab completion for the filesystem paths.
"""
def __init__(self,
delimiters=', \t\n\\',
bind_keys=['tab'],
completion_method=path_completer):
"""
:param delimiters:
String containing the delimiters for the user input.
:bind_keys:
list of keys that would trigger the completion.
:completion_method:
function to be used for suggesting values for completion
based on the input text.
"""
self.delimiters = delimiters
self.bind_keys = bind_keys
self.completion_method = completion_method
def activate(self, seed_dir=os.getcwd()):
"""
:param seed_dir:
The initial directory path relative to which all the
filepaths will be suggested and completed.
"""
readline.set_completer_delims(self.delimiters)
self.initial_dir = os.getcwd()
os.chdir(seed_dir)
for key in self.bind_keys:
readline.parse_and_bind("{}: complete".format(key))
readline.set_completer(self.completion_method)
def deactivate(self):
for key in self.bind_keys:
readline.parse_and_bind("{}: self-insert".format(key))
readline.set_completer()
os.chdir(self.initial_dir)
import os
import readline
import shutil
import unittest
from coala_utils.FilePathCompleter import (
path_completer, FilePathCompleter)
from coala_utils.ContextManagers import (
retrieve_stdout, simulate_console_inputs)
class FilePathCompleterTest(unittest.TestCase):
def setUp(self):
os.makedirs("test_dir", exist_ok=True)
touch(os.path.join("test_dir", "a_file"))
touch(os.path.join("test_dir", "b_file"))
touch("c_file")
self.fpc = FilePathCompleter()
self.directory = os.getcwd()
def assert_expected_output(self, user_input, expected_output):
state = 0
try:
while True:
self.assertEqual(expected_output[state],
path_completer(user_input, state))
state += 1
except IndexError:
self.assertEqual(state, len(expected_output))
def test_path_completer(self):
self.fpc.activate()
self.assertEqual(readline.get_completer(), path_completer)
self.assert_expected_output("test_d", ['test_dir' + os.sep])
self.assert_expected_output(
"test_dir" + os.sep, [os.path.join("test_dir", "a_file"),
os.path.join("test_dir", "b_file")])
self.assert_expected_output(
os.path.join("test_dir", "a"), [os.path.join("test_dir", "a_file")])
self.assert_expected_output("c_fi", ["c_file"])
self.fpc.deactivate()
self.assertEqual(readline.get_completer(), None)
def tearDown(self):
shutil.rmtree("test_dir")
os.remove("c_file")
def touch(fpath):
try:
os.utime(fpath, None)
except OSError:
open(fpath, 'a').close()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment