Author Topic: Minor "bug" in automatic indenting of braces  (Read 6852 times)

Offline Ceniza

  • Developer
  • Lives here!
  • *****
  • Posts: 1441
    • CenizaSOFT
Minor "bug" in automatic indenting of braces
« 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 :)

Offline danselmi

  • Developer
  • Almost regular
  • *****
  • Posts: 206
Re: Minor "bug" in automatic indenting of braces
« Reply #1 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.

Offline Ceniza

  • Developer
  • Lives here!
  • *****
  • Posts: 1441
    • CenizaSOFT
Re: Minor "bug" in automatic indenting of braces
« Reply #2 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

Offline danselmi

  • Developer
  • Almost regular
  • *****
  • Posts: 206
Re: Minor "bug" in automatic indenting of braces
« Reply #3 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.

Offline MortenMacFly

  • Administrator
  • Lives here!
  • *****
  • Posts: 9723
Re: Minor "bug" in automatic indenting of braces
« Reply #4 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;
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: https://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: https://wiki.codeblocks.org/index.php?title=FAQ

Offline danselmi

  • Developer
  • Almost regular
  • *****
  • Posts: 206
Re: Minor "bug" in automatic indenting of braces
« Reply #5 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.

Offline Ceniza

  • Developer
  • Lives here!
  • *****
  • Posts: 1441
    • CenizaSOFT
Re: Minor "bug" in automatic indenting of braces
« Reply #6 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.

Offline Ceniza

  • Developer
  • Lives here!
  • *****
  • Posts: 1441
    • CenizaSOFT
Re: Minor "bug" in automatic indenting of braces
« Reply #7 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.

Offline Ceniza

  • Developer
  • Lives here!
  • *****
  • Posts: 1441
    • CenizaSOFT
Re: Minor "bug" in automatic indenting of braces
« Reply #8 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: