Updated Spanish translation
[anjuta-git-plugin.git] / plugins / editor / aneditor-calltip.cxx
blob846196e8e1a70a8fe567b859abfaab731e233e69
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 aneditor-calltip.cxx
4 Copyright (C) 2004 Naba Kumar
6 This program is free software; you can redistribute it and/or modify
7 it 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
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include <libanjuta/anjuta-debug.h>
22 #include "aneditor-priv.h"
24 bool AnEditor::StartCallTip_new() {
25 TMTagAttrType attrs[] =
27 tm_tag_attr_name_t, tm_tag_attr_type_t, tm_tag_attr_none_t
29 SString linebuf;
30 GetLine(linebuf);
31 int current = GetCaretInLine();
32 call_tip_node.start_pos = SendEditor(SCI_GETCURRENTPOS);
33 call_tip_node.call_tip_start_pos = current;
35 int braces;
36 do {
37 braces = 0;
38 while (current > 0 && (braces || linebuf[current - 1] != '(')) {
39 if (linebuf[current - 1] == '(')
40 braces--;
41 else if (linebuf[current - 1] == ')')
42 braces++;
43 current--;
44 call_tip_node.start_pos--;
46 if (current > 0) {
47 current--;
48 call_tip_node.start_pos--;
49 } else
50 break;
51 while (current > 0 && isspace(linebuf[current - 1])) {
52 current--;
53 call_tip_node.start_pos--;
55 } while (current > 0 &&
56 !calltipWordCharacters.contains(linebuf[current - 1]));
58 if (current <= 0)
59 return true;
61 call_tip_node.startCalltipWord = current -1;
63 while (call_tip_node.startCalltipWord > 0 &&
64 calltipWordCharacters.contains(linebuf[call_tip_node.startCalltipWord - 1]))
65 call_tip_node.startCalltipWord--;
67 linebuf.change(current, '\0');
68 call_tip_node.rootlen = current - call_tip_node.startCalltipWord;
70 call_tip_node.max_def = 0;
71 call_tip_node.def_index = 0;
73 const GPtrArray *tags = tm_workspace_find(linebuf.c_str() +
74 call_tip_node.startCalltipWord,
75 tm_tag_prototype_t |
76 tm_tag_function_t |
77 tm_tag_macro_with_arg_t,
78 attrs, FALSE, TRUE);
79 if (tags && (tags->len > 0))
81 call_tip_node.max_def = (tags->len < 20)? tags->len:20;
82 printf ("Number of calltips found %d\n", tags->len);
83 for (unsigned int i = 0; (i < tags->len) && (i < 20); i++) {
84 TMTag *tag = (TMTag *) tags->pdata[0];
85 GString* tmp = g_string_new(NVL(tag->atts.entry.type_ref[1], ""));
86 for (unsigned int j = 0; j < tag->atts.entry.pointerOrder; j++)
87 g_string_append(tmp, "*");
88 g_string_append_printf(tmp, " %s%s", tag->name,
89 NVL(tag->atts.entry.arglist, ""));
90 call_tip_node.functionDefinition[i] = tmp->str;
91 g_string_free(tmp, TRUE);
93 char *real_tip;
94 if (call_tip_node.max_def > 1)
95 real_tip = g_strconcat ("\002",
96 call_tip_node.functionDefinition[0].c_str(),
97 NULL);
98 else
99 real_tip = g_strdup (call_tip_node.functionDefinition[0].c_str());
101 SendEditorString(SCI_CALLTIPSHOW, call_tip_node.start_pos -
102 call_tip_node.rootlen + 1, real_tip);
103 g_free (real_tip);
104 ContinueCallTip_new();
106 return true;
109 static bool IsCallTipSeparator(char ch) {
110 return (ch == ',') || (ch == ';');
113 void AnEditor::ContinueCallTip_new() {
114 SString linebuf;
115 GetLine(linebuf);
116 unsigned current = GetCaretInLine();
117 int commas = 0;
119 for (unsigned i = call_tip_node.call_tip_start_pos; i < current; i++) {
121 unsigned char ch = linebuf[i];
123 // check whether the are some other functions nested.
124 // if found we'll skip them to evitate commas problems
125 if ( ch == '(' ) {
126 int braces = 1;
127 for (unsigned k = i+1; k < linebuf.length(); k++ ) {
128 if ( linebuf[k] == '(' ) {
129 braces++;
131 else
132 if ( linebuf[k] == ')' ) {
133 braces--;
135 if ( braces == 0 ) {
136 i = k;
137 break;
142 if (IsCallTipSeparator(ch))
143 commas++;
146 // lets start from 0
147 int startHighlight = 0;
149 while (call_tip_node.functionDefinition[call_tip_node.def_index][startHighlight] &&
150 call_tip_node.functionDefinition[call_tip_node.def_index][startHighlight] != '(')
151 startHighlight++;
153 if (call_tip_node.functionDefinition[call_tip_node.def_index][startHighlight] == '(') {
154 startHighlight++;
157 // printf(const char*, ...
158 // -------^
160 while (call_tip_node.functionDefinition[call_tip_node.def_index][startHighlight] &&
161 commas > 0) {
162 if (IsCallTipSeparator(call_tip_node.functionDefinition[call_tip_node.def_index][startHighlight] ) ||
163 call_tip_node.functionDefinition[call_tip_node.def_index][startHighlight] == ')')
164 commas--;
165 startHighlight++;
168 if (IsCallTipSeparator(call_tip_node.functionDefinition[call_tip_node.def_index][startHighlight]) ||
169 call_tip_node.functionDefinition[call_tip_node.def_index][startHighlight] == ')')
170 startHighlight++;
172 int endHighlight = startHighlight;
174 if (call_tip_node.functionDefinition[call_tip_node.def_index][endHighlight])
175 endHighlight++;
177 while (call_tip_node.functionDefinition[call_tip_node.def_index][endHighlight] &&
178 !IsCallTipSeparator(call_tip_node.functionDefinition[call_tip_node.def_index][endHighlight])
179 && call_tip_node.functionDefinition[call_tip_node.def_index][endHighlight] != ')')
180 endHighlight++;
182 SendEditor(SCI_CALLTIPSETHLT, startHighlight, endHighlight);
185 //------------------------------------------------------------------------------
186 // we're going to save the current status of call_tip_node in call_tip_node_list
187 // to let another *new* call_tip to show up
190 void AnEditor::SaveCallTip() {
192 CallTipNode *ctn = new CallTipNode;
193 // g_message( "***saving calltip..." );
195 ctn->startCalltipWord = call_tip_node.startCalltipWord;
196 ctn->def_index = call_tip_node.def_index;
197 ctn->max_def = call_tip_node.max_def;
198 for (int i = 0; i < ctn->max_def; i++) {
199 ctn->functionDefinition[i] = call_tip_node.functionDefinition[i];
201 ctn->start_pos = call_tip_node.start_pos;
202 ctn->rootlen = call_tip_node.rootlen;
203 ctn->call_tip_start_pos = call_tip_node.call_tip_start_pos;
205 // push it
206 g_queue_push_tail( call_tip_node_queue, ctn );
208 SetCallTipDefaults();
211 void AnEditor::ResumeCallTip(bool pop_from_stack) {
213 if (pop_from_stack) {
214 if (g_queue_is_empty (call_tip_node_queue)) {
215 ShutDownCallTip();
216 return;
219 CallTipNode_ptr tmp_node;
221 // set up next CallTipNode parameters in AnEditor::call_tip_node
222 tmp_node = (CallTipNode_ptr)g_queue_pop_tail( call_tip_node_queue );
224 g_return_if_fail( tmp_node != NULL );
226 call_tip_node.startCalltipWord = tmp_node->startCalltipWord;
227 call_tip_node.def_index = tmp_node->def_index;
228 call_tip_node.max_def = tmp_node->max_def;
229 for (int i = 0; i < call_tip_node.max_def; i++)
230 call_tip_node.functionDefinition[i] =
231 tmp_node->functionDefinition[i];
232 call_tip_node.start_pos = tmp_node->start_pos;
233 call_tip_node.rootlen = tmp_node->rootlen;
234 call_tip_node.call_tip_start_pos = tmp_node->call_tip_start_pos;
236 // in response to g_malloc on SaveCallTip
237 delete tmp_node;
239 if (call_tip_node.max_def > 1 &&
240 call_tip_node.def_index == 0) {
242 char *real_tip;
243 real_tip = g_strconcat ("\002",
244 call_tip_node.functionDefinition[call_tip_node.def_index].c_str(),
245 NULL);
246 SendEditorString(SCI_CALLTIPSHOW, call_tip_node.start_pos -
247 call_tip_node.rootlen + 1, real_tip);
248 g_free (real_tip);
249 } else if (call_tip_node.max_def > 1 &&
250 call_tip_node.def_index == (call_tip_node.max_def - 1)) {
251 char *real_tip;
252 real_tip = g_strconcat ("\001",
253 call_tip_node.functionDefinition[call_tip_node.def_index].c_str(),
254 NULL);
255 SendEditorString(SCI_CALLTIPSHOW, call_tip_node.start_pos -
256 call_tip_node.rootlen + 1, real_tip);
257 g_free (real_tip);
258 } else if (call_tip_node.max_def > 1) {
259 char *real_tip;
260 real_tip = g_strconcat ("\001\002",
261 call_tip_node.functionDefinition[call_tip_node.def_index].c_str(),
262 NULL);
263 SendEditorString(SCI_CALLTIPSHOW, call_tip_node.start_pos -
264 call_tip_node.rootlen + 1, real_tip);
265 g_free (real_tip);
266 } else {
267 SendEditorString(SCI_CALLTIPSHOW, call_tip_node.start_pos -
268 call_tip_node.rootlen + 1,
269 call_tip_node.functionDefinition[call_tip_node.def_index].c_str());
273 //------------------------------------------------------------------------------
276 void AnEditor::ShutDownCallTip() {
278 // g_message( "***shutdowncalltip: length %d", g_queue_get_length( call_tip_node_queue ));
280 while ( g_queue_is_empty( call_tip_node_queue ) != TRUE ) {
281 CallTipNode_ptr tmp_node;
283 tmp_node = (CallTipNode_ptr)g_queue_pop_tail( call_tip_node_queue );
285 // in response to g_malloc on SaveCallTip
286 delete tmp_node;
288 // reset
289 SetCallTipDefaults();
292 //------------------------------------------------------------------------------
294 void AnEditor::SetCallTipDefaults( ) {
296 // we're going to set the default values to this.call_tip_node struct
297 call_tip_node.def_index = 0;
298 call_tip_node.max_def = 0;
299 call_tip_node.start_pos = 0;
300 call_tip_node.rootlen = 0;
301 call_tip_node.startCalltipWord = 0;
302 call_tip_node.call_tip_start_pos = 0;
305 //------------------------------------------------------------------------------
306 // gives a list of calltips which match the word on the current caret and display
307 // them
309 void AnEditor::CompleteCallTip() {
310 char expr[256];
311 TMTagAttrType attrs[] = {tm_tag_attr_name_t, tm_tag_attr_type_t, tm_tag_attr_none_t};
312 int caret_position = SendEditor(SCI_GETCURRENTPOS);
314 if (SendEditor(SCI_CALLTIPACTIVE))
315 return;
317 // get the current word
318 GetWordAtPosition(expr, sizeof(expr), caret_position);
319 DEBUG_PRINT("completecalltip: on word %s and caret_position %d", expr, caret_position);
321 const GPtrArray *tags = tm_workspace_find(expr,
322 tm_tag_prototype_t |
323 tm_tag_function_t |
324 tm_tag_macro_with_arg_t,
325 attrs, FALSE, TRUE);
327 // we'll provide a function calltip
328 if (tags && (tags->len > 0))
330 TMTag *tag = (TMTag *) tags->pdata[0];
331 SString definition;
332 char *tmp;
334 tmp = g_strdup_printf("%s %s%s", NVL(tag->atts.entry.type_ref[1], ""),
335 tag->name, NVL(tag->atts.entry.arglist, ""));
336 definition = tmp;
337 g_free(tmp);
339 char *real_tip;
340 real_tip = g_strdup (definition.c_str());
342 SendEditorString(SCI_CALLTIPSHOW, caret_position, real_tip);
343 g_free (real_tip);