Author Topic: about bracecompletion  (Read 15931 times)

Offline blueshake

  • Regular
  • ***
  • Posts: 459
about bracecompletion
« on: August 17, 2009, 05:28:44 am »
hello, jens:
refer to visual assist,I do a fes modifications for bracecompletion.
two modificactions:
1. the { } will stay in the same line now if current line have other words.
2. if the current caret postion's next char is not empty,the bracecompletion will not work.
here is the patch.
Code
Index: cbeditor.cpp
===================================================================
--- cbeditor.cpp (revision 5731)
+++ cbeditor.cpp (working copy)
@@ -331,19 +331,26 @@
         }
         if ( IsCharacterOrString(style) )
             return;
-        wxString leftBrace(_T("([{"));
-        wxString rightBrace(_T(")]}"));
+        const wxString leftBrace(_T("([{"));
+        const wxString rightBrace(_T(")]}"));
         int index = leftBrace.find(ch);
-        if (index != wxNOT_FOUND)
+        //Manager::Get()->GetLogManager()->DebugLog(F(_T("current: %d"),control->GetCharAt(pos)));
+        //Manager::Get()->GetLogManager()->DebugLog(_T("current:")+control->GetCharAt(pos));
+        const wxString unWant(_T("\n\r\t\b "));
+        if (index != wxNOT_FOUND && unWant.find(control->GetCharAt(pos)) != wxNOT_FOUND)
         {
-            control->AddText(rightBrace.GetChar(index));
-            control->GotoPos(pos);
-            if (ch == _T('{'))
-            {
-                control->NewLine();
+                control->AddText(rightBrace.GetChar(index));
                 control->GotoPos(pos);
-                return;
-            }
+                if (ch == _T('{'))
+                {
+                    const wxRegEx reg(_T("^[ \t]*{}[ \t]*"));
+                    if (reg.Matches(control->GetCurLine()))
+                    {
+                        control->NewLine();
+                        control->GotoPos(pos);
+                        return;
+                    }
+                }
         }
         else
         {
Keep low and hear the sadness of little dog.
I fall in love with a girl,but I don't dare to tell her.What should I do?

Offline killerbot

  • Administrator
  • Lives here!
  • *****
  • Posts: 5491
Re: about bracecompletion
« Reply #1 on: August 17, 2009, 09:05:51 am »
could you give some examples of the improvements [before/after] ?

mariocup

  • Guest
Re: about bracecompletion
« Reply #2 on: August 17, 2009, 09:13:51 am »
Hi blueshake,

2. if the current caret postion's next char is not empty,the bracecompletion will not work.
here is the patch.

I agree that the bracecompletion should not work if the next char is not empty. For example if you have a statement like

Code
if (variable1 && variable2)

and now modify the condition

Code
if (variable1 && (

then I do not want to add instantly the closing bracket, since this is not the desired place.

Offline killerbot

  • Administrator
  • Lives here!
  • *****
  • Posts: 5491
Re: about bracecompletion
« Reply #3 on: August 17, 2009, 09:18:44 am »
but what if you have the following
Code
if(test1)

and you want to add something like

Code
&& (test2 || test3)

to obtain

Code
if(test1 && (test2 || test3))

then I want the "()"

mariocup

  • Guest
Re: about bracecompletion
« Reply #4 on: August 17, 2009, 10:23:21 am »
Hi killerbot,

this is desirable too, but not a contradiction if we modify the condition for adding braces.

For example if the next char is a closing brace and you add a new "(" then "()" can be inserted, but in a case like

Code
if (test && "(" test2)

the closing brace should not be added automatically in my eyes, since the user will have to delete the "unwanted" closing brace and this can be very annoying after some time and will not increase the productivity.


Offline blueshake

  • Regular
  • ***
  • Posts: 459
Re: about bracecompletion
« Reply #5 on: August 17, 2009, 11:55:39 am »
I think mariocup is right.
so these codes can be changed to be so.add a ) will work.
Code
const wxString unWant(_T(")\n\r\t\b "));
see my attachment.
snap1 is new one , the {} will stay in the some line.
snap3 is old one, the {} will stay in twol line.
snap2 is example ,the next char is m ,so bracecompletion will not work.it will work if next one is  enter whitesapce , tab or ) (new added).

[attachment deleted by admin]
« Last Edit: August 17, 2009, 11:57:11 am by blueshake »
Keep low and hear the sadness of little dog.
I fall in love with a girl,but I don't dare to tell her.What should I do?

Offline killerbot

  • Administrator
  • Lives here!
  • *****
  • Posts: 5491
Re: about bracecompletion
« Reply #6 on: August 17, 2009, 08:09:33 pm »
and what will happen in your code when :

Code
int main
{
Will the closing '}' end up on the next line ? I think it should.

Offline blueshake

  • Regular
  • ***
  • Posts: 459
Re: about bracecompletion
« Reply #7 on: August 18, 2009, 02:25:54 am »
yes,it will work like below.
Code
int main
{
}

hi, killerbot, have any plan to on this patch.
Keep low and hear the sadness of little dog.
I fall in love with a girl,but I don't dare to tell her.What should I do?

Offline killerbot

  • Administrator
  • Lives here!
  • *****
  • Posts: 5491
Re: about bracecompletion
« Reply #8 on: August 18, 2009, 09:09:29 am »
I just applied it to my local copy, and will test it out.

Offline blueshake

  • Regular
  • ***
  • Posts: 459
Re: about bracecompletion
« Reply #9 on: August 18, 2009, 09:14:14 am »
nice to hear that ,
here is my new patch.
the opening { work like this now ,it is more like what visual assist do.
see the attachment.
Code
Index: cbeditor.cpp
===================================================================
--- cbeditor.cpp (revision 5731)
+++ cbeditor.cpp (working copy)
@@ -331,19 +331,25 @@
         }
         if ( IsCharacterOrString(style) )
             return;
-        wxString leftBrace(_T("([{"));
-        wxString rightBrace(_T(")]}"));
+        const wxString leftBrace(_T("([{"));
+        const wxString rightBrace(_T(")]}"));
         int index = leftBrace.find(ch);
-        if (index != wxNOT_FOUND)
+        const wxString unWant(_T(")\n\r\t\b "));
+        if (index != wxNOT_FOUND && unWant.find(control->GetCharAt(pos)) != wxNOT_FOUND)
         {
-            control->AddText(rightBrace.GetChar(index));
-            control->GotoPos(pos);
-            if (ch == _T('{'))
-            {
-                control->NewLine();
+                control->AddText(rightBrace.GetChar(index));
                 control->GotoPos(pos);
-                return;
-            }
+                if (ch == _T('{'))
+                {
+                    const wxRegEx reg(_T("^[ \t]*{}[ \t]*"));
+                    if (reg.Matches(control->GetCurLine()))
+                    {
+                        control->NewLine();
+                        control->GotoPos(pos);
+                        control->NewLine();
+                        return;
+                    }
+                }
         }
         else
         {


[attachment deleted by admin]
Keep low and hear the sadness of little dog.
I fall in love with a girl,but I don't dare to tell her.What should I do?

Offline killerbot

  • Administrator
  • Lives here!
  • *****
  • Posts: 5491
Re: about bracecompletion
« Reply #10 on: August 18, 2009, 09:54:48 am »
updated my copy with your change.

I already have a first point of feedback :

the following no longer works :
Code
if( --> if()
then I change this into:
Code
if(true &&)
All is still OK, but now it goes wrong
Code
if(true && ()
--> I don't get the closing one !!! And in this case I do want it.

Offline blueshake

  • Regular
  • ***
  • Posts: 459
Re: about bracecompletion
« Reply #11 on: August 18, 2009, 10:27:15 am »
hi,killerbot,it work for me,
see my attachment.
when i type if( and closing ) will automaticlly add.
Code
if(true && |)
in the "|" positon ,i type ( and it work too.
can you just give me more informations?

[attachment deleted by admin]
Keep low and hear the sadness of little dog.
I fall in love with a girl,but I don't dare to tell her.What should I do?

Offline killerbot

  • Administrator
  • Lives here!
  • *****
  • Posts: 5491
Re: about bracecompletion
« Reply #12 on: August 18, 2009, 10:56:51 am »
I just tried it again, and again I end up with :
Code
if(true && ()

could you copy paste here the codesnippet you have of the method you changed, so not as a patch, but just plain code. Maybe I didn't apply your patch correctly ...

Offline blueshake

  • Regular
  • ***
  • Posts: 459
Re: about bracecompletion
« Reply #13 on: August 18, 2009, 11:39:40 am »
hi,killerbot,i paste the the codes,and upload the file as a attachment.

Code
    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;
        const wxString leftBrace(_T("([{"));
        const wxString rightBrace(_T(")]}"));
        int index = leftBrace.find(ch);
        const wxString unWant(_T(")\n\r\t\b "));
        if (index != wxNOT_FOUND && unWant.find(control->GetCharAt(pos)) != wxNOT_FOUND)
        {
                control->AddText(rightBrace.GetChar(index));
                control->GotoPos(pos);
                if (ch == _T('{'))
                {
                    const wxRegEx reg(_T("^[ \t]*{}[ \t]*"));
                    if (reg.Matches(control->GetCurLine()))
                    {
                        control->NewLine();
                        control->GotoPos(pos);
                        control->NewLine();
                        return;
                    }
                }
        }
        else
        {
            index = rightBrace.find(ch);
            if (index != wxNOT_FOUND)
            {
                if (control->GetCharAt(pos) == ch)
                {
                    control->DeleteBack();
                    control->GotoPos(pos);
                    return;
                }
            }
        }
    }

[attachment deleted by admin]
Keep low and hear the sadness of little dog.
I fall in love with a girl,but I don't dare to tell her.What should I do?

Offline killerbot

  • Administrator
  • Lives here!
  • *****
  • Posts: 5491
Re: about bracecompletion
« Reply #14 on: August 18, 2009, 01:05:30 pm »
I can confirm it works now.
I didn't have the ')' in :
Code
const wxString unWant(_T(")\n\r\t\b "));
   :oops:

Offline killerbot

  • Administrator
  • Lives here!
  • *****
  • Posts: 5491
Re: about bracecompletion
« Reply #15 on: August 18, 2009, 02:33:25 pm »
Would you agree to add to the ';' to the unWant list. I think it should be added.

I ran in to an issue like this.

Current code :
Code
m_Timer->IsEllapsed;

I add the ( :

Code
m_Timer->IsEllapsed(;

but nothing happens. With my change, it works ok, and one obtains :
Code
m_Timer->IsEllapsed();

The same could be sai for the ',' operator

Offline blueshake

  • Regular
  • ***
  • Posts: 459
Re: about bracecompletion
« Reply #16 on: August 18, 2009, 03:37:03 pm »
actually ,in visual assist ,if IsEllapsed is a function ,the () will be added automaticlly,so the ;
is not in the unWant list.
i try to make a patch  for codecompletion to implemet the function.and it is easy to.
but the problem is :
if the function have argument.so caret position should be like this.
IsEllapsed(|). and I have no any chance to get what exactly item is completed in suggestion list.
the caret can not goto the right postion when the fucntion has argument.
so i have no idea about this issue.just do it if it is necessary.
Keep low and hear the sadness of little dog.
I fall in love with a girl,but I don't dare to tell her.What should I do?

Offline killerbot

  • Administrator
  • Lives here!
  • *****
  • Posts: 5491
Re: about bracecompletion
« Reply #17 on: August 18, 2009, 03:47:37 pm »
our code completion currently just adds the function name, no (...).

Offline blueshake

  • Regular
  • ***
  • Posts: 459
Re: about bracecompletion
« Reply #18 on: August 19, 2009, 10:26:49 am »
hi,
recently,i am going to make a patch,its function is
when you delete a ([{ and the right char is )]} ,so the the relative one will be deleted too.
for example
Code
int main(|)
int the "|" position ,you delete "(" and the ")" should be deleted too.
but i face a problem,
it seems that these codes can not work.the caret moved,but the ) didn't be delete.
any one have any idea about this?
these codes seems not be executed .
Code
m_pControl->DeleteBack();

here are the codes.
Code
void cbEditor::OnEditorModified(wxScintillaEvent& event)
{
//    wxString txt = _T("OnEditorModified(): ");
//    int flags = event.GetModificationType();
//    if (flags & wxSCI_MOD_CHANGEMARKER) txt << _T("wxSCI_MOD_CHANGEMARKER, ");
//    if (flags & wxSCI_MOD_INSERTTEXT) txt << _T("wxSCI_MOD_INSERTTEXT, ");
//    if (flags & wxSCI_MOD_DELETETEXT) txt << _T("wxSCI_MOD_DELETETEXT, ");
//    if (flags & wxSCI_MOD_CHANGEFOLD) txt << _T("wxSCI_MOD_CHANGEFOLD, ");
//    if (flags & wxSCI_PERFORMED_USER) txt << _T("wxSCI_PERFORMED_USER, ");
//    if (flags & wxSCI_MOD_BEFOREINSERT) txt << _T("wxSCI_MOD_BEFOREINSERT, ");
//    if (flags & wxSCI_MOD_BEFOREDELETE) txt << _T("wxSCI_MOD_BEFOREDELETE, ");
//    txt << _T("pos=")
//        << wxString::Format(_T("%d"), event.GetPosition())
//        << _T(", line=")
//        << wxString::Format(_T("%d"), event.GetLine())
//        << _T(", linesAdded=")
//        << wxString::Format(_T("%d"), event.GetLinesAdded());
//    Manager::Get()->GetLogManager()->DebugLog(txt);

    // whenever event.GetLinesAdded() != 0, we must re-set breakpoints for lines greater
    // than LineFromPosition(event.GetPosition())
    int linesAdded = event.GetLinesAdded();
    bool isAdd = event.GetModificationType() & wxSCI_MOD_INSERTTEXT;
    bool isDel = event.GetModificationType() & wxSCI_MOD_DELETETEXT;
    if ((isAdd || isDel) && linesAdded != 0)
    {
        // in case of no line numbers to be shown no need to set
        // NOTE : on every modification of the Editor we consult ConfigManager
        //        hopefully not to time consuming, otherwise we make a member out of it
        ConfigManager* mgr = Manager::Get()->GetConfigManager(_T("editor"));
        if (mgr->ReadBool(_T("/show_line_numbers"), true))
        {
            m_pData->SetLineNumberColWidth();
        }

        // NB: I don't think polling for each debugger every time will slow things down enough
        // to worry about unless there are automated tasks that call this routine regularly
        //
        // well, scintilla events happen regularly
        // although we only reach this part of the code only if a line has been added/removed
        // so, yes, it might not be that bad after all
        PluginsArray arr = Manager::Get()->GetPluginManager()->GetOffersFor(ptDebugger);
        int startline = m_pControl->LineFromPosition(event.GetPosition());
        for(size_t i=0;i<arr.GetCount();i++)
        {
            cbDebuggerPlugin* debugger = (cbDebuggerPlugin*)arr[i];
            debugger->EditorLinesAddedOrRemoved(this, startline, linesAdded);
        }

    }
    if (isDel)
    {
        Manager::Get()->GetLogManager()->DebugLog(event.GetText());
        Manager::Get()->GetLogManager()->DebugLog(F(_T("delete   %d"),event.GetText().size()));
        if (event.GetText().size() == 1)
        {
            const wxString leftBrace(_T("([{"));
            const wxString rightBrace(_T(")]}"));
            int left = leftBrace.find(event.GetText()[0]);
            if (left != wxNOT_FOUND)
            {
                wxChar ch = m_pControl->GetCharAt(event.GetPosition());
                int right = rightBrace.find(ch);
                if (right != wxNOT_FOUND && right == left)
                {
                    m_pControl->GotoPos(event.GetPosition() + 1);
                    m_pControl->DeleteBack();
                 
                }

            }

        }
    }

    OnScintillaEvent(event);
} // end of OnEditorModified
Keep low and hear the sadness of little dog.
I fall in love with a girl,but I don't dare to tell her.What should I do?

Offline killerbot

  • Administrator
  • Lives here!
  • *****
  • Posts: 5491
Re: about bracecompletion
« Reply #19 on: August 22, 2009, 09:17:15 am »
I have tested the patch now for more then a week (not related to the topic on the reply before this one) and I will apply it today to the trunk.

Offline blueshake

  • Regular
  • ***
  • Posts: 459
Re: about bracecompletion
« Reply #20 on: August 22, 2009, 09:33:29 am »
nice to hear that . :D
by the way, what is your idea about reply #18?
this confuse me for several days.
Keep low and hear the sadness of little dog.
I fall in love with a girl,but I don't dare to tell her.What should I do?

Offline killerbot

  • Administrator
  • Lives here!
  • *****
  • Posts: 5491
Re: about bracecompletion
« Reply #21 on: August 22, 2009, 09:42:21 am »
applied and many thanks for the contribution  :P

I have no idea 'm_pControl->DeleteBack();' why this does not work. I should study the class of m_pControl again first.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5915
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: about bracecompletion
« Reply #22 on: August 28, 2009, 01:12:30 pm »
hi,
recently,i am going to make a patch,its function is
when you delete a ([{ and the right char is )]} ,so the the relative one will be deleted too.
for example
Code
int main(|)
int the "|" position ,you delete "(" and the ")" should be deleted too.
but i face a problem,
it seems that these codes can not work.the caret moved,but the ) didn't be delete.
any one have any idea about this?
these codes seems not be executed .
Code
m_pControl->DeleteBack();

here are the codes.
Code
void cbEditor::OnEditorModified(wxScintillaEvent& event)
{
//    wxString txt = _T("OnEditorModified(): ");
//    int flags = event.GetModificationType();
//    if (flags & wxSCI_MOD_CHANGEMARKER) txt << _T("wxSCI_MOD_CHANGEMARKER, ");
//    if (flags & wxSCI_MOD_INSERTTEXT) txt << _T("wxSCI_MOD_INSERTTEXT, ");
//    if (flags & wxSCI_MOD_DELETETEXT) txt << _T("wxSCI_MOD_DELETETEXT, ");
//    if (flags & wxSCI_MOD_CHANGEFOLD) txt << _T("wxSCI_MOD_CHANGEFOLD, ");
//    if (flags & wxSCI_PERFORMED_USER) txt << _T("wxSCI_PERFORMED_USER, ");
//    if (flags & wxSCI_MOD_BEFOREINSERT) txt << _T("wxSCI_MOD_BEFOREINSERT, ");
//    if (flags & wxSCI_MOD_BEFOREDELETE) txt << _T("wxSCI_MOD_BEFOREDELETE, ");
//    txt << _T("pos=")
//        << wxString::Format(_T("%d"), event.GetPosition())
//        << _T(", line=")
//        << wxString::Format(_T("%d"), event.GetLine())
//        << _T(", linesAdded=")
//        << wxString::Format(_T("%d"), event.GetLinesAdded());
//    Manager::Get()->GetLogManager()->DebugLog(txt);

    // whenever event.GetLinesAdded() != 0, we must re-set breakpoints for lines greater
    // than LineFromPosition(event.GetPosition())
    int linesAdded = event.GetLinesAdded();
    bool isAdd = event.GetModificationType() & wxSCI_MOD_INSERTTEXT;
    bool isDel = event.GetModificationType() & wxSCI_MOD_DELETETEXT;
    if ((isAdd || isDel) && linesAdded != 0)
    {
        // in case of no line numbers to be shown no need to set
        // NOTE : on every modification of the Editor we consult ConfigManager
        //        hopefully not to time consuming, otherwise we make a member out of it
        ConfigManager* mgr = Manager::Get()->GetConfigManager(_T("editor"));
        if (mgr->ReadBool(_T("/show_line_numbers"), true))
        {
            m_pData->SetLineNumberColWidth();
        }

        // NB: I don't think polling for each debugger every time will slow things down enough
        // to worry about unless there are automated tasks that call this routine regularly
        //
        // well, scintilla events happen regularly
        // although we only reach this part of the code only if a line has been added/removed
        // so, yes, it might not be that bad after all
        PluginsArray arr = Manager::Get()->GetPluginManager()->GetOffersFor(ptDebugger);
        int startline = m_pControl->LineFromPosition(event.GetPosition());
        for(size_t i=0;i<arr.GetCount();i++)
        {
            cbDebuggerPlugin* debugger = (cbDebuggerPlugin*)arr[i];
            debugger->EditorLinesAddedOrRemoved(this, startline, linesAdded);
        }

    }
    if (isDel)
    {
        Manager::Get()->GetLogManager()->DebugLog(event.GetText());
        Manager::Get()->GetLogManager()->DebugLog(F(_T("delete   %d"),event.GetText().size()));
        if (event.GetText().size() == 1)
        {
            const wxString leftBrace(_T("([{"));
            const wxString rightBrace(_T(")]}"));
            int left = leftBrace.find(event.GetText()[0]);
            if (left != wxNOT_FOUND)
            {
                wxChar ch = m_pControl->GetCharAt(event.GetPosition());
                int right = rightBrace.find(ch);
                if (right != wxNOT_FOUND && right == left)
                {
                    m_pControl->GotoPos(event.GetPosition() + 1);
                    m_pControl->DeleteBack();
                 
                }

            }

        }
    }

    OnScintillaEvent(event);
} // end of OnEditorModified

I tested this patch, it seems m_pControl->DeleteBack(); has no effect.
I don't know why...
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline Jenna

  • Administrator
  • Lives here!
  • *****
  • Posts: 7255
Re: about bracecompletion
« Reply #23 on: August 28, 2009, 02:00:09 pm »
I tested this patch, it seems m_pControl->DeleteBack(); has no effect.
I don't know why...

If I see it right, you can not modify the Document from inside the document-modified event (at least not call Document::DeletChars(), did not check this for other modifications).
And I think that's good, because it could lead to infinite loops.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5915
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: about bracecompletion
« Reply #24 on: August 28, 2009, 02:11:53 pm »
I tested this patch, it seems m_pControl->DeleteBack(); has no effect.
I don't know why...

If I see it right, you can not modify the Document from inside the document-modified event (at least not call Document::DeletChars(), did not check this for other modifications).
And I think that's good, because it could lead to infinite loops.


Thanks.

It is a reasonable explanation.

Here comes another question:

How can we do such kind of delete?
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5915
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: about bracecompletion
« Reply #25 on: August 28, 2009, 04:01:09 pm »
I find the reason in

http://wxcode.sourceforge.net/components/wxscintilla/reference.html

Quote
wxEVT_SCI_MODIFIED

This notification is sent when the text or styling of the document changes or is about to change. You can set a mask for the notifications that are sent to the container with SetModEventMask. The notification structure contains information about what changed, how the change occurred and whether this changed the number of lines in the document. No modifications may be performed while in a wxEVT_SCI_MODIFIED event.


If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline Jenna

  • Administrator
  • Lives here!
  • *****
  • Posts: 7255
Re: about bracecompletion
« Reply #26 on: August 28, 2009, 05:37:38 pm »
That's more or less what I wrote.
I did not look at the (wx)Scintilla-documentation, but in the sources (they use a counter to avoid multiple modifications at the same time).