Code::Blocks Forums

Developer forums (C::B DEVELOPMENT STRICTLY!) => Development => CodeCompletion redesign => Topic started by: ollydbg on April 05, 2009, 04:17:44 pm

Title: BraceCompletion patch to improve Code Completion
Post by: ollydbg on April 05, 2009, 04:17:44 pm
Hi, blueshake has just built a patch to do BraceCompletion. I have applied in my local copy and tested it. It works Great! Thanks blueshake for your patch. (He has some difficulty to post these code, So, I wrote this post instead).

Here is his patch:
Code
Index: src/plugins/codecompletion/codecompletion.cpp
===================================================================
--- src/plugins/codecompletion/codecompletion.cpp (revision 5519)
+++ src/plugins/codecompletion/codecompletion.cpp (working copy)
@@ -1876,6 +1876,17 @@
 //    else if (event.GetEventType() == wxEVT_SCI_MODIFIED)
 //        Manager::Get()->GetLogManager()->DebugLog(_T("wxEVT_SCI_MODIFIED"));
 
+//do this when the [ { ( " ' were typed
+
+    if (event.GetEventType() == wxEVT_SCI_CHARADDED)
+        {
+            m_timerCodeCompletion.Stop();
+            wxChar ch = event.GetKey();
+            DoBraceCompletion(control, ch);
+            //event.Skip();
+        }
+/////////////////////////////////
+
     if (event.GetEventType() == wxEVT_SCI_CHARADDED &&
         !control->AutoCompActive()) // not already active autocompletion
     {
@@ -1886,9 +1897,10 @@
         int wordstart = control->WordStartPosition(pos, true);
 
         // if more than two chars have been typed, invoke CC
+        ////////////////////////////////
         int autoCCchars = cfg->ReadInt(_T("/auto_launch_chars"), 4);
         bool autoCC = cfg->ReadBool(_T("/auto_launch"), true) &&
-                    pos - wordstart >= autoCCchars;
+                   pos - wordstart >= autoCCchars;
 
         // update calltip highlight while we type
         if (control->CallTipActive())
@@ -2008,3 +2020,77 @@
 {
     // nothing for now
 }
+
+void CodeCompletion::DoBraceCompletion(cbStyledTextCtrl* control, const wxChar& ch)
+{
+    int pos = control->GetCurrentPos();
+    int style = control->GetStyleAt(pos);
+    if (style == wxSCI_C_COMMENT || style == wxSCI_C_COMMENTLINE)
+        {
+            return;
+        }
+    if (ch == _T('\'') )//&& style != || ch == _T('"') )
+        {
+            if (control->GetCharAt(pos) == ch)
+            {
+                control->DeleteBack();
+                control->GotoPos(pos);
+                return;
+            }
+            else
+            {
+                if (style == wxSCI_C_STRING)
+                    return;
+                control->AddText(ch);
+                control->GotoPos(pos);
+                return;
+            }
+        }
+    if (ch == _T('"'))
+        {
+            if (control->GetCharAt(pos) == ch)
+            {
+                control->DeleteBack();
+                control->GotoPos(pos);
+                return;
+            }
+            else
+            {
+                if (style == wxSCI_C_CHARACTER)
+                    return;
+                control->AddText(ch);
+                control->GotoPos(pos);
+                return;
+            }
+        }
+    if (style == wxSCI_C_STRING || style == wxSCI_C_CHARACTER)
+        return;
+    wxString leftBrace(_T("([{"));
+    wxString rightBrace(_T(")]}"));
+    int index = leftBrace.find(ch);
+        if (index != wxNOT_FOUND)
+            {
+                control->AddText(rightBrace.GetChar(index));
+                control->GotoPos(pos);
+                if (ch == _T('{'))
+                {
+                    control->NewLine();
+                    control->GotoPos(pos);
+                    return;
+                }
+            }
+        else
+            {
+                index = rightBrace.find(ch);
+                if (index != wxNOT_FOUND)
+                    {
+                        if (control->GetCharAt(pos) == ch)
+                        {
+                            control->DeleteBack();
+                            control->GotoPos(pos);
+                            return;
+                        }
+
+                    }
+            }
+}
Index: src/plugins/codecompletion/codecompletion.h
===================================================================
--- src/plugins/codecompletion/codecompletion.h (revision 5519)
+++ src/plugins/codecompletion/codecompletion.h (working copy)
@@ -115,7 +115,7 @@
         void OnStartParsingFunctions(wxTimerEvent& event);
         void OnFunction(wxCommandEvent& event);
         void ParseFunctionsAndFillToolbar(bool force = false);
-
+        void DoBraceCompletion(cbStyledTextCtrl* control, const wxChar& ch);
         int m_PageIndex;
         bool m_InitDone;
 



Thanks for testing! :D See the screen shot.

After enter "{", another "}" will be automatically added. So does (  [  "




[attachment deleted by admin]
Title: Re: BraceCompletion patch to improve Code Completion
Post by: killerbot on April 05, 2009, 05:31:58 pm
I have applied it in my local copy, a little bit modified (indentation issues in the patch, not in the meaning of the new code ;-) ).
Seems to work nice.
I will test it a in my production system, when I don't find any shot term issues, I will commit this.

Thanks for the contribution !!!!!!!!!!!!
Title: Re: BraceCompletion patch to improve Code Completion
Post by: danselmi on April 05, 2009, 07:55:19 pm
I also applied is on my local copy.

1.: It works great as long as you edit c/c++ sources. I also use cb to edit other sources, where the ' is used to access attributes. I think, we have to check which lexer is configured.
2.: I believe that this code better suits to "smart indenting" (as Ceniza mentioned int this post http://forums.codeblocks.org/index.php/topic,9820.0.html (http://forums.codeblocks.org/index.php/topic,9820.0.html)) than to cc.

regards danselmi
Title: Re: BraceCompletion patch to improve Code Completion
Post by: killerbot on April 05, 2009, 09:35:00 pm
to have all references together (see also) : http://forums.codeblocks.org/index.php/topic,8803.0.html


Though I think that adding to CC could be the first step until a more fundamental refactoring can be done.
Title: Re: BraceCompletion patch to improve Code Completion
Post by: mandrav on April 06, 2009, 09:54:26 am
Though I think that adding to CC could be the first step until a more fundamental refactoring can be done.

Agreed for the refactoring but until then, smart-indenting is the place to put it in.
Title: Re: BraceCompletion patch to improve Code Completion
Post by: danselmi on April 06, 2009, 11:42:30 pm
I modified your patch:
Code
Index: sdk/cbeditor.cpp
===================================================================
--- sdk/cbeditor.cpp (revision 5539)
+++ sdk/cbeditor.cpp (working copy)
@@ -221,6 +221,135 @@
         return -1;
     }
 
+    bool IsComment( int style )
+    {
+        cbStyledTextCtrl* control = m_pOwner->GetControl();
+        switch ( control->GetLexer() )
+        {
+            case wxSCI_LEX_CPP:
+                return  style == wxSCI_C_COMMENT ||
+                        style == wxSCI_C_COMMENTLINE ||
+                        style == wxSCI_C_COMMENTDOC ||
+                        style == wxSCI_C_COMMENTDOCKEYWORD ||
+                        style == wxSCI_C_COMMENTDOCKEYWORDERROR ||
+                        style == wxSCI_C_COMMENTLINEDOC;
+            case wxSCI_LEX_D:
+                return  style == wxSCI_D_COMMENT ||
+                        style == wxSCI_D_COMMENTLINE ||
+                        style == wxSCI_D_COMMENTDOC ||
+                        style == wxSCI_D_COMMENTDOCKEYWORD ||
+                        style == wxSCI_D_COMMENTDOCKEYWORDERROR ||
+                        style == wxSCI_D_COMMENTLINEDOC;
+            default:
+                return false;
+        }
+        return false;
+    }
+    bool IsPreprocessor( int style )
+    {
+        cbStyledTextCtrl* control = m_pOwner->GetControl();
+        if ( control->GetLexer() == wxSCI_LEX_CPP )
+            return  style == wxSCI_C_PREPROCESSOR;
+        return false;
+    }
+    bool IsCharacterOrString( int  style )
+    {
+        cbStyledTextCtrl* control = m_pOwner->GetControl();
+        switch ( control->GetLexer() )
+        {
+            case wxSCI_LEX_CPP:
+                return style == wxSCI_C_STRING || style == wxSCI_C_CHARACTER;
+            case wxSCI_LEX_D:
+                return style == wxSCI_D_STRING || style == wxSCI_D_CHARACTER;
+            default:
+                return false;
+        }
+        return false;
+    }
+    bool IsCharacter( int  style )
+    {
+        cbStyledTextCtrl* control = m_pOwner->GetControl();
+        switch ( control->GetLexer() )
+        {
+            case wxSCI_LEX_CPP:
+                return style == wxSCI_C_CHARACTER;
+            case wxSCI_LEX_D:
+                return style == wxSCI_D_CHARACTER;
+            default:
+                return false;
+        }
+        return false;
+    }
+    void DoBraceCompletion(const wxChar& ch)
+    {
+        cbStyledTextCtrl* control = m_pOwner->GetControl();
+        int pos = control->GetCurrentPos();
+        int style = control->GetStyleAt(pos);
+        if ( IsComment(style) || IsPreprocessor(style) )
+            return;
+        if ( ch == _T('\'') )
+        {
+            if ( control->GetCharAt(pos) == ch && pos > 1 && control->GetCharAt(pos-2) != _T('\\') )
+            {
+                control->DeleteBack();
+                control->GotoPos(pos);
+            }
+            else
+            {
+                if ( control->GetCharAt(pos-2) == _T('\\') || IsCharacterOrString(style) )
+                    return;
+                control->AddText(ch);
+                control->GotoPos(pos);
+            }
+            return;
+        }
+        if ( ch == _T('"') )
+        {
+            if (control->GetCharAt(pos) == ch && pos > 1 && control->GetCharAt(pos-2) != _T('\\') )
+            {
+                control->DeleteBack();
+                control->GotoPos(pos);
+            }
+            else
+            {
+                if ( control->GetCharAt(pos-2) == _T('\\') || IsCharacter(style) )
+                    return;
+                control->AddText(ch);
+                control->GotoPos(pos);
+            }
+            return;
+        }
+        if ( IsCharacterOrString(style) )
+            return;
+        wxString leftBrace(_T("([{"));
+        wxString rightBrace(_T(")]}"));
+        int index = leftBrace.find(ch);
+        if (index != wxNOT_FOUND)
+        {
+            control->AddText(rightBrace.GetChar(index));
+            control->GotoPos(pos);
+            if (ch == _T('{'))
+            {
+                control->NewLine();
+                control->GotoPos(pos);
+                return;
+            }
+        }
+        else
+        {
+            index = rightBrace.find(ch);
+            if (index != wxNOT_FOUND)
+            {
+                if (control->GetCharAt(pos) == ch)
+                {
+                    control->DeleteBack();
+                    control->GotoPos(pos);
+                    return;
+                }
+            }
+        }
+    }
+
     /** Strip Trailing Blanks before saving */
     void StripTrailingSpaces()
     {
@@ -2787,6 +2916,13 @@
         }
     }
 
+    bool braceCompletion = Manager::Get()->GetConfigManager(_T("editor"))->ReadBool(_T("/brace_completion"), true);
+    if ( braceCompletion )
+    {
+        if ( control->GetLexer() == wxSCI_LEX_CPP || control->GetLexer() == wxSCI_LEX_D )
+            m_pData->DoBraceCompletion( ch );
+    }
+
     OnScintillaEvent(event);
 }
 
