Code::Blocks Forums

Developer forums (C::B DEVELOPMENT STRICTLY!) => Development => Topic started by: Ceniza on November 25, 2008, 07:27:34 pm

Title: Minor "bug" in automatic indenting of braces
Post by: Ceniza on November 25, 2008, 07:27:34 pm
It's been a while since I noticed this little inconvenience, but I think it's never too late to comment about it.

Code::Blocks tries to be smart by automatically indenting the next line of code if what you just wrote is an opening brace '{', and it also tries to be smart by putting the closing brace '}' at the same level. However, if you have an opening brace followed by a closing brace, and you press enter when the cursor is in the middle, you end up with the closing brace being indented. I'm quite sure the fix is very simple, when you know the right place to look for it. I would love to fix this myself, but only pin-pointing the right place to look for it would take me quite some time, which I don't really have now. I may have some time this Thursday to look into it, but if someone else feels like fixing a bug that sounds quite simple, go ahead :)
Title: Re: Minor "bug" in automatic indenting of braces
Post by: danselmi on November 25, 2008, 08:33:27 pm
Hi

With this patch:
Code
--- cbeditor.cpp	(revision 5322)
+++ cbeditor.cpp (working copy)
@@ -2574,7 +2574,7 @@
                 switch(control->GetLexer())
                 {
                     case wxSCI_LEX_CPP:
-                        if (b == _T('{'))
+                        if ( b == _T('{') && control->GetCharAt(pos) != _T('}') )
                         {
smart-indent will work as expected if the closing brace is immediately behind
the cursor before pressing enter. I'm able to prepare a version which is
checking the next non blank char, if you think this is needed.
Title: Re: Minor "bug" in automatic indenting of braces
Post by: Ceniza on November 25, 2008, 09:25:21 pm
One that checks the next non-blank character sounds good, if it also removes those blank characters in between. At least you have found the right place to modify that behavior :D
Title: Re: Minor "bug" in automatic indenting of braces
Post by: danselmi on November 26, 2008, 01:17:35 pm
Hi

This patch
Code
--- cbeditor.cpp	(revision 5318)
+++ cbeditor.cpp (working copy)
@@ -172,7 +172,31 @@
         }
         return 0;
     }
+    wxChar  GetNextNonWhitespaceCharOfLine(int position = -1, int *pos = 0)
+    {
+        cbStyledTextCtrl* control = m_pOwner->GetControl();
+        if (position == -1)
+            position = control->GetCurrentPos();
 
+        while (position < control->GetLength())
+        {
+            wxChar c = control->GetCharAt(position);
+            if ( c == _T('\n') || c ==  _T('\r') )
+            {
+                if ( pos ) *pos = position;
+                return 0;
+            }
+            if ( c !=  _T(' ') && c != _T('\t') )
+            {
+                if ( pos ) *pos = position;
+                return c;
+            }
+            position++;
+        }
+
+        return 0;
+    }
+
     int FindBlockStart(int position, wxChar blockStart, wxChar blockEnd, bool skipNested = true)
     {
         cbStyledTextCtrl* control = m_pOwner->GetControl();
@@ -2571,15 +2595,25 @@
 
                 // SMART INDENTING - THIS IS LANGUAGE SPECIFIC, BUT CURRENTLY ONLY IMPLEMENTED FOR C/C++ AND PYTHON
                 wxChar b = m_pData->GetLastNonWhitespaceChar();
+                int nonblankpos;
+                wxChar c = m_pData->GetNextNonWhitespaceCharOfLine(pos, &nonblankpos);
                 switch(control->GetLexer())
                 {
                     case wxSCI_LEX_CPP:
                         if (b == _T('{'))
                         {
-                            if(control->GetUseTabs())
-                                indent << _T('\t'); // 1 tab
+                            if ( c != _T('}') )
+                            {
+                                if(control->GetUseTabs())
+                                    indent << _T('\t'); // 1 tab
+                                else
+                                    indent << wxString(_T(' '), control->GetTabWidth()); // n spaces
+                            }
                             else
-                                indent << wxString(_T(' '), control->GetTabWidth()); // n spaces
+                            {
+                                control->SetCurrentPos(nonblankpos);
+                                control->DeleteBack();
+                            }
                         }
                         break;
will search for the next non blank char on the line and removes these blank chars.
Title: Re: Minor "bug" in automatic indenting of braces
Post by: MortenMacFly on November 26, 2008, 04:26:11 pm
This patch
Code
+                int nonblankpos;
+                wxChar c = m_pData->GetNextNonWhitespaceCharOfLine(pos, &nonblankpos);
I would do this calculation inside the switch clause for the cpp lexter and after (inside) the check for the opening bracket to minimise CPU load like this:
Code
                    case wxSCI_LEX_CPP:
                        if (b == _T('{'))
                        {
                            int nonblankpos;
                            wxChar c = m_pData->GetNextNonWhitespaceCharOfLine(pos, &nonblankpos);
                            if (c != _T('}'))
                            {
                                if(control->GetUseTabs())
                                    indent << _T('\t'); // 1 tab
                                else
                                    indent << wxString(_T(' '), control->GetTabWidth()); // n spaces
                            }
                            else
                            {
                                control->SetCurrentPos(nonblankpos);
                                control->DeleteBack();
                            }
                        }
                        break;
Title: Re: Minor "bug" in automatic indenting of braces
Post by: danselmi on November 26, 2008, 06:20:39 pm
you are right:
Code
--- cbeditor.cpp	(revision 5318)
+++ cbeditor.cpp (working copy)
@@ -172,7 +172,31 @@
         }
         return 0;
     }
