Completed
Push — master ( 2ddb7f...efffd2 )
by Lambda
01:00
created

_delete_entire_text()   A

Complexity

Conditions 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
"""Action module."""
2
from typing import Callable, Optional, Dict, Tuple, Sequence    # noqa: F401
3
from .prompt import Prompt
4
5
ActionCallback = Callable[[Prompt], Optional[int]]
6
ActionRules = Sequence[Tuple[str, ActionCallback]]
7
8
9
class Action:
10
    """Action class which holds action callbacks.
11
12
    Attributes:
13
        registry (dict): An action dictionary.
14
    """
15
16
    __slots__ = ('registry',)
17
18
    def __init__(self) -> None:
19
        """Constructor."""
20
        self.registry = {}  # type: Dict[str, ActionCallback]
21
22
    def register(self, name: str, callback: ActionCallback=None) -> None:
23
        """Register action callback to a specified name.
24
25
        Args:
26
            name (str): An action name which follow {namespace}:{action name}
27
            callback (Callable): An action callback which take a
28
                ``prompt.prompt.Prompt`` instance and return None or int.
29
        """
30
        self.registry[name] = callback
31
32
    def register_from_rules(self, rules: ActionRules) -> None:
33
        """Register action callbacks from rules.
34
35
        Args:
36
            rules (Iterable): An iterator which returns rules. A rule is a
37
                (name, callback) tuple.
38
        """
39
        for rule in rules:
40
            self.register(*rule)
41
42
    def call(self, prompt: Prompt, name: str) -> Optional[int]:
43
        """Call a callback of specified action.
44
45
        Args:
46
            prompt (Prompt): A ``prompt.prompt.Prompt`` instance.
47
            name (str): An action name.
48
49
        Returns:
50
            None or int: None or int which represent the prompt status.
51
        """
52
        if name not in self.registry:
53
            raise AttributeError(
54
                'No action "%s" has registered.' % name
55
            )
56
        fn = self.registry[name]
57
        return fn(prompt)
58
59
    @classmethod
60
    def from_rules(cls, rules: ActionRules) -> 'Action':
61
        """Create a new action instance from rules.
62
63
        Args:
64
            rules (Iterable): An iterator which returns rules. A rule is a
65
                (name, callback) tuple.
66
67
        Returns:
68
            Action: An action instance.
69
        """
70
        action = cls()
71
        action.register_from_rules(rules)
72
        return action
73
74
75
# Default actions -------------------------------------------------------------
76
def _accept(prompt):
77
    from .prompt import STATUS_ACCEPT
78
    return STATUS_ACCEPT
79
80
81
def _cancel(prompt):
82
    from .prompt import STATUS_CANCEL
83
    return STATUS_CANCEL
84
85
86
def _toggle_insert_mode(prompt):
87
    from .prompt import MODE_INSERT, MODE_REPLACE
88
    if prompt.mode == MODE_INSERT:
89
        prompt.mode = MODE_REPLACE
90
    else:
91
        prompt.mode = MODE_INSERT
92
93
94
def _delete_char_before_caret(prompt):
95
    if prompt.caret.locus == 0:
96
        return
97
    prompt.context.text = ''.join([
98
        prompt.caret.get_backward_text()[:-1],
99
        prompt.caret.get_selected_text(),
100
        prompt.caret.get_forward_text(),
101
    ])
102
    prompt.caret.locus -= 1
103
104
105
def _delete_char_under_caret(prompt):
106
    prompt.context.text = ''.join([
107
        prompt.caret.get_backward_text(),
108
        prompt.caret.get_forward_text(),
109
    ])
110
111
112
def _delete_text_after_caret(prompt):
113
    prompt.context.text = prompt.caret.get_backward_text()
114
    prompt.caret.locus = prompt.caret.tail
115
116
117
def _delete_entire_text(prompt):
118
    prompt.context.text = ''
119
    prompt.caret.locus = prompt.caret.tail
120
121
122
def _move_caret_to_left(prompt):
123
    prompt.caret.locus -= 1
124
125
126
def _move_caret_to_right(prompt):
127
    prompt.caret.locus += 1
128
129
130
def _move_caret_to_head(prompt):
131
    prompt.caret.locus = prompt.caret.head
132
133
134
def _move_caret_to_lead(prompt):
135
    prompt.caret.locus = prompt.caret.lead
136
137
138
def _move_caret_to_tail(prompt):
139
    prompt.caret.locus = prompt.caret.tail
140
141
142
def _assign_previous_text(prompt):
143
    prompt.text = prompt.history.previous()
144
145
146
def _assign_next_text(prompt):
147
    prompt.text = prompt.history.next()
148
149
150
def _assign_previous_matched_text(prompt):
151
    prompt.text = prompt.history.previous_match()
152
153
154
def _assign_next_matched_text(prompt):
155
    prompt.text = prompt.history.next_match()
156
157
158
def _paste_from_register(prompt):
159
    prompt.nvim.command(r'echon "\""')
160
    reg = prompt.nvim.eval('nr2char(getchar())')
161
    val = prompt.nvim.call('getreg', reg)
162
    prompt.update_text(val)
163
164
165
def _paste_from_default_register(prompt):
166
    val = prompt.nvim.call('getreg', prompt.nvim.vvars['register'])
167
    prompt.update_text(val)
168
169
170
def _yank_to_register(prompt):
171
    prompt.nvim.command(r'echon "\""')
172
    reg = prompt.nvim.eval('nr2char(getchar())')
173
    prompt.nvim.call('setreg', reg, prompt.text)
174
175
176
def _yank_to_default_register(prompt):
177
    prompt.nvim.call('setreg', prompt.nvim.vvars['register'], prompt.text)
178
179
180
DEFAULT_ACTION = Action.from_rules([
181
    ('prompt:accept', _accept),
182
    ('prompt:cancel', _cancel),
183
    ('prompt:toggle_insert_mode', _toggle_insert_mode),
184
    ('prompt:delete_char_before_caret', _delete_char_before_caret),
185
    ('prompt:delete_char_under_caret', _delete_char_under_caret),
186
    ('prompt:delete_text_after_caret', _delete_text_after_caret),
187
    ('prompt:delete_entire_text', _delete_entire_text),
188
    ('prompt:move_caret_to_left', _move_caret_to_left),
189
    ('prompt:move_caret_to_right', _move_caret_to_right),
190
    ('prompt:move_caret_to_head', _move_caret_to_head),
191
    ('prompt:move_caret_to_lead', _move_caret_to_lead),
192
    ('prompt:move_caret_to_tail', _move_caret_to_tail),
193
    ('prompt:assign_previous_text', _assign_previous_text),
194
    ('prompt:assign_next_text', _assign_next_text),
195
    ('prompt:assign_previous_matched_text', _assign_previous_matched_text),
196
    ('prompt:assign_next_matched_text', _assign_next_matched_text),
197
    ('prompt:paste_from_register', _paste_from_register),
198
    ('prompt:paste_from_default_register', _paste_from_default_register),
199
    ('prompt:yank_to_register', _yank_to_register),
200
    ('prompt:yank_to_default_register', _yank_to_default_register),
201
])
202