Index: sdk/editorconfigurationdlg.cpp
===================================================================
--- sdk/editorconfigurationdlg.cpp (revision 5539)
+++ sdk/editorconfigurationdlg.cpp (working copy)
@@ -106,6 +106,7 @@
 
     XRCCTRL(*this, "chkAutoIndent", wxCheckBox)->SetValue(cfg->ReadBool(_T("/auto_indent"), true));
     XRCCTRL(*this, "chkSmartIndent", wxCheckBox)->SetValue(cfg->ReadBool(_T("/smart_indent"), true));
+    XRCCTRL(*this, "chkBraceCompletion", wxCheckBox)->SetValue(cfg->ReadBool(_T("/brace_completion"), true));
     XRCCTRL(*this, "chkUseTab", wxCheckBox)->SetValue(cfg->ReadBool(_T("/use_tab"), false));
     m_EnableScrollWidthTracking = cfg->ReadBool(_T("/margin/scroll_width_tracking"), false);
     XRCCTRL(*this, "chkScrollWidthTracking", wxCheckBox)->SetValue(m_EnableScrollWidthTracking);
@@ -863,6 +864,7 @@
 
         cfg->Write(_T("/auto_indent"),          XRCCTRL(*this, "chkAutoIndent", wxCheckBox)->GetValue());
         cfg->Write(_T("/smart_indent"),         XRCCTRL(*this, "chkSmartIndent", wxCheckBox)->GetValue());
+        cfg->Write(_T("/brace_completion"),     XRCCTRL(*this, "chkBraceCompletion", wxCheckBox)->GetValue());
         cfg->Write(_T("/use_tab"),              XRCCTRL(*this, "chkUseTab", wxCheckBox)->GetValue());
         cfg->Write(_T("/show_indent_guides"),   XRCCTRL(*this, "chkShowIndentGuides", wxCheckBox)->GetValue());
         cfg->Write(_T("/tab_indents"),          XRCCTRL(*this, "chkTabIndents", wxCheckBox)->GetValue());
Index: sdk/resources/editor_configuration.xrc
===================================================================
--- sdk/resources/editor_configuration.xrc (revision 5539)
+++ sdk/resources/editor_configuration.xrc (working copy)
@@ -275,6 +275,13 @@
                               <flag>wxALIGN_LEFT|wxALIGN_TOP</flag>
                             </object>
                             <object class="sizeritem">
+                              <object class="wxCheckBox" name="chkBraceCompletion">
+                                <label>Brace completion</label>
+                                <checked>1</checked>
+                              </object>
+                              <flag>wxALIGN_LEFT|wxALIGN_TOP</flag>
+                            </object>
+                            <object class="sizeritem">
                               <object class="wxCheckBox" name="chkBackspaceUnindents">
                                 <label>Backspace unindents</label>
                                 <checked>1</checked>

