Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/prompt_toolkit/lexers/base.py: 53%

32 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-04-20 06:09 +0000

1""" 

2Base classes for prompt_toolkit lexers. 

3""" 

4from __future__ import annotations 

5 

6from abc import ABCMeta, abstractmethod 

7from typing import Callable, Hashable 

8 

9from prompt_toolkit.document import Document 

10from prompt_toolkit.formatted_text.base import StyleAndTextTuples 

11 

12__all__ = [ 

13 "Lexer", 

14 "SimpleLexer", 

15 "DynamicLexer", 

16] 

17 

18 

19class Lexer(metaclass=ABCMeta): 

20 """ 

21 Base class for all lexers. 

22 """ 

23 

24 @abstractmethod 

25 def lex_document(self, document: Document) -> Callable[[int], StyleAndTextTuples]: 

26 """ 

27 Takes a :class:`~prompt_toolkit.document.Document` and returns a 

28 callable that takes a line number and returns a list of 

29 ``(style_str, text)`` tuples for that line. 

30 

31 XXX: Note that in the past, this was supposed to return a list 

32 of ``(Token, text)`` tuples, just like a Pygments lexer. 

33 """ 

34 

35 def invalidation_hash(self) -> Hashable: 

36 """ 

37 When this changes, `lex_document` could give a different output. 

38 (Only used for `DynamicLexer`.) 

39 """ 

40 return id(self) 

41 

42 

43class SimpleLexer(Lexer): 

44 """ 

45 Lexer that doesn't do any tokenizing and returns the whole input as one 

46 token. 

47 

48 :param style: The style string for this lexer. 

49 """ 

50 

51 def __init__(self, style: str = "") -> None: 

52 self.style = style 

53 

54 def lex_document(self, document: Document) -> Callable[[int], StyleAndTextTuples]: 

55 lines = document.lines 

56 

57 def get_line(lineno: int) -> StyleAndTextTuples: 

58 "Return the tokens for the given line." 

59 try: 

60 return [(self.style, lines[lineno])] 

61 except IndexError: 

62 return [] 

63 

64 return get_line 

65 

66 

67class DynamicLexer(Lexer): 

68 """ 

69 Lexer class that can dynamically returns any Lexer. 

70 

71 :param get_lexer: Callable that returns a :class:`.Lexer` instance. 

72 """ 

73 

74 def __init__(self, get_lexer: Callable[[], Lexer | None]) -> None: 

75 self.get_lexer = get_lexer 

76 self._dummy = SimpleLexer() 

77 

78 def lex_document(self, document: Document) -> Callable[[int], StyleAndTextTuples]: 

79 lexer = self.get_lexer() or self._dummy 

80 return lexer.lex_document(document) 

81 

82 def invalidation_hash(self) -> Hashable: 

83 lexer = self.get_lexer() or self._dummy 

84 return id(lexer)