GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( d4b3d7...313210 )
by thatsIch
56s
created

get_lines_of_section_on_cursor()   A

Complexity

Conditions 1

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
cc 1
c 4
b 0
f 0
dl 0
loc 13
rs 9.4285
1
"""This module handles the whole auto smart completion sublime-rainmeter has to offer."""
2
3
# python libs
4
import re
5
6
# st libs
7
import sublime
8
9
# own libs
10
from .. import logger
0 ignored issues
show
Bug introduced by
The name logger does not seem to exist in module completion.
Loading history...
11
from .skin.rainmeter_section import SkinRainmeterSectionAutoComplete
12
from .skin.metadata_section import SkinMetadataSectionAutoComplete
13
from .section import SkinSectionAutoCompleter
14
15
16
class ContextSensAutoCompletion(object):
17
    """
18
    This represents the internal implementation for the contextual auto completion.
19
20
    It uses smart environmental information like section, key, values etc
21
    to provide smarter auto completion suggestions.
22
    """
23
24
    # only show our completion list because nothing else makes sense in this context
25
    flags = sublime.INHIBIT_EXPLICIT_COMPLETIONS | sublime.INHIBIT_WORD_COMPLETIONS
26
27
    section = None
28
    skin_rainmeter_section = None
29
    skin_metadata_section = None
30
31
    scope = "source.rainmeter"
32
33
    # comments are specified by ';'
34
    comment_exp = re.compile(r'^\s*;.*')
35
36
    # enable searching for [] in multiline environment
37
    bracket_expression = re.compile(r'^\s*\[.+\]\s*$', re.MULTILINE)
38
    section_expression = re.compile(r'^\s*\[(.+)\]\s*$', re.I)
39
    key_expression = re.compile(r'^\s*(.+)\s*\=?\s*(.*?)\s*$', re.MULTILINE)
40
    key_value_expression = re.compile(r'^\s*(.+?)\s*\=\s*(.*?)\s*$', re.MULTILINE)
41
42
    def __init__(self):
43
        """Initialize the different completer components."""
44
        self.section = SkinSectionAutoCompleter()
45
        self.skin_rainmeter_section = SkinRainmeterSectionAutoComplete()
46
        self.skin_metadata_section = SkinMetadataSectionAutoComplete()
47
48
    def get_lines_of_section_on_cursor(self, view, location):
49
        """Determine content of current section."""
50
        size = view.size()
51
        start_content = view.substr(sublime.Region(0, location))
52
        end_content = view.substr(sublime.Region(location, size))
53
54
        start_index = self.get_start_index_of_section(start_content)
55
        end_index = self.get_end_index_of_section(end_content, location, size)
56
57
        section = view.substr(sublime.Region(start_index, end_index))
58
        lines = section.splitlines()
59
60
        return lines
61
62
    def get_start_index_of_section(self, start_content):
63
        """
64
        Return the index of the section.
65
66
        If no section is found the first index (0) is returned
67
        """
68
        matches = list(self.bracket_expression.finditer(start_content))
69
70
        if len(matches) > 0:
71
            last_match = matches[-1]
72
            return last_match.start()
73
74
        # no previous section found, hardly legal but who cares
75
        else:
76
            return 0
77
78
    def get_end_index_of_section(self, end_content, offset, end_index):
79
        """
80
        Return the index of the next section.
81
82
        If no next section is found the last index is returned given through the param end_index
83
        """
84
        matches = list(self.bracket_expression.finditer(end_content))
85
        if len(matches) > 0:
86
            first_match = matches[0]
87
            return first_match.start() + offset
88
89
        # no next section found
90
        else:
91
            return end_index
92
93
    def get_key_value(self, line_content):
94
        """
95
        Extract the key and/or value in a line if existing.
96
97
        This is used if a specific completion is only shown
98
        on special conditions like only show X on measures.
99
100
        If nothing is given return (None, None)
101
        """
102
        key_value_match = self.key_value_expression.search(line_content)
103
        if key_value_match:
