BEGIN_EVENT_TABLE(LEditor, wxScintilla)
EVT_SCI_CHARADDED (wxID_ANY, LEditor::OnCharAdded)
EVT_SCI_MARGINCLICK (wxID_ANY, LEditor::OnMarginClick)
EVT_SCI_CALLTIP_CLICK (wxID_ANY, LEditor::OnCallTipClick)
EVT_SCI_DWELLEND (wxID_ANY, LEditor::OnDwellEnd)
EVT_SCI_UPDATEUI (wxID_ANY, LEditor::OnSciUpdateUI)
EVT_SCI_SAVEPOINTREACHED (wxID_ANY, LEditor::OnSavePoint)
EVT_SCI_SAVEPOINTLEFT (wxID_ANY, LEditor::OnSavePoint)
EVT_SCI_MODIFIED (wxID_ANY, LEditor::OnChange)
EVT_CONTEXT_MENU (LEditor::OnContextMenu)
EVT_KEY_DOWN (LEditor::OnKeyDown)
EVT_LEFT_DOWN (LEditor::OnLeftDown)
EVT_MIDDLE_DOWN (LEditor::OnMiddleDown)
EVT_MIDDLE_UP (LEditor::OnMiddleUp)
EVT_LEFT_UP (LEditor::OnLeftUp)
EVT_LEAVE_WINDOW (LEditor::OnLeaveWindow)
EVT_KILL_FOCUS (LEditor::OnFocusLost)
EVT_SCI_DOUBLECLICK (wxID_ANY, LEditor::OnLeftDClick)
EVT_COMMAND (wxID_ANY, wxEVT_FRD_FIND_NEXT, LEditor::OnFindDialog)
EVT_COMMAND (wxID_ANY, wxEVT_FRD_REPLACE, LEditor::OnFindDialog)
EVT_COMMAND (wxID_ANY, wxEVT_FRD_REPLACEALL, LEditor::OnFindDialog)
EVT_COMMAND (wxID_ANY, wxEVT_FRD_BOOKMARKALL, LEditor::OnFindDialog)
EVT_COMMAND (wxID_ANY, wxEVT_FRD_CLOSE, LEditor::OnFindDialog)
EVT_COMMAND (wxID_ANY, wxEVT_FRD_CLEARBOOKMARKS, LEditor::OnFindDialog)
EVT_COMMAND (wxID_ANY, wxEVT_CMD_JOB_STATUS_VOID_PTR, LEditor::OnHighlightThread)
EVT_COMMAND (wxID_ANY, wxCMD_EVENT_REMOVE_MATCH_INDICATOR, LEditor::OnRemoveMatchInidicator)
END_EVENT_TABLE()
and in codeblock ,I can not figure out how to do this.can somebode tell me how to do this in codeblock,thanks.Look into:
void cbEditor::OnScintillaEvent(wxScintillaEvent& event)
cbStyledTextCtrl* cbEditor::CreateEditor()
{
m_ID = wxNewId();
// avoid gtk-critical because of sizes less than -1 (can happen with wxAuiNotebook/cbAuiNotebook)
wxSize size = m_pControl ? wxDefaultSize : GetSize();
size.x = std::max(size.x, -1);
size.y = std::max(size.y, -1);
cbStyledTextCtrl* control = new cbStyledTextCtrl(this, m_ID, wxDefaultPosition, size);
control->UsePopUp(false);
wxString enc_name = Manager::Get()->GetConfigManager(_T("editor"))->Read(_T("/default_encoding"), wxEmptyString);
m_pData->m_encoding = wxFontMapper::GetEncodingFromName(enc_name);
// dynamic events
Connect( m_ID, -1, wxEVT_SCI_MARGINCLICK,
(wxObjectEventFunction) (wxEventFunction) (wxScintillaEventFunction)
&cbEditor::OnMarginClick );
Connect( m_ID, -1, wxEVT_SCI_UPDATEUI,
(wxObjectEventFunction) (wxEventFunction) (wxScintillaEventFunction)
&cbEditor::OnEditorUpdateUI );
Connect( m_ID, -1, wxEVT_SCI_CHANGE,
(wxObjectEventFunction) (wxEventFunction) (wxScintillaEventFunction)
&cbEditor::OnEditorChange );
Connect( m_ID, -1, wxEVT_SCI_CHARADDED,
(wxObjectEventFunction) (wxEventFunction) (wxScintillaEventFunction)
&cbEditor::OnEditorCharAdded );
Connect( m_ID, -1, wxEVT_SCI_DWELLSTART,
(wxObjectEventFunction) (wxEventFunction) (wxScintillaEventFunction)
&cbEditor::OnEditorDwellStart );
Connect( m_ID, -1, wxEVT_SCI_DWELLEND,
(wxObjectEventFunction) (wxEventFunction) (wxScintillaEventFunction)
&cbEditor::OnEditorDwellEnd );
Connect( m_ID, -1, wxEVT_SCI_USERLISTSELECTION,
(wxObjectEventFunction) (wxEventFunction) (wxScintillaEventFunction)
&cbEditor::OnUserListSelection );
Connect( m_ID, -1, wxEVT_SCI_MODIFIED,
(wxObjectEventFunction) (wxEventFunction) (wxScintillaEventFunction)
&cbEditor::OnEditorModified );
// Now bind all *other* scintilla events to a common function so that editor hooks
// can be informed for them too.
// If you implement one of these events using a different function, do the following:
// * comment it out here,
// * "connect" it in the above block
// * and make sure you call OnScintillaEvent() from your new handler function
// This will make sure that all editor hooks will be called when needed.
int scintilla_events[] =
{
// wxEVT_SCI_CHANGE,
wxEVT_SCI_STYLENEEDED,
// wxEVT_SCI_CHARADDED,
wxEVT_SCI_SAVEPOINTREACHED,
wxEVT_SCI_SAVEPOINTLEFT,
wxEVT_SCI_ROMODIFYATTEMPT,
wxEVT_SCI_KEY,
wxEVT_SCI_DOUBLECLICK,
// wxEVT_SCI_UPDATEUI,
// wxEVT_SCI_MODIFIED,
wxEVT_SCI_MACRORECORD,
// wxEVT_SCI_MARGINCLICK,
wxEVT_SCI_NEEDSHOWN,
wxEVT_SCI_PAINTED,
// wxEVT_SCI_USERLISTSELECTION,
wxEVT_SCI_URIDROPPED,
// wxEVT_SCI_DWELLSTART,
// wxEVT_SCI_DWELLEND,
wxEVT_SCI_START_DRAG,
wxEVT_SCI_DRAG_OVER,
wxEVT_SCI_DO_DROP,
wxEVT_SCI_ZOOM,
wxEVT_SCI_HOTSPOT_CLICK,
wxEVT_SCI_HOTSPOT_DCLICK,
wxEVT_SCI_CALLTIP_CLICK,
wxEVT_SCI_AUTOCOMP_SELECTION,
// wxEVT_SCI_INDICATOR_CLICK,
// wxEVT_SCI_INDICATOR_RELEASE,
-1 // to help enumeration of this array
};
int i = 0;
while (scintilla_events[i] != -1)
{
Connect( m_ID, -1, scintilla_events[i],
(wxObjectEventFunction) (wxEventFunction) (wxScintillaEventFunction)
&cbEditor::OnScintillaEvent );
++i;
}
return control;
}
SCN_KEY
Reports all keys pressed but not consumed by Scintilla.
cbStyledTextCtrl* cbEditor::CreateEditor()
{
m_ID = wxNewId();
// avoid gtk-critical because of sizes less than -1 (can happen with wxAuiNotebook/cbAuiNotebook)
wxSize size = m_pControl ? wxDefaultSize : GetSize();
size.x = std::max(size.x, -1);
size.y = std::max(size.y, -1);
cbStyledTextCtrl* control = new cbStyledTextCtrl(this, m_ID, wxDefaultPosition, size);
control->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(cbEditor::OnKeyDown));
I make a patch for this, welcome to test.
void f(
void f(|)
void f)
Fix now.I make a patch for this, welcome to test.
I found a bug:
When I enter this:CodeThen, I will get the close parenthesis auto added.void f(
CodeBut at this moment, I press backspace key, then the opening parenthesis was deleted but the close parenthesis still there.void f(|)
Codevoid f)
Except this bug, all the other functions works really nice!!! Thanks for the contribution.
Fix now.Some remarks concerning this patch:
if (!AllowTabSmartJump())
{
event.Skip();
return;
}
case _T('\''):
case 57: // (
case 0x91: // {
Index: src/include/cbstyledtextctrl.h
===================================================================
--- src/include/cbstyledtextctrl.h (revision 6196)
+++ src/include/cbstyledtextctrl.h (working copy)
@@ -24,9 +24,13 @@
void OnKillFocus(wxFocusEvent& event);
void OnGetFocus(wxFocusEvent& event);
void OnGPM(wxMouseEvent& event);
+ void OnKeyDown(wxKeyEvent& event);
+ void OnKeyUp(wxKeyEvent& event);
+ bool AllowTabSmartJump();
wxWindow* m_pParent;
wxLongLong m_lastFocusTime;
+ bool m_tabSmartJump;
DECLARE_EVENT_TABLE()
};
Index: src/sdk/cbstyledtextctrl.cpp
===================================================================
--- src/sdk/cbstyledtextctrl.cpp (revision 6196)
+++ src/sdk/cbstyledtextctrl.cpp (working copy)
@@ -18,17 +18,23 @@
#include "editorbase.h" // DisplayContextMenu
#include "prep.h" // platform::gtk
+static const wxString s_leftBrace(_T("([{'\""));
+static const wxString s_rightBrace(_T(")]}'\""));
+
BEGIN_EVENT_TABLE(cbStyledTextCtrl, wxScintilla)
EVT_CONTEXT_MENU(cbStyledTextCtrl::OnContextMenu)
EVT_KILL_FOCUS(cbStyledTextCtrl::OnKillFocus)
EVT_MIDDLE_DOWN(cbStyledTextCtrl::OnGPM)
EVT_SET_FOCUS(cbStyledTextCtrl::OnGetFocus)
+ EVT_KEY_DOWN(cbStyledTextCtrl::OnKeyDown)
+ EVT_KEY_UP(cbStyledTextCtrl::OnKeyUp)
END_EVENT_TABLE()
cbStyledTextCtrl::cbStyledTextCtrl(wxWindow* pParent, int id, const wxPoint& pos, const wxSize& size, long style)
: wxScintilla(pParent, id, pos, size, style),
m_pParent(pParent),
- m_lastFocusTime(0L)
+ m_lastFocusTime(0L),
+ m_tabSmartJump(false)
{
//ctor
}
@@ -103,3 +109,125 @@
SetSelectionVoid(start, end);
}
} // end of OnGPM
+
+void cbStyledTextCtrl::OnKeyDown(wxKeyEvent& event)
+{
+ int keyCode = event.GetKeyCode();
+ switch (keyCode)
+ {
+ case WXK_TAB:
+ {
+ if (m_tabSmartJump)
+ {
+ if (s_rightBrace.Find(GetCharAt(GetCurrentPos())) == wxNOT_FOUND)
+ {
+ m_tabSmartJump = false;
+ }
+ else
+ {
+ CharRight();
+ return;
+ }
+ }
+ }
+ break;
+
+ case WXK_BACK:
+ {
+ if (m_tabSmartJump)
+ {
+ const int pos = GetCurrentPos();
+ const int index = s_leftBrace.Find(GetCharAt(pos - 1));
+ if (index != wxNOT_FOUND && GetCharAt(pos) == s_rightBrace.GetChar(index))
+ {
+ CharRight();
+ DeleteBack();
+ }
+ }
+ }
+ break;
+
+ case WXK_ESCAPE:
+ {
+ if (m_tabSmartJump)
+ {
+ m_tabSmartJump = false;
+ CharLeft();
+ Tab();
+ return;
+ }
+ }
+ break;
+
+ case WXK_RETURN:
+ {
+ m_tabSmartJump = false;
+ }
+ break;
+ }
+
+ event.Skip();
+}
+
+void cbStyledTextCtrl::OnKeyUp(wxKeyEvent& event)
+{
+ const int keyCode = event.GetKeyCode();
+ switch (keyCode)
+ {
+ case _T('['): // [ {
+ case _T('\''): // ' "
+ case _T('9'): // (
+ {
+ if (!AllowTabSmartJump()) break;
+
+ wxChar ch = keyCode;
+ if (event.ShiftDown())
+ {
+ if (keyCode == _T('\'')) ch = _T('"');
+ else if (keyCode == _T('9')) ch = _T('(');
+ else if (keyCode == _T('[')) ch = _T('{');
+ }
+
+ int index = s_leftBrace.Find(ch);
+ if (index != wxNOT_FOUND && GetCharAt(GetCurrentPos()) == s_rightBrace.GetChar(index))
+ m_tabSmartJump = true;
+ else if (keyCode == _T('\'')) // ' "
+ m_tabSmartJump = false;
+ }
+ break;
+
+ case _T(']'): // ] }
+ case _T('0'): // )
+ {
+ if (!AllowTabSmartJump()) break;
+ if (keyCode == _T('0') && !event.ShiftDown()) break;
+ m_tabSmartJump = false;
+ }
+ break;
+ }
+
+ event.Skip();
+}
+
+bool cbStyledTextCtrl::AllowTabSmartJump()
+{
+ int style = GetStyleAt(GetCurrentPos() - 2);
+ switch (GetLexer())
+ {
+ case wxSCI_LEX_CPP:
+ {
+ if (style != wxSCI_C_STRING && style != wxSCI_C_CHARACTER)
+ return true;
+ else
+ return !(style == wxSCI_C_STRING || style == wxSCI_C_CHARACTER);
+ }
+ case wxSCI_LEX_D:
+ {
+ if (style != wxSCI_D_STRING && style != wxSCI_D_CHARACTER)
+ return true;
+ else
+ return !(style == wxSCI_D_STRING || style == wxSCI_D_CHARACTER);
+ }
+ }
+ return false;
+}
2.) The trial for AllowTabSmartJump() should be the first statement in the method, like:Here, I do not quite understand: Why did not directly break it, because at the end of the function, there implementation: 'event.Skip ();' ?Codeif (!AllowTabSmartJump())
{
event.Skip();
return;
}
Here, I do not quite understand: Why did not directly break it, because at the end of the function, there implementation: 'event.Skip ();' ?Yes, but there are computations in between which can be avoided. Namely event.GetKeyCode(); and the switch computation.
The same like this:CodeIndex: src/include/cbstyledtextctrl.h
+ switch (GetLexer())
+ {
+ case wxSCI_LEX_CPP:
+ {
+ if (style != wxSCI_C_STRING && style != wxSCI_C_CHARACTER)
+ return true;
+ else
+ return !(style == wxSCI_C_STRING || style == wxSCI_C_CHARACTER);
+ }
+ case wxSCI_LEX_D:
+ {
+ if (style != wxSCI_D_STRING && style != wxSCI_D_CHARACTER)
+ return true;
+ else
+ return !(style == wxSCI_D_STRING || style == wxSCI_D_CHARACTER);
+ }
+ }
+ return false;
+}
Index: src/include/cbstyledtextctrl.h
+ switch (GetLexer())
+ {
+ case wxSCI_LEX_CPP:
+ {
+ if (style != wxSCI_C_STRING && style != wxSCI_C_CHARACTER)
+ return true;
+ }
+ case wxSCI_LEX_D:
+ {
+ if (style != wxSCI_D_STRING && style != wxSCI_D_CHARACTER)
+ return true;
+ }
+ }
+ return false;
+}
The same like this:Haha, you're right! Thank you. :PCode???Index: src/include/cbstyledtextctrl.h
+ switch (GetLexer())
+ {
+ case wxSCI_LEX_CPP:
+ {
+ if (style != wxSCI_C_STRING && style != wxSCI_C_CHARACTER)
+ return true;
+ }
+ case wxSCI_LEX_D:
+ {
+ if (style != wxSCI_D_STRING && style != wxSCI_D_CHARACTER)
+ return true;
+ }
+ }
+ return false;
+}
:lol: :lol: :lol:
Index: src/include/cbstyledtextctrl.h
+ switch (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);
+ }
+ }
+ return false;
+}
Sorry, I still do not quite understand.Here, I do not quite understand: Why did not directly break it, because at the end of the function, there implementation: 'event.Skip ();' ?Yes, but there are computations in between which can be avoided. Namely event.GetKeyCode(); and the switch computation.
void cbStyledTextCtrl::OnKeyUp(wxKeyEvent& event)
{
if (!AllowTabSmartJump())
{
event.Skip();
return;
}
const int keyCode = event.GetKeyCode();
switch (keyCode)
{
...
}
event.Skip();
}
Why not this (and get rid of the if-statements) :cool! :DCode?Index: src/include/cbstyledtextctrl.h
+ switch (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);
+ }
+ }
+ return false;
+}
+ void SetTabSmartJump(bool enable = true) { m_tabSmartJump = enable; }
+
Index: src/include/cbstyledtextctrl.h
===================================================================
--- src/include/cbstyledtextctrl.h (revision 6196)
+++ src/include/cbstyledtextctrl.h (working copy)
@@ -19,14 +19,20 @@
cbStyledTextCtrl(wxWindow* pParent, int id, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0);
virtual ~cbStyledTextCtrl();
wxDateTime GetLastFocusTime() const {return m_lastFocusTime;}
+ void SetTabSmartJump(bool enable = true) { m_tabSmartJump = enable; }
+
private:
void OnContextMenu(wxContextMenuEvent& event);
void OnKillFocus(wxFocusEvent& event);
void OnGetFocus(wxFocusEvent& event);
void OnGPM(wxMouseEvent& event);
+ void OnKeyDown(wxKeyEvent& event);
+ void OnKeyUp(wxKeyEvent& event);
+ bool AllowTabSmartJump();
wxWindow* m_pParent;
wxLongLong m_lastFocusTime;
+ bool m_tabSmartJump;
DECLARE_EVENT_TABLE()
};
Index: src/sdk/cbstyledtextctrl.cpp
===================================================================
--- src/sdk/cbstyledtextctrl.cpp (revision 6196)
+++ src/sdk/cbstyledtextctrl.cpp (working copy)
@@ -18,17 +18,23 @@
#include "editorbase.h" // DisplayContextMenu
#include "prep.h" // platform::gtk
+static const wxString s_leftBrace(_T("([{'\""));
+static const wxString s_rightBrace(_T(")]}'\""));
+
BEGIN_EVENT_TABLE(cbStyledTextCtrl, wxScintilla)
EVT_CONTEXT_MENU(cbStyledTextCtrl::OnContextMenu)
EVT_KILL_FOCUS(cbStyledTextCtrl::OnKillFocus)
EVT_MIDDLE_DOWN(cbStyledTextCtrl::OnGPM)
EVT_SET_FOCUS(cbStyledTextCtrl::OnGetFocus)
+ EVT_KEY_DOWN(cbStyledTextCtrl::OnKeyDown)
+ EVT_KEY_UP(cbStyledTextCtrl::OnKeyUp)
END_EVENT_TABLE()
cbStyledTextCtrl::cbStyledTextCtrl(wxWindow* pParent, int id, const wxPoint& pos, const wxSize& size, long style)
: wxScintilla(pParent, id, pos, size, style),
m_pParent(pParent),
- m_lastFocusTime(0L)
+ m_lastFocusTime(0L),
+ m_tabSmartJump(false)
{
//ctor
}
@@ -103,3 +109,115 @@
SetSelectionVoid(start, end);
}
} // end of OnGPM
+
+void cbStyledTextCtrl::OnKeyDown(wxKeyEvent& event)
+{
+ int keyCode = event.GetKeyCode();
+ switch (keyCode)
+ {
+ case WXK_TAB:
+ {
+ if (m_tabSmartJump)
+ {
+ if (s_rightBrace.Find(GetCharAt(GetCurrentPos())) == wxNOT_FOUND)
+ {
+ m_tabSmartJump = false;
+ }
+ else
+ {
+ CharRight();
+ return;
+ }
+ }
+ }
+ break;
+
+ case WXK_BACK:
+ {
+ if (m_tabSmartJump)
+ {
+ const int pos = GetCurrentPos();
+ const int index = s_leftBrace.Find(GetCharAt(pos - 1));
+ if (index != wxNOT_FOUND && GetCharAt(pos) == s_rightBrace.GetChar(index))
+ {
+ CharRight();
+ DeleteBack();
+ }
+ }
+ }
+ break;
+
+ case WXK_ESCAPE:
+ {
+ if (m_tabSmartJump)
+ {
+ m_tabSmartJump = false;
+ CharLeft();
+ Tab();
+ return;
+ }
+ }
+ break;
+
+ case WXK_RETURN:
+ {
+ m_tabSmartJump = false;
+ }
+ break;
+ }
+
+ event.Skip();
+}
+
+void cbStyledTextCtrl::OnKeyUp(wxKeyEvent& event)
+{
+ const int keyCode = event.GetKeyCode();
+ switch (keyCode)
+ {
+ case _T('['): // [ {
+ case _T('\''): // ' "
+ case _T('9'): // (
+ {
+ if (!AllowTabSmartJump()) break;
+
+ wxChar ch = keyCode;
+ if (event.ShiftDown())
+ {
+ if (keyCode == _T('\'')) ch = _T('"');
+ else if (keyCode == _T('9')) ch = _T('(');
+ else if (keyCode == _T('[')) ch = _T('{');
+ }
+
+ int index = s_leftBrace.Find(ch);
+ if (index != wxNOT_FOUND && GetCharAt(GetCurrentPos()) == s_rightBrace.GetChar(index))
+ m_tabSmartJump = true;
+ else if (keyCode == _T('\'')) // ' "
+ m_tabSmartJump = false;
+ }
+ break;
+
+ case _T(']'): // ] }
+ case _T('0'): // )
+ {
+ if (!AllowTabSmartJump()) break;
+ if (keyCode == _T('0') && !event.ShiftDown()) break;
+ m_tabSmartJump = false;
+ }
+ break;
+ }
+
+ event.Skip();
+}
+
+bool cbStyledTextCtrl::AllowTabSmartJump()
+{
+ int style = GetStyleAt(GetCurrentPos() - 2);
+ switch (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);
+ }
+ return false;
+}
We do not have access to ‘event.GetKeyCode()’ value and 'switch’ calculation, BUT, we need call 'AllowTabSmartJump' each time.Yes, but in the other case you do call AllowTabSmartJump() all the time, too - right?! You do it in every case statement.
Index: src/plugins/codecompletion/codecompletion.cpp
===================================================================
--- src/plugins/codecompletion/codecompletion.cpp (revision 6202)
+++ src/plugins/codecompletion/codecompletion.cpp (working copy)
@@ -2014,6 +2014,7 @@
control->SetTargetStart(start);
control->SetTargetEnd(pos);
control->ReplaceTarget(itemText+_T("()"));
+ control->SetTabSmartJump();
pos = control->GetCurrentPos();
control->GotoPos(pos + itemText.size()+2);
if ((*it).second != 0)
#include <stdio.h>
class A
{
public:
void test()
{
}
};
int main(int argc, char* argv[])
{
A a;
a.test(|) // HERE, when backspace, it's can delete '(', also ')'.
return 0;
}
ok, then I won't apply it on trunk and wait till cc gets merged towards trunk :-)Yeah, and i hope the merge will be soon, we just need more test.