Digraph   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 55
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 55
rs 10
wmc 9

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __init__() 0 3 1
B retrieve() 0 20 5
A find() 0 17 3
1
"""Digraph module."""
2
import re
3
from .key import Key
4
from .util import Singleton, getchar, int2char
5
6
7
DIGRAPH_PATTERN = re.compile(r'(\S{2})\s+(\S)+\s+\d+')
8
"""A digraph pattern used to find digraphs in digraph buffer."""
9
10
11
class Digraph(metaclass=Singleton):
12
    """A digraph registry singleton class.
13
14
    Note:
15
        This class defines ``__slots__`` attribute so sub-class must override
16
        the attribute to extend available attributes.
17
18
    Attributes:
19
        registry (dict): A cached digraph registry.
20
    """
21
22
    __slots__ = ('registry',)
23
24
    def __init__(self):
25
        """Constructor."""
26
        self.registry = None
27
28
    def find(self, nvim, char1, char2):
29
        """Find a digraph of char1/char2.
30
31
        Args:
32
            nvim (neovim.Nvim): A ``neovim.Nvim`` instance.
33
            char1 (str): A char1 for a digraph.
34
            char2 (str): A char2 for a digraph.
35
36
        Return:
37
            str: A digraph character.
38
        """
39
        if self.registry is None:
40
            digraph_output = nvim.call('execute', 'digraphs')
41
            self.registry = _parse_digraph_output(digraph_output)
42
        if char1 + char2 not in self.registry:
43
            return self.registry.get(char2 + char1, char2)
44
        return self.registry[char1 + char2]
45
46
    def retrieve(self, nvim):
47
        """Retrieve char1/char2 and return a corresponding digraph.
48
49
        It asks users to hit two characters which indicate a digraph.
50
51
        Args:
52
            nvim (neovim.Nvim): A ``neovim.Nvim`` instance.
53
54
        Return:
55
            str: A digraph character.
56
        """
57
        code1 = getchar(nvim)
58
        if isinstance(code1, bytes) and code1.startswith(b'\x80'):
59
            return Key.represent(nvim, code1)
60
        code2 = getchar(nvim)
61
        if isinstance(code2, bytes) and code2.startswith(b'\x80'):
62
            return Key.represent(nvim, code2)
63
        char1 = int2char(nvim, code1)
64
        char2 = int2char(nvim, code2)
65
        return self.find(nvim, char1, char2)
66
67
68
def _parse_digraph_output(output):
69
    output = output.replace('\n', '')
70
    output = output.replace('\r', '')
71
    return {
72
        m.group(1): m.group(2)
73
        for m in DIGRAPH_PATTERN.finditer(output)
74
    }
75