104
            key_match = key_value_match.group(1)
105
            value_match = key_value_match.group(2)
106
            logger.info(
107
                __file__,
108
                "on_query_completions",
109
                "key/value found in '" + line_content + 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
110
                "' with ('" + key_match + "', '" + value_match + "')"
111
            )
112
113
            return key_match, value_match
114
115
        key_only_match = self.key_expression.search(line_content)
116
        if key_only_match:
117
            logger.info(
118
                __file__,
119
                "on_query_completions",
120
                "potential key found in '" + line_content + "'"
121
            )
122
            return key_only_match.group(1), None
123
124
        return None, None
125
126
    def get_key_values(self, lines):
127
        """Extract all key values in the given lines."""
128
        key_values = []
129
130
        for line in lines:
131
            key, value = self.get_key_value(line)
132
            if key:
133
                key_values.append((key, value))
134
135
        return key_values
136
137
    def on_query_completions(self, view, prefix, locations):
138
        """"Execute if a auto completion is requested.
139
140
        can be either via typing or manual invoked with ctrl+space.
141
142
        This provides general variable extractions which are then
143
        passed to the domain specific worker completions.
144
        """
145
        for location in locations:
146
            # ignore non scope
147
            if not view.match_selector(location, self.scope):
148
                return None
149
150
            # ignore on comment lines
151
            cursor_line = view.line(location)
152
            line_content = view.substr(cursor_line)
153
            if self.comment_exp.search(line_content):
154
                logger.info(__file__, "on_query_completions", "found comment")
155
                return None
156
157
            # find last occurance of the [] to determine the ini sections
158
            lines = self.get_lines_of_section_on_cursor(view, location)
159
            # filter empty lines
160
            lines = list(filter(None, lines))
161
            # filter comments
162
            lines = list(filter(lambda l: not self.comment_exp.search(l), lines))
163
164
            if not lines:
165
                logger.info(__file__, "bootstrap.on_query_completions", "section is empty")
166
                size = view.size()
167
                content = view.substr(sublime.Region(0, size))
168
                sections = self.bracket_expression.findall(content)
169
170
                return self.section.get_key_context_completion(prefix, line_content, sections)
171
172
            # extract section
173
            first_line = lines[0]
174
            match = self.section_expression.search(first_line)
175
176
            # no section defined
177
            # TODO section suggestion
0 ignored issues
show
Coding Style introduced by
TODO and FIXME comments should generally be avoided.
Loading history...
178
            # if not match:
179
            #     logger.info(__file__, "on_query_completions", "no section found")
180
            #     size = view.size()
181
            #     content = view.substr(sublime.Region(0, size))
182
            #     sections = self.bracket_expression.findall(content)
183
184
            #     return self.section.get_key_context_completion(prefix, line_content, sections)
185
            section = match.group(1)
186
187
            key_match, value_match = self.get_key_value(line_content)
188
            key_values = self.get_key_values(lines)
189
190
            if value_match == "":
191
                logger.info(
192
                    __file__,
193
                    "on_query_completions",
194
                    "after equal trigger in '" + line_content + "'"
195
                )
196
                # value trigger
197
                value_result = self.skin_rainmeter_section.get_value_context_completion(
198
                    section,
199
                    key_match
200
                )
201
202
                if value_result:
203
                    return value_result
204
205
            # only do key completion if we are in the key are
206
            # that means in front of the equal or no equal at all
207
            else:
208
                logger.info(
209
                    __file__,
210
                    "on_query_completions",
211
                    "before equal trigger in '" + line_content + "'"
212
                )
213
                key_result = self.skin_rainmeter_section.get_key_context_completion(
214
                    prefix,
215
                    line_content,
216
                    section,
217
                    key_values
218
                )
219
220
                if key_result:
221
                    return key_result
222
223
                key_result = self.skin_metadata_section.get_key_context_completion(
224
                    prefix,
225
                    line_content,
226
                    section,
227
                    key_values
228
                )
229
                if key_result:
230
                    return key_result
231
232
            return None
233