+    wxChar  GetNextNonWhitespaceCharOfLine(int position = -1, int *pos = 0)
+    {
+        cbStyledTextCtrl* control = m_pOwner->GetControl();
+        if (position == -1)
+            position = control->GetCurrentPos();
 
+        while (position < control->GetLength())
+        {
+            wxChar c = control->GetCharAt(position);
+            if ( c == _T('\n') || c ==  _T('\r') )
+            {
+                if ( pos ) *pos = position;
+                return 0;
+            }
+            if ( c !=  _T(' ') && c != _T('\t') )
+            {
+                if ( pos ) *pos = position;
+                return c;
+            }
+            position++;
+        }
+
+        return 0;
+    }
+
     int FindBlockStart(int position, wxChar blockStart, wxChar blockEnd, bool skipNested = true)
     {
         cbStyledTextCtrl* control = m_pOwner->GetControl();
@@ -2576,10 +2600,23 @@
                     case wxSCI_LEX_CPP:
                         if (b == _T('{'))
                         {
-                            if(control->GetUseTabs())
-                                indent << _T('\t'); // 1 tab
+                            int nonblankpos;
+                            wxChar c = m_pData->GetNextNonWhitespaceCharOfLine(pos, &nonblankpos);
+                            if ( c != _T('}') )
+                            {
+                                if(control->GetUseTabs())
+                                    indent << _T('\t'); // 1 tab
+                                else
+                                    indent << wxString(_T(' '), control->GetTabWidth()); // n spaces
+                            }
                             else
-                                indent << wxString(_T(' '), control->GetTabWidth()); // n spaces
+                            {
+                                if ( pos != nonblankpos )
+                                {
+                                    control->SetCurrentPos(nonblankpos);
+                                    control->DeleteBack();
+                                }
+                            }
                         }
                         break;
this should also work if there are not blanks after the cursor.
Title: Re: Minor "bug" in automatic indenting of braces
Post by: Ceniza on November 26, 2008, 08:30:31 pm
It's nice to see it's getting somewhere. I hope I have the time tomorrow to check it, unless someone else decides to commit it.
Title: Re: Minor "bug" in automatic indenting of braces
Post by: Ceniza on November 27, 2008, 10:09:36 pm
Sorry, I didn't have the time to check it today... as I expected, and now it's time for me to go to bed.

Hopefully, I'll have some time this weekend.
Title: Re: Minor "bug" in automatic indenting of braces
Post by: Ceniza on December 05, 2008, 09:12:54 am
Well, I finally had the time to check the patch and test it. It's now applied in revision 5328. Thanks danselmi :wink: