Completed
Push — master ( 82760b...c05ef7 )
by Lambda
02:32
created

History.previous()   A

Complexity

Conditions 3

Size

Total Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
dl 0
loc 21
rs 9.3142
c 0
b 0
f 0
1
"""Command-line history module."""
2
import weakref
3
from neovim import Nvim
4
from .prompt import Prompt
5
6
7
class History:
8
    """History class which manage a Vim's command-line history for input."""
9
10
    __slots__ = ('prompt', '_index', '_cached', '_backward', '_threshold')
11
12
    def __init__(self, prompt: Prompt) -> None:
13
        """Constructor.
14
15
        Args:
16
            prompt (Prompt): The ``prompt.prompt.Prompt`` instance. The
17
                instance is used to initialize internal variables and never
18
                stored.
19
        """
20
        self.prompt = weakref.proxy(prompt)
21
        self._index = 0
22
        self._cached = prompt.text
23
        self._backward = prompt.caret.get_backward_text()
24
        self._threshold = 0
25
26
    @property
27
    def nvim(self) -> Nvim:
28
        """A ``neovim.Nvim`` instance."""
29
        return self.prompt.nvim
30
31
    def current(self) -> str:
32
        """Current command-line history value of input.
33
34
        Returns:
35
            str: A current command-line history value of input which an
36
                internal index points to. It returns a cached value when the
37
                internal index points to 0.
38
        """
39
        if self._index == 0:
40
            return self._cached
41
        return self.nvim.call('histget', 'input', -self._index)
42
43
    def previous(self) -> str:
44
        """Get previous command-line history value of input.
45
46
        It increases an internal index and points to a previous command-line
47
        history value.
48
49
        Note that it cahces a ``prompt.text`` when the internal index was 0 (an
50
        initial value) and the cached value is used when the internal index
51
        points to 0.
52
        This behaviour is to mimic a Vim's builtin command-line history
53
        behaviour.
54
55
        Returns:
56
            str: A previous command-line history value of input.
57
        """
58
        if self._index == 0:
59
            self._cached = self.prompt.text
60
            self._threshold = self.nvim.call('histnr', 'input')
61
        if self._index < self._threshold:
62
            self._index += 1
63
        return self.current()
64
65
    def next(self) -> str:
66
        """Get next command-line history value of input.
67
68
        It decreases an internal index and points to a next command-line
69
        history value.
70
71
        Returns:
72
            str: A next command-line history value of input.
73
        """
74
        if self._index == 0:
75
            self._cached = self.prompt.text
76
            self._threshold = self.nvim.call('histnr', 'input')
77
        if self._index > 0:
78
            self._index -= 1
79
        return self.current()
80
81
    def previous_match(self) -> str:
82
        """
83
        Get previous matched command-line history value of input.
84
85
        The initial query text is a text before the cursor when an internal
86
        index was 0 (like a cached value but only before the cursor.)
87
        It increases an internal index until a previous command-line history
88
        value matches to an initial query text and points to the matched
89
        previous history value.
90
        This behaviour is to mimic a Vim's builtin command-line history
91
        behaviour.
92
93
        Returns:
94
            str: A matched previous command-line history value of input.
95
        """
96
        if self._index == 0:
97
            self._backward = self.prompt.caret.get_backward_text()
98
        index = _index = self._index - 1
99
        while _index < self._index:
100
            _index = self._index
101
            candidate = self.previous()
102
            if candidate.startswith(self._backward):
103
                return candidate
104
        self._index = index
105
        return self.previous()
106
107
    def next_match(self) -> str:
108
        """Get next matched command-line history value of input.
109
110
        The initial query text is a text before the cursor when an internal
111
        index was 0 (like a cached value but only before the cursor.)
112
        It decreases an internal index until a next command-line history value
113
        matches to an initial query text and points to the matched next
114
        command-line history value.
115
        This behaviour is to mimic a Vim's builtin command-line history
116
        behaviour.
117
118
        Returns:
119
            str: A matched next command-line history value of input.
120
        """
121
        if self._index == 0:
122
            return self._cached
123
        index = _index = self._index + 1
124
        while _index > self._index:
125
            _index = self._index
126
            candidate = self.next()
127
            if candidate.startswith(self._backward):
128
                return candidate
129
        self._index = index
130
        return self.next()
131