Title: Re: BraceCompletion patch to improve Code Completion
Post by: killerbot on April 08, 2009, 09:07:00 am
ok, this modification is even better I think :-)

However I stumbled already on 1 issue !!

When you use " within a set of "" :

Example :

std::string Test = ""     <--------------- after i typed the first "

then i start typing in bewteen the ""

std::string Test = "This is "   <-------------------- all still ok

std::string Test = "This is \""   <---------- the \" will trigger things to go wrong
  it changes into : std::string Test = "This is \"  <------------- NOT ok

so I continue to type :
std::string Test = "This is \"my\"
 turns in to : std::string Test = "This is \"my\""  <----------- which is ok again

and I type some more :

std::string Test = "This is \"my\" test";  <--- ok : syntax correct

Now let's add also \"\" around the is (so not extending the ones around 'my') :

When I type the first part of it I get :
std::string Test = "This \""is \"my\" test"
where it should have been : std::string Test = "This \"is \"my\" test"

and when I type the end part the same thing occurs
std::string Test = "This \""is\"" \"my\" test"

So basically, when the " is escaped (\) don't do the special stuff ;-)


PS : I think it should also be active for :
 - C language (or is that part of the CPP lexer)
 - java code/lexer


PS2 : this evening I will apply the modified patch in my private build and test. In case of applying to the trunk I will now work based upon the modified patch, with the setting to enable/disable the functionality.
Title: Re: BraceCompletion patch to improve Code Completion
Post by: danselmi on April 08, 2009, 11:22:36 pm
Quote
ok, this modification is even better I think
kudos to blueshake! I only moved the code around.

Quote
PS : I think it should also be active for :
 - C language (or is that part of the CPP lexer)
Yes, C language is part of C++. Scintilla has no special lexer for java so the cpp lexer can be used to highlight java sources (adjust the lexer configuration "lexer_cpp.xml"). If scintilla is configured to use the cpp lexer for java sources then BraceCompletion will also work for that.

Quote
However I stumbled already on 1 issue !!
I tried to correct that (and updated my previous post).
Title: Re: BraceCompletion patch to improve Code Completion
Post by: killerbot on April 12, 2009, 01:19:02 pm
I have updated my test build with the updated patch code.
Everything still is fine :-)

The first issue I mentioned is solved, but the next issues still remain.

Quote
std::string Test = "This is \"my\" test";  <--- ok : syntax correct

Now let's add also \"\" around the is (so not extending the ones around 'my') :

When I type the first part of it I get :
std::string Test = "This \""is \"my\" test"
where it should have been : std::string Test = "This \"is \"my\" test"

and when I type the end part the same thing occurs
std::string Test = "This \""is\"" \"my\" test"

Most probably to solve this, the character in front should be checked, and when that is a '\' the code should stop issuing the completion part.
Title: Re: BraceCompletion patch to improve Code Completion
Post by: Ceniza on April 12, 2009, 03:52:01 pm
What about using current style information? If the double quote is typed inside a piece of text that is already marked as a string, do not complete. Comments could also be subject to this criteria. Just in case, by "current style information" I mean the style applied by Scintilla's lexer in the editor. No checking of previous characters required.
Title: Re: BraceCompletion patch to improve Code Completion
Post by: danselmi on April 22, 2009, 11:28:08 pm
Quote
the character in front should be checked, and when that is a '\' the code should stop issuing the completion part.
I updated my previous post and submitted the patch at berlios. patch id: 2746.

I also played around with the style information. It is not as easy as I expected: The style information reflects the state just after adding the character which triggers the BraceCompletion. So there are also checks needed about the style or character before the current position.