From bcf27feb980aec593c7cb771984e46113cfad757 Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Tue, 16 Dec 2014 22:31:57 -0300 Subject: New Code Completion -=-=-=-=-=-=-=-=-=- -Massive improvement to code completion -Argument hinting for functions If you manage to out-smart the code-completion in a situation where completion should be possible to guess, let me know. Please enter the commit message for your changes. Lines starting --- scene/gui/text_edit.cpp | 679 ++++++++++++++++++++++++++++-------------------- 1 file changed, 393 insertions(+), 286 deletions(-) (limited to 'scene/gui/text_edit.cpp') diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index ba68948e6b..715c3cbf7e 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -359,385 +359,445 @@ void TextEdit::_update_scrollbars() { void TextEdit::_notification(int p_what) { - switch(p_what) { - case NOTIFICATION_ENTER_TREE: { + switch(p_what) { + case NOTIFICATION_ENTER_TREE: { - _update_caches(); - if (cursor_changed_dirty) - MessageQueue::get_singleton()->push_call(this,"_cursor_changed_emit"); - if (text_changed_dirty) - MessageQueue::get_singleton()->push_call(this,"_text_changed_emit"); + _update_caches(); + if (cursor_changed_dirty) + MessageQueue::get_singleton()->push_call(this,"_cursor_changed_emit"); + if (text_changed_dirty) + MessageQueue::get_singleton()->push_call(this,"_text_changed_emit"); - } break; - case NOTIFICATION_RESIZED: { + } break; + case NOTIFICATION_RESIZED: { - cache.size=get_size(); - adjust_viewport_to_cursor(); + cache.size=get_size(); + adjust_viewport_to_cursor(); - } break; - case NOTIFICATION_THEME_CHANGED: { + } break; + case NOTIFICATION_THEME_CHANGED: { - _update_caches(); - }; - case NOTIFICATION_DRAW: { + _update_caches(); + }; + case NOTIFICATION_DRAW: { - int line_number_char_count=0; + int line_number_char_count=0; - { - int lc=text.size()+1; - cache.line_number_w=0; - while(lc) { - cache.line_number_w+=1; - lc/=10; - }; + { + int lc=text.size()+1; + cache.line_number_w=0; + while(lc) { + cache.line_number_w+=1; + lc/=10; + }; - if (line_numbers) { + if (line_numbers) { - line_number_char_count=cache.line_number_w; - cache.line_number_w=(cache.line_number_w+1)*cache.font->get_char_size('0').width; - } else { - cache.line_number_w=0; - } + line_number_char_count=cache.line_number_w; + cache.line_number_w=(cache.line_number_w+1)*cache.font->get_char_size('0').width; + } else { + cache.line_number_w=0; + } - } - _update_scrollbars(); + } + _update_scrollbars(); - RID ci = get_canvas_item(); - int xmargin_beg=cache.style_normal->get_margin(MARGIN_LEFT)+cache.line_number_w; - int xmargin_end=cache.size.width-cache.style_normal->get_margin(MARGIN_RIGHT); - //let's do it easy for now: - cache.style_normal->draw(ci,Rect2(Point2(),cache.size)); - if (has_focus()) - cache.style_focus->draw(ci,Rect2(Point2(),cache.size)); + RID ci = get_canvas_item(); + int xmargin_beg=cache.style_normal->get_margin(MARGIN_LEFT)+cache.line_number_w; + int xmargin_end=cache.size.width-cache.style_normal->get_margin(MARGIN_RIGHT); + //let's do it easy for now: + cache.style_normal->draw(ci,Rect2(Point2(),cache.size)); + if (has_focus()) + cache.style_focus->draw(ci,Rect2(Point2(),cache.size)); - int ascent=cache.font->get_ascent(); + int ascent=cache.font->get_ascent(); - int visible_rows = get_visible_rows(); + int visible_rows = get_visible_rows(); - int tab_w = cache.font->get_char_size(' ').width*tab_size; + int tab_w = cache.font->get_char_size(' ').width*tab_size; - Color color = cache.font_color; - int in_region=-1; + Color color = cache.font_color; + int in_region=-1; - if (syntax_coloring) { + if (syntax_coloring) { - if (custom_bg_color.a>0.01) { + if (custom_bg_color.a>0.01) { - Point2i ofs = Point2i(cache.style_normal->get_offset())/2.0; - VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(ofs, get_size()-cache.style_normal->get_minimum_size()+ofs),custom_bg_color); - } - //compute actual region to start (may be inside say, a comment). - //slow in very large documments :( but ok for source! + Point2i ofs = Point2i(cache.style_normal->get_offset())/2.0; + VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(ofs, get_size()-cache.style_normal->get_minimum_size()+ofs),custom_bg_color); + } + //compute actual region to start (may be inside say, a comment). + //slow in very large documments :( but ok for source! - for(int i=0;i& cri_map=text.get_color_region_info(i); + const Map& cri_map=text.get_color_region_info(i); - if (in_region>=0 && color_regions[in_region].line_only) { - in_region=-1; //reset regions that end at end of line - } + if (in_region>=0 && color_regions[in_region].line_only) { + in_region=-1; //reset regions that end at end of line + } - for( const Map::Element* E= cri_map.front();E;E=E->next() ) { + for( const Map::Element* E= cri_map.front();E;E=E->next() ) { - const Text::ColorRegionInfo &cri=E->get(); + const Text::ColorRegionInfo &cri=E->get(); - if (in_region==-1) { + if (in_region==-1) { - if (!cri.end) { + if (!cri.end) { - in_region=cri.region; - } - } else if (in_region==cri.region && !color_regions[cri.region].line_only) { //ignore otherwise + in_region=cri.region; + } + } else if (in_region==cri.region && !color_regions[cri.region].line_only) { //ignore otherwise - if (cri.end || color_regions[cri.region].eq) { + if (cri.end || color_regions[cri.region].eq) { - in_region=-1; - } - } - } - } - } + in_region=-1; + } + } + } + } + } - int deregion=0; //force it to clear inrgion - Point2 cursor_pos; + int deregion=0; //force it to clear inrgion + Point2 cursor_pos; - for (int i=0;i=(int)text.size()) - continue; + if (line<0 || line>=(int)text.size()) + continue; - const String &str=text[line]; + const String &str=text[line]; - int char_margin=xmargin_beg-cursor.x_ofs; - int char_ofs=0; - int ofs_y=i*get_row_height()+cache.line_spacing/2; - bool prev_is_char=false; - bool in_keyword=false; - Color keyword_color; + int char_margin=xmargin_beg-cursor.x_ofs; + int char_ofs=0; + int ofs_y=i*get_row_height()+cache.line_spacing/2; + bool prev_is_char=false; + bool in_keyword=false; + Color keyword_color; - if (cache.line_number_w) { - Color fcol = cache.font_color; - fcol.a*=0.4; - String fc = String::num(line+1); - while (fc.length() < line_number_char_count) { - fc="0"+fc; - } + if (cache.line_number_w) { + Color fcol = cache.font_color; + fcol.a*=0.4; + String fc = String::num(line+1); + while (fc.length() < line_number_char_count) { + fc="0"+fc; + } - cache.font->draw(ci,Point2(cache.style_normal->get_margin(MARGIN_LEFT),ofs_y+cache.font->get_ascent()),fc,fcol); - } + cache.font->draw(ci,Point2(cache.style_normal->get_margin(MARGIN_LEFT),ofs_y+cache.font->get_ascent()),fc,fcol); + } - const Map& cri_map=text.get_color_region_info(line); + const Map& cri_map=text.get_color_region_info(line); - if (text.is_marked(line)) { + if (text.is_marked(line)) { - VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(xmargin_beg, ofs_y,xmargin_end-xmargin_beg,get_row_height()),cache.mark_color); - } + VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(xmargin_beg, ofs_y,xmargin_end-xmargin_beg,get_row_height()),cache.mark_color); + } - if (text.is_breakpoint(line)) { + if (text.is_breakpoint(line)) { - VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(xmargin_beg, ofs_y,xmargin_end-xmargin_beg,get_row_height()),cache.breakpoint_color); - } + VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(xmargin_beg, ofs_y,xmargin_end-xmargin_beg,get_row_height()),cache.breakpoint_color); + } - if (line==cursor.line) { + if (line==cursor.line) { - VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(xmargin_beg, ofs_y,xmargin_end-xmargin_beg,get_row_height()),cache.current_line_color); + VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(xmargin_beg, ofs_y,xmargin_end-xmargin_beg,get_row_height()),cache.current_line_color); - } - for (int j=0;j0) { - deregion--; - if (deregion==0) - in_region=-1; - } - if (syntax_coloring && deregion==0) { + if (deregion>0) { + deregion--; + if (deregion==0) + in_region=-1; + } + if (syntax_coloring && deregion==0) { - color = cache.font_color; //reset - //find keyword - bool is_char = _is_text_char(str[j]); - bool is_symbol=_is_symbol(str[j]); + color = cache.font_color; //reset + //find keyword + bool is_char = _is_text_char(str[j]); + bool is_symbol=_is_symbol(str[j]); - if (j==0 && in_region>=0 && color_regions[in_region].line_only) { - in_region=-1; //reset regions that end at end of line - } + if (j==0 && in_region>=0 && color_regions[in_region].line_only) { + in_region=-1; //reset regions that end at end of line + } - if (is_symbol && cri_map.has(j)) { + if (is_symbol && cri_map.has(j)) { - const Text::ColorRegionInfo &cri=cri_map[j]; + const Text::ColorRegionInfo &cri=cri_map[j]; - if (in_region==-1) { + if (in_region==-1) { - if (!cri.end) { + if (!cri.end) { - in_region=cri.region; - } - } else if (in_region==cri.region && !color_regions[cri.region].line_only) { //ignore otherwise + in_region=cri.region; + } + } else if (in_region==cri.region && !color_regions[cri.region].line_only) { //ignore otherwise - if (cri.end || color_regions[cri.region].eq) { + if (cri.end || color_regions[cri.region].eq) { - deregion=color_regions[cri.region].eq?color_regions[cri.region].begin_key.length():color_regions[cri.region].end_key.length(); - } - } - } + deregion=color_regions[cri.region].eq?color_regions[cri.region].begin_key.length():color_regions[cri.region].end_key.length(); + } + } + } - if (!is_char) - in_keyword=false; + if (!is_char) + in_keyword=false; - if (in_region==-1 && !in_keyword && is_char && !prev_is_char) { + if (in_region==-1 && !in_keyword && is_char && !prev_is_char) { - int to=j; - while(_is_text_char(str[to]) && to=0) - color=color_regions[in_region].color; - else if (in_keyword) - color=keyword_color; - else if (is_symbol) - color=symbol_color; + if (in_region>=0) + color=color_regions[in_region].color; + else if (in_keyword) + color=keyword_color; + else if (is_symbol) + color=symbol_color; - prev_is_char=is_char; + prev_is_char=is_char; - } - int char_w; + } + int char_w; - //handle tabulator + //handle tabulator - if (str[j]=='\t') { - int left = char_ofs%tab_w; - if (left==0) - char_w=tab_w; - else - char_w=tab_w-char_ofs%tab_w; // is right... + if (str[j]=='\t') { + int left = char_ofs%tab_w; + if (left==0) + char_w=tab_w; + else + char_w=tab_w-char_ofs%tab_w; // is right... - } else { - char_w=cache.font->get_char_size(str[j],str[j+1]).width; - } + } else { + char_w=cache.font->get_char_size(str[j],str[j+1]).width; + } - if ( (char_ofs+char_margin)=xmargin_end) { - if (syntax_coloring) - continue; - else - break; - } + if ( (char_ofs+char_margin+char_w)>=xmargin_end) { + if (syntax_coloring) + continue; + else + break; + } - bool in_selection = (selection.active && line>=selection.from_line && line<=selection.to_line && (line>selection.from_line || j>=selection.from_column) && (line=selection.from_line && line<=selection.to_line && (line>selection.from_line || j>=selection.from_column) && (linecanvas_item_add_rect(ci,Rect2(Point2i( char_ofs+char_margin, ofs_y ), Size2i(char_w,get_row_height())),cache.selection_color); - } + if (in_selection) { + //inside selection! + VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(Point2i( char_ofs+char_margin, ofs_y ), Size2i(char_w,get_row_height())),cache.selection_color); + } - if (str[j]>=32) - cache.font->draw_char(ci,Point2i( char_ofs+char_margin, ofs_y+ascent),str[j],str[j+1],in_selection?cache.font_selected_color:color); - else if (draw_tabs && str[j]=='\t') { - int yofs= (get_row_height() - cache.tab_icon->get_height())/2; - cache.tab_icon->draw(ci, Point2(char_ofs+char_margin,ofs_y+yofs),in_selection?cache.font_selected_color:color); - } + if (str[j]>=32) + cache.font->draw_char(ci,Point2i( char_ofs+char_margin, ofs_y+ascent),str[j],str[j+1],in_selection?cache.font_selected_color:color); + else if (draw_tabs && str[j]=='\t') { + int yofs= (get_row_height() - cache.tab_icon->get_height())/2; + cache.tab_icon->draw(ci, Point2(char_ofs+char_margin,ofs_y+yofs),in_selection?cache.font_selected_color:color); + } - if (cursor.column==j && cursor.line==line) { + if (cursor.column==j && cursor.line==line) { - cursor_pos = Point2i( char_ofs+char_margin, ofs_y ); - VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cursor_pos, Size2i(1,get_row_height())),cache.font_color); + cursor_pos = Point2i( char_ofs+char_margin, ofs_y ); + VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cursor_pos, Size2i(1,get_row_height())),cache.font_color); - } - char_ofs+=char_w; + } + char_ofs+=char_w; - } + } - if (cursor.column==str.length() && cursor.line==line) { + if (cursor.column==str.length() && cursor.line==line) { - cursor_pos=Point2i( char_ofs+char_margin, ofs_y ); - VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cursor_pos, Size2i(1,get_row_height())),cache.font_color); + cursor_pos=Point2i( char_ofs+char_margin, ofs_y ); + VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(cursor_pos, Size2i(1,get_row_height())),cache.font_color); - } - } + } + } - if (completion_active) { - // code completion box - Ref csb = get_stylebox("completion"); - Ref csel = get_stylebox("completion_selected"); - int maxlines = get_constant("completion_lines"); - int cmax_width = get_constant("completion_max_width")*cache.font->get_char_size('x').x; - Color existing = get_color("completion_existing"); - int scrollw = get_constant("completion_scroll_width"); - Color scrollc = get_color("completion_scroll_color"); + if (completion_active) { + // code completion box + Ref csb = get_stylebox("completion"); + Ref csel = get_stylebox("completion_selected"); + int maxlines = get_constant("completion_lines"); + int cmax_width = get_constant("completion_max_width")*cache.font->get_char_size('x').x; + Color existing = get_color("completion_existing"); + int scrollw = get_constant("completion_scroll_width"); + Color scrollc = get_color("completion_scroll_color"); - int lines = MIN(completion_options.size(),maxlines); - int w=0; - int h=lines*get_row_height(); - int nofs = cache.font->get_string_size(completion_base).width; + int lines = MIN(completion_options.size(),maxlines); + int w=0; + int h=lines*get_row_height(); + int nofs = cache.font->get_string_size(completion_base).width; - if (completion_options.size() < 50) { - for(int i=0;iget_string_size(completion_options[i]).x,cmax_width); - if (w2>w) - w=w2; - } - } else { - w=cmax_width; - } - int th = h + csb->get_minimum_size().y; - if (cursor_pos.y+get_row_height()+th > get_size().height) { - completion_rect.pos.y=cursor_pos.y-th; - } else { - completion_rect.pos.y=cursor_pos.y+get_row_height()+csb->get_offset().y; - } + if (completion_options.size() < 50) { + for(int i=0;iget_string_size(completion_options[i]).x,cmax_width); + if (w2>w) + w=w2; + } + } else { + w=cmax_width; + } - if (cursor_pos.x-nofs+w+scrollw > get_size().width) { - completion_rect.pos.x=get_size().width-w-scrollw; - } else { - completion_rect.pos.x=cursor_pos.x-nofs; - } + int th = h + csb->get_minimum_size().y; + if (cursor_pos.y+get_row_height()+th > get_size().height) { + completion_rect.pos.y=cursor_pos.y-th; + } else { + completion_rect.pos.y=cursor_pos.y+get_row_height()+csb->get_offset().y; - completion_rect.size.width=w; - completion_rect.size.height=h; - if (completion_options.size()<=maxlines) - scrollw=0; + } - draw_style_box(csb,Rect2(completion_rect.pos-csb->get_offset(),completion_rect.size+csb->get_minimum_size()+Size2(scrollw,0))); + if (cursor_pos.x-nofs+w+scrollw > get_size().width) { + completion_rect.pos.x=get_size().width-w-scrollw; + } else { + completion_rect.pos.x=cursor_pos.x-nofs; + } + completion_rect.size.width=w; + completion_rect.size.height=h; + if (completion_options.size()<=maxlines) + scrollw=0; - int line_from = CLAMP(completion_index - lines/2, 0, completion_options.size() - lines); - draw_style_box(csel,Rect2(Point2(completion_rect.pos.x,completion_rect.pos.y+(completion_index-line_from)*get_row_height()),Size2(completion_rect.size.width,get_row_height()))); + draw_style_box(csb,Rect2(completion_rect.pos-csb->get_offset(),completion_rect.size+csb->get_minimum_size()+Size2(scrollw,0))); - draw_rect(Rect2(completion_rect.pos,Size2(nofs,completion_rect.size.height)),existing); - for(int i=0;i= completion_options.size()); - draw_string(cache.font,Point2(completion_rect.pos.x,completion_rect.pos.y+i*get_row_height()+cache.font->get_ascent()),completion_options[l],cache.font_color,completion_rect.size.width); - } + draw_rect(Rect2(completion_rect.pos,Size2(nofs,completion_rect.size.height)),existing); - if (scrollw) { - //draw a small scroll rectangle to show a position in the options - float r = maxlines / (float)completion_options.size(); - float o = line_from / (float)completion_options.size(); - draw_rect(Rect2(completion_rect.pos.x+completion_rect.size.width,completion_rect.pos.y+o*completion_rect.size.y,scrollw,completion_rect.size.y*r),scrollc); - } + for(int i=0;i= completion_options.size()); + draw_string(cache.font,Point2(completion_rect.pos.x,completion_rect.pos.y+i*get_row_height()+cache.font->get_ascent()),completion_options[l],cache.font_color,completion_rect.size.width); + } - } + if (scrollw) { + //draw a small scroll rectangle to show a position in the options + float r = maxlines / (float)completion_options.size(); + float o = line_from / (float)completion_options.size(); + draw_rect(Rect2(completion_rect.pos.x+completion_rect.size.width,completion_rect.pos.y+o*completion_rect.size.y,scrollw,completion_rect.size.y*r),scrollc); + } + completion_line_ofs=line_from; + } - } break; - case NOTIFICATION_FOCUS_ENTER: { + if (completion_hint!="") { - if (OS::get_singleton()->has_virtual_keyboard()) - OS::get_singleton()->show_virtual_keyboard(get_text(),get_global_rect()); + Ref sb = get_stylebox("panel","TooltipPanel"); + Ref font = cache.font; + Color font_color = get_color("font_color","TooltipLabel"); - } break; - case NOTIFICATION_FOCUS_EXIT: { - if (OS::get_singleton()->has_virtual_keyboard()) - OS::get_singleton()->hide_virtual_keyboard(); + int max_w=0; + int sc = completion_hint.get_slice_count("\n"); + int offset=0; + int spacing=0; + for(int i=0;iget_string_size(l).x; + max_w = MAX(len,max_w); + if (i==0) { + offset = font->get_string_size(l.substr(0,l.find(String::chr(0xFFFF)))).x; + } else { + spacing+=cache.line_spacing; + } - } + + } + + + + Size2 size = Size2(max_w,sc*font->get_height()+spacing); + Size2 minsize = size+sb->get_minimum_size(); + + + if (completion_hint_offset==-0xFFFF) { + completion_hint_offset=cursor_pos.x-offset; + } + + + Point2 hint_ofs = Vector2(completion_hint_offset,cursor_pos.y-minsize.y); + draw_style_box(sb,Rect2(hint_ofs,minsize)); + + spacing=0; + for(int i=0;iget_string_size(l.substr(0,l.find(String::chr(0xFFFF)))).x; + end = font->get_string_size(l.substr(0,l.rfind(String::chr(0xFFFF)))).x; + } + + draw_string(font,hint_ofs+sb->get_offset()+Vector2(0,font->get_ascent()+font->get_height()*i+spacing),l.replace(String::chr(0xFFFF),""),font_color); + if (end>0) { + Vector2 b = hint_ofs+sb->get_offset()+Vector2(begin,font->get_height()+font->get_height()*i+spacing-1); + draw_line(b,b+Vector2(end-begin,0),font_color); + } + spacing+=cache.line_spacing; + } + } + + + } break; + case NOTIFICATION_FOCUS_ENTER: { + + if (OS::get_singleton()->has_virtual_keyboard()) + OS::get_singleton()->show_virtual_keyboard(get_text(),get_global_rect()); + + } break; + case NOTIFICATION_FOCUS_EXIT: { + + if (OS::get_singleton()->has_virtual_keyboard()) + OS::get_singleton()->hide_virtual_keyboard(); + + } break; + + } } void TextEdit::_consume_pair_symbol(CharType ch) { @@ -918,6 +978,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { return; } else { _cancel_completion(); + _cancel_code_hint(); } if (mb.pressed) { @@ -1172,6 +1233,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { } _cancel_completion(); + } /* TEST CONTROL FIRST!! */ @@ -1268,6 +1330,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { break; unselect=true; break; + default: if (k.unicode>=32 && !k.mod.command && !k.mod.alt && !k.mod.meta) clear=true; @@ -1318,6 +1381,13 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { _push_current_op(); } break; + case KEY_ESCAPE: { + if (completion_hint!="") { + completion_hint=""; + update(); + + } + } break; case KEY_TAB: { if (readonly) @@ -1454,6 +1524,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { if (k.mod.shift) _post_shift_selection(); + _cancel_code_hint(); } break; case KEY_DOWN: { @@ -1473,6 +1544,7 @@ void TextEdit::_input_event(const InputEvent& p_input_event) { if (k.mod.shift) _post_shift_selection(); + _cancel_code_hint(); } break; @@ -2333,6 +2405,30 @@ String TextEdit::get_text() { }; +String TextEdit::get_text_for_completion() { + + String longthing; + int len = text.size(); + for (int i=0;i0 && l[cofs-1]>32 && !_is_symbol(l[cofs-1])) { - s=String::chr(l[cofs-1])+s; + + while(cofs>0 && l[cofs-1]>32 && _is_completable(l[cofs-1])) { + s=String::chr(l[cofs-1])+s; + if (l[cofs-1]=='\'' || l[cofs-1]=='"') + break; + cofs--; } + update(); if (s=="" && (cofs==0 || !completion_prefixes.has(String::chr(l[cofs-1])))) { @@ -3055,36 +3174,24 @@ void TextEdit::_update_completion_candidates() { completion_enabled=true; } + + void TextEdit::query_code_comple() { - String l = text[cursor.line]; - int ofs = CLAMP(cursor.column,0,l.length()); - String cs; - while(ofs>0 && l[ofs-1]>32) { - - if (_is_symbol(l[ofs-1])) { - String s; - while(ofs>0 && l[ofs-1]>32 && _is_symbol(l[ofs-1])) { - s=String::chr(l[ofs-1])+s; - ofs--; - } - if (completion_prefixes.has(s)) - cs=s+cs; - else - break; - } else { + String l = text[cursor.line]; + int ofs = CLAMP(cursor.column,0,l.length()); - cs=String::chr(l[ofs-1])+cs; - ofs--; - } + if (ofs>0 && (_is_completable(l[ofs-1]) || completion_prefixes.has(String::chr(l[ofs-1])))) + emit_signal("request_completion"); - } +} - if (cs!="") { - emit_signal("request_completion",cs,cursor.line); - } +void TextEdit::set_code_hint(const String& p_hint) { + completion_hint=p_hint; + completion_hint_offset=-0xFFFF; + update(); } void TextEdit::code_complete(const Vector &p_strings) { @@ -3236,7 +3343,7 @@ void TextEdit::_bind_methods() { ADD_SIGNAL(MethodInfo("cursor_changed")); ADD_SIGNAL(MethodInfo("text_changed")); - ADD_SIGNAL(MethodInfo("request_completion",PropertyInfo(Variant::STRING,"keyword"),PropertyInfo(Variant::INT,"line"))); + ADD_SIGNAL(MethodInfo("request_completion")); } -- cgit v1.2.3