1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
|
"""
Implements completion resolvers.
A completion resolver is an object that provides completion proposals in
the completion window in source editors.
To implement a new completion resolver:
- derive from the class CompletionResolver
and override the method get_completions
- register your class using GPS.Completion.Register
1
Example
-------
This shows how to create two completion resolvers: a simple one which just
returns a list of completion proposals, and one which is a function
(supposedly more costly) which returns completions proposals one by one.
import GPS
from modules import Module
from completion import CompletionResolver, CompletionProposal
import time
# A simple resolver
class Simple_Resolver(CompletionResolver):
def __init__(self):
pass
def get_completions(self, loc):
return [CompletionProposal("cat", "cat", "description of cat"),
CompletionProposal("dog", "dog", "description of dog")]
# An advanced resolver
class Advanced_Resolver(CompletionResolver):
def __init__(self):
pass
def get_completions(self, loc):
current = 1
while current < 1000:
yield CompletionProposal(
"completion %s" % current,
"item %s" % current,
"documentation for item %s" % current)
current += 1
# Register both resolvers
GPS.Completion.register(Simple_Resolver(), 'Ada')
GPS.Completion.register(Advanced_Resolver(), 'Ada')
"""
import text_utils
CAT_UNKNOWN = 1
CAT_PACKAGE = 2
CAT_NAMESPACE = 3
CAT_TASK = 4
Cat_PROCEDURE = 5
CAT_FUNCTION = 6
CAT_METHOD = 7
CAT_CONSTRUCTOR = 8
CAT_DESTRUCTOR = 9
CAT_PROTECTED = 10
CAT_ENTRY = 11
CAT_CLASS = 12
CAT_STRUCTURE = 13
CAT_CASE_INSIDE_RECORD = 14
CAT_UNION = 15
CAT_TYPE = 16
CAT_SUBTYPE = 17
CAT_VARIABLE = 18
CAT_LOCAL_VARIABLE = 19
CAT_PARAMETER = 20
CAT_DISCRIMINANT = 21
CAT_FIELD = 22
CAT_LITERAL = 23
CAT_REPRESENTATION_CLAUSE = 24
CAT_WITH = 25
CAT_USE = 26
CAT_INCLUDE = 27
CAT_LOOP_STATEMENT = 28
CAT_IF_STATEMENT = 29
CAT_CASE_STATEMENT = 30
CAT_SELECT_STATEMENT = 31
CAT_ACCEPT_STATEMENT = 32
CAT_DECLARE_BLOCK = 33
CAT_RETURN_BLOCK = 34
Cat_Simple_Block = 35
CAT_EXCEPTION_HANDLER = 36
CAT_PRAGMA = 37
CAT_ASPECT = 38
CAT_CUSTOM = 39
def to_completion_point(ed_loc):
"""
Find the beginning of the word currently being completed.
Word = [a-zA-Z0-9_]
"""
return text_utils.forward_until(
ed_loc.forward_char(-1),
lambda c: not (c.isalpha() or c.isdigit() or c == "_"),
backwards=True
).forward_char()
class CompletionProposal(object):
""" A completion proposal.
"""
def __init__(self, name, label, documentation,
icon_name="", action_name="", language_category=CAT_CUSTOM):
"""
Creates a Completion Proposal.
The following fields can be defined:
- name: the actual string which will be inserted in the editor
if this proposal is chosen
- label: the label to be used in the list in the completion
window. For a short text completion, this should be
the same as name.
- documentation: text appearing in the documentation window
when this proposal is selected in the list.
In pango markup language.
- icon_name: (optional) the name of a named icon in the icon
theme.
- action_name: (optional) the name of an action to execute
when this proposal is selected.
"""
self.name = name
self.label = label
self.documentation = documentation
self.icon_name = icon_name
self.action_name = action_name
self.language_category = language_category
def get_data_as_list(self):
return [self.name, self.label, self.documentation,
self.icon_name, self.action_name, self.language_category]
class SimpleCompletionResolver(object):
def __init__(self):
pass
def get_completions(self, loc):
"""
Return a list of CompletionProposals.
loc is an EditorLocation, pointing to the point at which the
completion is occurring.
"""
return []
class CompletionResolver(object):
def __init__(self):
pass
def get_completion_prefix(self, loc):
"""
Return the current replacement prefix, as a string.
For instance when completing
foo (bl
then this should return "bl", indicating that the completions
being proposed will complete a word starting with "bl"
The engine will call get_completion_prefix before get_completions,
so you may cache the result of get_completion_prefix if you need.
"""
return ""
def get_completions(self, loc):
"""
Return an iterable object returning iteration proposals.
loc is an EditorLocation, pointing to the point at which the
completion is occurring.
"""
return []
def _ada_get_completions(self, loc):
""" Binding function, do not override """
return AdaIterableWrapper(self.get_completions(loc))
class AdaIterableWrapper(object):
"""
This object wraps around a python iterable object, and provides
binding to the Ada completion iterator. For internal use only.
"""
def __init__(self, iterable):
self.iterable = iterable
self.iterator = None
def _ada_first(self):
if self.iterator:
self.iterator.rewind()
if not self.iterator:
self.iterator = AdaIteratorWrapper(self.iterable.__iter__())
return self.iterator
class AdaIteratorWrapper(object):
""" Binding to a Python iterator, for internal use only. """
def __init__(self, iterator):
self.iterator = iterator
self.current = None
self.at_end = False
self.cached_results = []
# this contains the results that we have already visited
self.index_in_cache = -1
# Index of the current item in the cache, positive only
# when we are re-visiting.
# The python iterator mechanism only knows we're at end when a call to
# next() raises an exception. To map to the Ada behavior, we do one
# call to next() ahead of time and cache the result.
self._ada_next()
def rewind(self):
if self.cached_results:
self.index_in_cache = 0
def _ada_at_end(self):
return self.at_end
def _ada_get(self):
return self.current
def _ada_next(self):
if self.index_in_cache < 0:
# This means that we are not currently visiting the cache
try:
self.current = next(self.iterator)
except StopIteration:
self.at_end = True
self.current = None
else:
# We are currently visiting the cache
if self.index_in_cache < len(self.cached_results):
# We are currently navigating within the cache
self.current = self.cached_results[self.index_in_cache]
self.index_in_cache += 1
else:
# we had been navigating in the cache but reached the end:
# inform that we are no longer navigating the cache, and
# call again to visit using the iterator.
self.index_in_cache = -1
self._ada_next()
|