Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/prompt_toolkit/key_binding/vi_state.py: 45%

49 statements  

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

1from __future__ import annotations 

2 

3from enum import Enum 

4from typing import TYPE_CHECKING, Callable 

5 

6from prompt_toolkit.clipboard import ClipboardData 

7 

8if TYPE_CHECKING: 

9 from .key_bindings.vi import TextObject 

10 from .key_processor import KeyPressEvent 

11 

12__all__ = [ 

13 "InputMode", 

14 "CharacterFind", 

15 "ViState", 

16] 

17 

18 

19class InputMode(str, Enum): 

20 value: str 

21 

22 INSERT = "vi-insert" 

23 INSERT_MULTIPLE = "vi-insert-multiple" 

24 NAVIGATION = "vi-navigation" # Normal mode. 

25 REPLACE = "vi-replace" 

26 REPLACE_SINGLE = "vi-replace-single" 

27 

28 

29class CharacterFind: 

30 def __init__(self, character: str, backwards: bool = False) -> None: 

31 self.character = character 

32 self.backwards = backwards 

33 

34 

35class ViState: 

36 """ 

37 Mutable class to hold the state of the Vi navigation. 

38 """ 

39 

40 def __init__(self) -> None: 

41 #: None or CharacterFind instance. (This is used to repeat the last 

42 #: search in Vi mode, by pressing the 'n' or 'N' in navigation mode.) 

43 self.last_character_find: CharacterFind | None = None 

44 

45 # When an operator is given and we are waiting for text object, 

46 # -- e.g. in the case of 'dw', after the 'd' --, an operator callback 

47 # is set here. 

48 self.operator_func: None | (Callable[[KeyPressEvent, TextObject], None]) = None 

49 self.operator_arg: int | None = None 

50 

51 #: Named registers. Maps register name (e.g. 'a') to 

52 #: :class:`ClipboardData` instances. 

53 self.named_registers: dict[str, ClipboardData] = {} 

54 

55 #: The Vi mode we're currently in to. 

56 self.__input_mode = InputMode.INSERT 

57 

58 #: Waiting for digraph. 

59 self.waiting_for_digraph = False 

60 self.digraph_symbol1: str | None = None # (None or a symbol.) 

61 

62 #: When true, make ~ act as an operator. 

63 self.tilde_operator = False 

64 

65 #: Register in which we are recording a macro. 

66 #: `None` when not recording anything. 

67 # Note that the recording is only stored in the register after the 

68 # recording is stopped. So we record in a separate `current_recording` 

69 # variable. 

70 self.recording_register: str | None = None 

71 self.current_recording: str = "" 

72 

73 # Temporary navigation (normal) mode. 

74 # This happens when control-o has been pressed in insert or replace 

75 # mode. The user can now do one navigation action and we'll return back 

76 # to insert/replace. 

77 self.temporary_navigation_mode = False 

78 

79 @property 

80 def input_mode(self) -> InputMode: 

81 "Get `InputMode`." 

82 return self.__input_mode 

83 

84 @input_mode.setter 

85 def input_mode(self, value: InputMode) -> None: 

86 "Set `InputMode`." 

87 if value == InputMode.NAVIGATION: 

88 self.waiting_for_digraph = False 

89 self.operator_func = None 

90 self.operator_arg = None 

91 

92 self.__input_mode = value 

93 

94 def reset(self) -> None: 

95 """ 

96 Reset state, go back to the given mode. INSERT by default. 

97 """ 

98 # Go back to insert mode. 

99 self.input_mode = InputMode.INSERT 

100 

101 self.waiting_for_digraph = False 

102 self.operator_func = None 

103 self.operator_arg = None 

104 

105 # Reset recording state. 

106 self.recording_register = None 

107 self.current_recording = ""