1
-----------------------------------------------------------------------
4
-- Copyright (C) 2006-2008, AdaCore --
6
-- GPS is free software; you can redistribute it and/or modify it --
7
-- under the terms of the GNU General Public License as published by --
8
-- the Free Software Foundation; either version 2 of the License, or --
9
-- (at your option) any later version. --
11
-- This program is distributed in the hope that it will be useful, --
12
-- but WITHOUT ANY WARRANTY; without even the implied warranty of --
13
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU --
14
-- General Public License for more details. You should have received --
15
-- a copy of the GNU General Public License along with this program; --
16
-- if not, write to the Free Software Foundation, Inc., 59 Temple --
17
-- Place - Suite 330, Boston, MA 02111-1307, USA. --
18
-----------------------------------------------------------------------
20
-- Provides the base structures / subprograms for the completion manager. A
21
-- completion manager is the base class of the completion mechanism. Before
22
-- using it, you have to add manually the completion resolvers you want to
23
-- use. A completion manager has to be build at each completion request, since
24
-- it might depend on different datas. You can see for example the subprogram
25
-- Full_Test in the test driver Completion.Test.
27
with Ada.Containers.Indefinite_Ordered_Maps;
28
with Ada.Containers.Indefinite_Ordered_Sets;
29
with Ada.Containers.Doubly_Linked_Lists;
33
with GNAT.Strings; use GNAT.Strings;
35
with Language; use Language;
38
with Virtual_Lists.Extensive;
40
with GNATCOLL.VFS; use GNATCOLL.VFS;
44
type Completion_Proposal;
45
-- This is the type of a proposal.
47
type Completion_Proposal_Access is access all Completion_Proposal'Class;
49
procedure Free (This : in out Completion_Proposal_Access);
51
type Completion_List is private;
52
-- This type hold a set of completions
54
procedure Free (List : in out Completion_List);
55
-- Free the memory associated to the completion list.
57
function Get_Completed_String (This : Completion_List) return String;
58
-- Return the string that have been analyzed and is in the process of
59
-- being completed. This is just the part of the string already in the
60
-- buffer, and should be replaced by the string found in the completion,
61
-- in order to have the proper casing.
63
Null_Completion_List : constant Completion_List;
65
------------------------
66
-- Completion_Context --
67
------------------------
69
type Completion_Context is private;
70
-- A context holds data used by the completion engine to precise the
71
-- completion. It holds at least the buffer and the offset of the
72
-- completion, but some completion engines might want to attach specific
75
procedure Free (Context : in out Completion_Context);
76
-- Free data associated to the context given in parameter.
79
(Context : Completion_Context) return String_Access;
80
-- Return the buffer associated to this context.
82
function Get_Completion_Offset
83
(Context : Completion_Context) return Natural;
84
-- Return the offset associated to this context.
87
(Context : Completion_Context) return GNATCOLL.VFS.Virtual_File;
88
-- Return the file associated with this context
94
type Completion_Id (Id_Length : Integer) is record
95
Resolver_Id : String (1 .. 8);
96
-- This id identifies in an unique way a resolver. Users are responsible
97
-- of avoiding name clashes.
99
Id : String (1 .. Id_Length);
102
Column : Natural := 0;
104
-- This type is used to store a completion proposal in an long time basis -
105
-- while the Completion_Proposal lifecycle is bound to its resolver one. A
106
-- resolver is supposed to be able to retreive a proposal based on an id,
107
-- if the proposal is still valid.
109
function "<" (Left, Right : Completion_Id) return Boolean;
110
-- Arbitrary comparison between two completion ids.
112
overriding function "=" (Left, Right : Completion_Id) return Boolean;
113
-- Return true if the two ids are equals.
115
-------------------------
116
-- Completion_Resolver --
117
-------------------------
119
type Completion_Resolver is abstract tagged private;
120
-- This types holds a completion engine. Various completion engines can be
121
-- created, based on constructs or xrefs.
123
type Completion_Resolver_Access is access all Completion_Resolver'Class;
125
procedure Free (Resolver : in out Completion_Resolver_Access);
126
-- Frees a completion resolver access. This will also call the internal
129
function Next (Resolver : access Completion_Resolver'Class)
130
return Completion_Resolver_Access;
131
-- Return the next completion resolver in the parent Completion_Manager,
134
procedure Get_Completion_Root
135
(Resolver : access Completion_Resolver;
137
Context : Completion_Context;
138
Result : in out Completion_List) is abstract;
139
-- Starts a completion, looking from the offset given in parameter.
140
-- Offset should be the offset of the place from where we try to find the
141
-- corresponding identifier, in bytes, and visiblity will be calculated
142
-- for this offset. If offset is lower than zero, it means that the
143
-- completion is done from the very begining of the file, and therefore
144
-- nothing from the file should be extracted. The completions returned by
145
-- this procedure are either resolved, or need to be expanded by an other
146
-- completion resolver.
148
procedure Free (Resolver : in out Completion_Resolver) is abstract;
149
-- Free the data of a Resolver.
151
function Get_Id (Resolver : Completion_Resolver) return String is abstract;
152
-- Return a unique ID corresponing to this resolver.
154
------------------------
155
-- Completion_Manager --
156
------------------------
158
type Completion_Manager is abstract tagged private;
159
-- A completion manager is a type holding a list of completions resolvers.
160
-- Resolvers will be called in the order they are referenced. This object
161
-- also holds a couple of general datas, such as the buffer from where the
162
-- completion is done.
164
type Completion_Manager_Access is access all Completion_Manager'Class;
166
procedure Free (This : in out Completion_Manager_Access);
167
-- Free the memory associated to a completion manager access. This does not
168
-- free the referenced resolvers which have to be freed separately.
170
procedure Register_Resolver
171
(Manager : access Completion_Manager;
172
Resolver : access Completion_Resolver'Class);
173
-- Add a resolver to this manager. A given resolver can only be added in
174
-- one manager (it knows its manager). Resolvers will be called in the
175
-- order that they have been registred.
177
function Create_Context
178
(Manager : access Completion_Manager;
179
File : GNATCOLL.VFS.Virtual_File;
180
Buffer : String_Access;
181
Lang : Language_Access;
182
Offset : Natural) return Completion_Context;
183
-- Creates a new context for this manager, with the offset and the buffer
184
-- given in parameter.
186
function Get_Resolver
187
(Manager : access Completion_Manager;
188
Name : String) return Completion_Resolver_Access;
189
-- Return the resolver registered in the manager of the given name.
191
-------------------------
192
-- Completion_Proposal --
193
-------------------------
195
type Completion_Proposal is abstract tagged record
196
Resolver : access Completion_Resolver'Class;
199
type File_Location is record
200
File_Path : Virtual_File;
202
Column : Basic_Types.Visible_Column_Type;
205
Null_File_Location : constant File_Location;
207
Null_Completion_Proposal : constant Completion_Proposal'Class;
209
function Get_Resolver
210
(Proposal : Completion_Proposal) return Completion_Resolver_Access;
211
-- Returns the resolver that have been used to create this proposal.
213
function Get_Completion
214
(Proposal : Completion_Proposal) return UTF8_String is abstract;
215
-- Return the text that has to be used for the completion, may be different
218
function Get_Label (Proposal : Completion_Proposal) return UTF8_String;
219
-- Return the label of the completion proposal. By defaut, return the
222
function Get_Id (Proposal : Completion_Proposal) return UTF8_String;
223
-- Return the identifier of the entity referenced in the proposal. This
224
-- identifier can be different from the completion propsed and the label.
225
-- By default, return the completion.
227
function Get_Caret_Offset
228
(Proposal : Completion_Proposal) return Basic_Types.Character_Offset_Type;
229
-- Return the offset where the editor caret is supposed to be after the
230
-- completion. In the default implementation, it's always moved at the
231
-- end of the inserted text.
233
function Get_Documentation
234
(Proposal : Completion_Proposal) return UTF8_String;
235
-- Return the documentation corresponding to the proposal.
237
function Get_Location (Proposal : Completion_Proposal) return File_Location;
238
-- Return the location of the object pointed by the given proposal, null
239
-- if none. By default, return Null_Location.
241
function Get_Category
242
(Proposal : Completion_Proposal) return Language_Category is abstract;
243
-- Return the category of the object proposed for the completion
245
function Get_Visibility
246
(Proposal : Completion_Proposal) return Construct_Visibility is abstract;
247
-- Return the visibility of the object proposed for completion
249
function Is_Valid (Proposal : Completion_Proposal) return Boolean;
250
-- Return true if the proposal should be accessible by the user. By
251
-- default, this is always true. Unvalid proposal are automatically skipped
252
-- by the Next & First subprogram. However, an unvalid completion can be
253
-- returned by an iterator if changes are made between two iterations.
254
-- Users using such a behavior have to ensure that the iterator result of
255
-- the iterator is still valid after such a modification. A call to next
256
-- on the iterator will make the completion valid again.
258
function Get_Initial_Completion_List
259
(Manager : access Completion_Manager; Context : Completion_Context)
260
return Completion_List is abstract;
261
-- Generates an initial completion list, for the cursor pointing at the
262
-- given offset. This operation is time consuming, so it would be good
263
-- to use the one below afterwards, until the completion process is done.
266
(Proposal : Completion_Proposal;
267
Context : Completion_Context;
268
Offset : Integer) return Boolean is abstract;
269
-- Return true if the proposal given in parameter matches the completion
270
-- search parameters given, false otherwise.
272
function To_Completion_Id
273
(Proposal : Completion_Proposal) return Completion_Id is abstract;
274
-- Creates a completion id able to retreive this completion proposal later
277
procedure Free (Proposal : in out Completion_Proposal) is abstract;
278
-- Free the memory associated to the proposal.
280
-------------------------
281
-- Completion_Iterator --
282
-------------------------
284
type Completion_Iterator is private;
285
-- This type is used to iterate over the various possibilities of a
288
function First (This : Completion_List) return Completion_Iterator;
289
-- Return the first proposal of the completion list.
291
procedure Next (This : in out Completion_Iterator);
292
-- Gets the next proposal of the completion list.
294
function Get_Proposal
295
(This : Completion_Iterator) return Completion_Proposal'Class;
296
-- Return the actual proposal for the given iterator.
297
-- The returned value should NOT be freed by the user.
299
procedure Free (This : in out Completion_Iterator);
300
-- Free the data associated to a completion iterator.
302
function At_End (This : Completion_Iterator) return Boolean;
303
-- Return true if the iterator is after the last element of its list.
305
function Is_Valid (It : Completion_Iterator) return Boolean;
306
-- Return true if the iterator should be used by the user, false otherwise.
307
-- iterators returned by Next and First subprograms are always valid (even
308
-- if, in the case of Next, the iterator given in parameter is not). A
309
-- valid iterator can be invalidated if the iterated structure changes
310
-- during the iteration.
312
Null_Completion_Iterator : constant Completion_Iterator;
313
-- Default value for an empty iterator.
317
type Completion_Context_Record is tagged record
318
Buffer : String_Access;
319
-- Buffer.all should be encoded in UTF8.
322
Lang : Language_Access;
323
File : GNATCOLL.VFS.Virtual_File;
326
type Completion_Context is access all Completion_Context_Record'Class;
328
procedure Free (Context : in out Completion_Context_Record);
330
type Completion_Resolver is abstract tagged record
331
Manager : Completion_Manager_Access;
334
package Completion_Resolver_Map_Pckg is new
335
Ada.Containers.Indefinite_Ordered_Maps
336
(String, Completion_Resolver_Access);
338
package Completion_Resolver_List_Pckg is new
339
Ada.Containers.Doubly_Linked_Lists (Completion_Resolver_Access);
341
use Completion_Resolver_Map_Pckg;
342
use Completion_Resolver_List_Pckg;
344
package Context_List_Pckg is new Generic_List (Completion_Context);
346
use Context_List_Pckg;
348
type Completion_Manager is abstract tagged record
349
Resolvers : Completion_Resolver_Map_Pckg.Map;
350
Ordered_Resolvers : Completion_Resolver_List_Pckg.List;
351
Contexts : Context_List_Pckg.List;
354
Null_File_Location : constant File_Location := (No_File, 0, 0);
356
procedure Free_Proposal (Proposal : in out Completion_Proposal'Class);
357
-- Used to instantiate the generic list (this is not actually doing
360
---------------------
361
-- Completion_List --
362
---------------------
364
package Completion_List_Pckg is new Virtual_Lists
365
(Completion_Proposal'Class);
367
package Completion_List_Extensive_Pckg is new
368
Completion_List_Pckg.Extensive (Free => Free_Proposal);
370
type Completion_List is record
371
List : Completion_List_Pckg.Virtual_List;
372
Searched_Identifier : String_Access;
375
package Completion_Id_Set is new
376
Ada.Containers.Indefinite_Ordered_Sets (Completion_Id);
378
use Completion_Id_Set;
380
type Completion_Iterator is record
381
It : Completion_List_Pckg.Virtual_List_Iterator;
382
Already_Extracted : Completion_Id_Set.Set;
385
Null_Completion_List : constant Completion_List :=
386
(Completion_List_Pckg.Null_Virtual_List, null);
388
Null_Completion_Iterator : constant Completion_Iterator :=
389
(It => Completion_List_Pckg.Null_Virtual_List_Iterator, others => <>);
391
--------------------------------
392
-- Simple_Completion_Proposal --
393
--------------------------------
395
type Simple_Completion_Proposal is new Completion_Proposal with record
396
Name : String_Access;
397
Category : Language_Category := Cat_Unknown;
398
Documentation : String_Access;
401
overriding function Get_Completion
402
(Proposal : Simple_Completion_Proposal) return UTF8_String;
403
-- See inherited documentation
405
overriding function Get_Documentation
406
(Proposal : Simple_Completion_Proposal) return UTF8_String;
407
-- See inherited documentation
409
overriding function Get_Category
410
(Proposal : Simple_Completion_Proposal) return Language_Category;
411
-- See inherited documentation
413
overriding function Get_Visibility
414
(Proposal : Simple_Completion_Proposal) return Construct_Visibility;
415
-- See inherited documentation
417
overriding function Match
418
(Proposal : Simple_Completion_Proposal;
419
Context : Completion_Context;
420
Offset : Integer) return Boolean;
421
-- See inherited documentation
423
overriding function To_Completion_Id
424
(Proposal : Simple_Completion_Proposal) return Completion_Id;
425
-- See inherited documentation
427
overriding procedure Free (Proposal : in out Simple_Completion_Proposal);
428
-- See inherited documentation
431
(Seeked_Name, Tested_Name : String; Is_Partial : Boolean) return Boolean;
432
-- Return true if Tested_Name matches Seeked_Name, possibly only partially
433
-- (in which case Seeked_Name is the beginning of Tested_Name), false
436
Null_Completion_Proposal : constant Completion_Proposal'Class :=
437
Simple_Completion_Proposal'
440
Category => Cat_Unknown,
441
Documentation => null);