Shellmen/src/libs/prompt_toolkit/contrib/regular_languages/validation.py

58 lines
2.0 KiB
Python

"""
Validator for a regular langage.
"""
from __future__ import unicode_literals
from prompt_toolkit.validation import Validator, ValidationError
from prompt_toolkit.document import Document
from .compiler import _CompiledGrammar
__all__ = (
'GrammarValidator',
)
class GrammarValidator(Validator):
"""
Validator which can be used for validation according to variables in
the grammar. Each variable can have its own validator.
:param compiled_grammar: `GrammarCompleter` instance.
:param validators: `dict` mapping variable names of the grammar to the
`Validator` instances to be used for each variable.
"""
def __init__(self, compiled_grammar, validators):
assert isinstance(compiled_grammar, _CompiledGrammar)
assert isinstance(validators, dict)
self.compiled_grammar = compiled_grammar
self.validators = validators
def validate(self, document):
# Parse input document.
# We use `match`, not `match_prefix`, because for validation, we want
# the actual, unambiguous interpretation of the input.
m = self.compiled_grammar.match(document.text)
if m:
for v in m.variables():
validator = self.validators.get(v.varname)
if validator:
# Unescape text.
unwrapped_text = self.compiled_grammar.unescape(v.varname, v.value)
# Create a document, for the completions API (text/cursor_position)
inner_document = Document(unwrapped_text, len(unwrapped_text))
try:
validator.validate(inner_document)
except ValidationError as e:
raise ValidationError(
cursor_position=v.start + e.cursor_position,
message=e.message)
else:
raise ValidationError(cursor_position=len(document.text),
message='Invalid command')