int main()
int main[]
int main())
What are the circumstances in which one would want to do this? I don't think I have ever wanted to convert () to [].
* if user has a selection, typing a brace char (or quote char) puts the brace around the selection instead of deleting the selection.This feature already exists. Do you have Selection brace completion enabled? (Although, the recent SmartIndent refactor has restricted it to C/C++ only; I am exploring how to make it general purpose again.)
...decide where they should go.Base class functions?
Index: src/plugins/contrib/SmartIndent/CppSmartIndent.cpp
===================================================================
--- src/plugins/contrib/SmartIndent/CppSmartIndent.cpp (revision 8464)
+++ src/plugins/contrib/SmartIndent/CppSmartIndent.cpp (working copy)
@@ -19,8 +19,11 @@
namespace
{
PluginRegistrant<CppSmartIndent> reg(_T("CppSmartIndent"));
-}
-void CppSmartIndent::OnEditorHook(cbEditor* ed, wxScintillaEvent& event) const
+}
+
+static int m_bracePos=-1;
+
+void CppSmartIndent::OnEditorHook(cbEditor* ed, wxScintillaEvent& event)const
{
// check if smart indent is enabled
@@ -32,18 +35,33 @@
if ( !SmartIndentEnabled() )
return;
-
- wxEventType type = event.GetEventType();
- if ( type != wxEVT_SCI_CHARADDED )
- return;
-
+
cbStyledTextCtrl* stc = ed->GetControl();
if (!stc)
return;
wxString langname = Manager::Get()->GetEditorManager()->GetColourSet()->GetLanguageName(ed->GetLanguage());
if ( langname != _T("C/C++") && langname != _T("D") && langname != _T("Java") ) return;
+
+ wxEventType type = event.GetEventType();
+ if ( type == wxEVT_SCI_KEY )
+ {
+ int p = stc->GetCurrentPos();
+ int a = stc->GetAnchor();
+ int m=p;
+ if(a>=0 && a<p)
+ m=a;
+ m_bracePos = stc->BraceMatch(m);
+ Manager::Get()->GetLogManager()->Log(wxString::Format(_T("Key Event Brace pos %i"),m_bracePos));
+ event.Skip(true);
+ return;
+ }
+ if ( type != wxEVT_SCI_CHARADDED )
+ return;
+
+
+
ed->AutoIndentDone(); // we are responsible.
const int pos = stc->GetCurrentPos();
@@ -440,13 +458,56 @@
}
return false;
}
+
void CppSmartIndent::DoSelectionBraceCompletion(cbStyledTextCtrl* control, const wxChar &ch)const
{
if (!control->GetLastSelectedText().IsEmpty())
{
-
const int pos = control->GetCurrentPos();
- wxString selectedText = control->GetLastSelectedText();
+ wxString selectedText = control->GetLastSelectedText();
+ Manager::Get()->GetLogManager()->Log(_T("Last Selected Text ")+selectedText);
+ if(selectedText == _T("(") ||
+ selectedText == _T(")") ||
+ selectedText == _T("[") ||
+ selectedText == _T("]") ||
+ selectedText == _T("{") ||
+ selectedText == _T("}")
+ )
+ {
+ int p = pos;
+ wxString opch;
+ switch (ch)
+ {
+ case _T('('):
+ opch = _T(")");
+ break;
+ case _T(')'):
+ opch = _T("(");
+ break;
+ case _T('['):
+ opch = _T("]");
+ break;
+ case _T(']'):
+ opch = _T("[");
+ break;
+ case _T('{'):
+ opch = _T("}");
+ break;
+ case _T('}'):
+ opch = _T("{");
+ break;
+ }
+ //int m = control->BraceMatch(p-1);
+ Manager::Get()->GetLogManager()->Log(wxString::Format(_T("Brace pos %i"),m_bracePos));
+ if (m_bracePos == wxSCI_INVALID_POSITION)
+ return;
+ control->BeginUndoAction();
+ control->InsertText(m_bracePos, opch);
+ control->DeleteRange(m_bracePos+1, 1);
+ control->SetCurrentPos(p);
+ control->EndUndoAction();
+ return;
+ }
switch (ch)
{
case _T('\''):
@@ -547,6 +608,7 @@
}
} // SelectionBraceCompletion
}
+
void CppSmartIndent::DoBraceCompletion(cbStyledTextCtrl* control, const wxChar& ch)const
{
int pos = control->GetCurrentPos();
@Alpha: would still like to have the brace selection behavior for other languages beside C/C++. As obfuscated suggests, just move that method to the base class and have more (all?) of the smart indent implementations call it would be one way to do it.Something like that; what I am planning is to have more generic base function that is called as a fall-back, and smart indent plugins would then (have the option to) specialize the behavior (for example, when used on a double quote ("), it currently utilizes C/C++ escapes, which may not be applicable to all languages).
If you want to work on this, go ahead. Otherwise, I should have a patch available in a few days.
Index: src/plugins/contrib/SmartIndent/PythonSmartIndent.cpp
===================================================================
--- src/plugins/contrib/SmartIndent/PythonSmartIndent.cpp (revision 8478)
+++ src/plugins/contrib/SmartIndent/PythonSmartIndent.cpp (working copy)
@@ -69,4 +69,7 @@
stc->EndUndoAction();
}
}
+
+ if ( SelectionBraceCompletionEnabled() || stc->IsBraceShortcutActive() )
+ ed->DoSelectionBraceCompletion(stc, ch);
}
Index: src/plugins/contrib/SmartIndent/LuaSmartIndent.cpp
===================================================================
--- src/plugins/contrib/SmartIndent/LuaSmartIndent.cpp (revision 8478)
+++ src/plugins/contrib/SmartIndent/LuaSmartIndent.cpp (working copy)
@@ -67,6 +67,9 @@
stc->EndUndoAction();
}
}
+
+ if ( SelectionBraceCompletionEnabled() || stc->IsBraceShortcutActive() )
+ ed->DoSelectionBraceCompletion(stc, ch);
}
bool LuaSmartIndent::BraceIndent(cbStyledTextCtrl *stc, wxString &indent)const
Index: src/plugins/contrib/SmartIndent/XMLSmartIndent.cpp
===================================================================
--- src/plugins/contrib/SmartIndent/XMLSmartIndent.cpp (revision 8478)
+++ src/plugins/contrib/SmartIndent/XMLSmartIndent.cpp (working copy)
@@ -47,16 +47,28 @@
ed->AutoIndentDone(); // we are responsible
- const int pos = stc->GetCurrentPos();
+ int pos = stc->GetCurrentPos();
int currLine = stc->LineFromPosition(pos);
const wxChar ch = event.GetKey();
wxRegEx reTag(wxT("***:<[ \t]*?(|/)[ \t]*?([a-zA-Z][a-zA-Z0-9_-]*).*?(|/)[ \t]*?>"));
+ bool complQuote = true;
+ if ( SelectionBraceCompletionEnabled() || stc->IsBraceShortcutActive() )
+ {
+ ed->DoSelectionBraceCompletion(stc, ch);
+ if (pos != stc->GetCurrentPos())
+ {
+ complQuote = false;
+ pos = stc->GetCurrentPos();
+ currLine = stc->LineFromPosition(pos);
+ }
+ }
+
if (BraceCompletionEnabled())
{
// finish tag
- if (ch == wxT('>'))
+ if ( ch == wxT('>') && !stc->IsString(stc->GetStyleAt(pos)) )
{
wxString tag;
for (int i = pos - 2; i > 0; --i)
@@ -72,7 +84,7 @@
stc->InsertText(pos, wxT("</") + reTag.GetMatch(tag, 2) + wxT(">"));
}
// close string
- else if (ch == wxT('"') || ch == wxT('\''))
+ else if (complQuote && (ch == wxT('"') || ch == wxT('\'')))
{
if (stc->GetCharAt(pos) == ch)
{
@@ -113,14 +125,14 @@
}
}
// indent
- if ( (ch == wxT('\n')) || ( (stc->GetEOLMode() == wxSCI_EOL_CR) && (ch == wxT('\r')) ) )
+ if ( AutoIndentEnabled()
+ && ( (ch == wxT('\n')) || ((stc->GetEOLMode() == wxSCI_EOL_CR) && (ch == wxT('\r'))) ) )
{
- if (AutoIndentEnabled())
+ wxString indent = ed->GetLineIndentString(currLine - 1);
+ stc->BeginUndoAction();
+ if (SmartIndentEnabled()) // smart indent
{
- wxString indent = ed->GetLineIndentString(currLine - 1);
int idx = stc->GetLine(currLine - 1).Find(wxT('>'), true);
-
- stc->BeginUndoAction();
if (idx != wxNOT_FOUND)
{
wxString tag;
@@ -167,10 +179,10 @@
}
}
}
- stc->InsertText(pos, indent);
- stc->GotoPos(pos + indent.Length());
- stc->ChooseCaretX();
- stc->EndUndoAction();
}
+ stc->InsertText(pos, indent);
+ stc->GotoPos(pos + indent.Length());
+ stc->ChooseCaretX();
+ stc->EndUndoAction();
}
}
Index: src/plugins/contrib/SmartIndent/PascalSmartIndent.cpp
===================================================================
--- src/plugins/contrib/SmartIndent/PascalSmartIndent.cpp (revision 8478)
+++ src/plugins/contrib/SmartIndent/PascalSmartIndent.cpp (working copy)
@@ -44,6 +44,9 @@
DoIndent(ed, langname); // indent because \n added
else if ( ch != wxT(' ') )
DoUnIndent(ed, langname); // un-indent because not a newline added
+
+ if ( SelectionBraceCompletionEnabled() || stc->IsBraceShortcutActive() )
+ ed->DoSelectionBraceCompletion(stc, ch);
}
void PascalSmartIndent::DoIndent(cbEditor* ed, const wxString& WXUNUSED(langname)) const
Index: src/plugins/contrib/SmartIndent/HDLSmartIndent.cpp
===================================================================
--- src/plugins/contrib/SmartIndent/HDLSmartIndent.cpp (revision 8478)
+++ src/plugins/contrib/SmartIndent/HDLSmartIndent.cpp (working copy)
@@ -49,6 +49,9 @@
DoIndent(ed, langname); // indent because \n added
else if ( ch != wxT(' ') )
DoUnIndent(ed, langname); // un-indent because not a newline added
+
+ if ( SelectionBraceCompletionEnabled() || stc->IsBraceShortcutActive() )
+ ed->DoSelectionBraceCompletion(stc, ch);
}
int HDLSmartIndent::FindBlockStartVHDL(cbEditor* ed, int position, wxString block) const
Index: src/plugins/contrib/SmartIndent/FortranSmartIndent.cpp
===================================================================
--- src/plugins/contrib/SmartIndent/FortranSmartIndent.cpp (revision 8478)
+++ src/plugins/contrib/SmartIndent/FortranSmartIndent.cpp (working copy)
@@ -103,4 +103,7 @@
stc->EndUndoAction();
}
+
+ if ( SelectionBraceCompletionEnabled() || stc->IsBraceShortcutActive() )
+ ed->DoSelectionBraceCompletion(stc, ch);
}
Index: src/include/cbeditor.h
===================================================================
--- src/include/cbeditor.h (revision 8478)
+++ src/include/cbeditor.h (working copy)
@@ -301,6 +301,7 @@
static void ApplyStyles(cbStyledTextCtrl* control);
void AutoIndentDone();
+ void DoSelectionBraceCompletion(cbStyledTextCtrl* control, const wxChar& ch) const;
private:
cbEditor(const cbEditor& /*rhs*/); // prevent copy construction
Index: src/sdk/cbeditor.cpp
===================================================================
--- src/sdk/cbeditor.cpp (revision 8478)
+++ src/sdk/cbeditor.cpp (working copy)
@@ -3095,12 +3095,33 @@
control->EndUndoAction();
}
}
+ if( Manager::Get()->GetConfigManager(_T("editor"))->ReadBool(_T("/brace_completion"), true)
+ || control->IsBraceShortcutActive())
+ DoSelectionBraceCompletion(control, ch);
}
}
void cbEditor::AutoIndentDone()
{
m_autoIndentDone = true;
}
+void cbEditor::DoSelectionBraceCompletion(cbStyledTextCtrl* control, const wxChar& ch) const
+{
+ if (control->GetLastSelectedText().IsEmpty())
+ return;
+ const wxString braces(wxT("([{<'\")]}>'\""));
+ const int braceAIdx = braces.Find(ch, true); // from end (so caret ends after quotes)
+ if (braceAIdx == wxNOT_FOUND)
+ return;
+ const int braceBIdx = (braceAIdx + (braces.Length() / 2)) % braces.Length();
+ control->BeginUndoAction();
+ control->DeleteBack();
+ if (braceAIdx < braceBIdx)
+ control->InsertText(control->GetCurrentPos(),
+ braces[braceAIdx] + control->GetLastSelectedText() + braces[braceBIdx]);
+ else
+ control->AddText(braces[braceBIdx] + control->GetLastSelectedText() + braces[braceAIdx]);
+ control->EndUndoAction();
+}
void cbEditor::OnEditorDwellStart(wxScintillaEvent& event)
{
Here is a candidate patch.dmoore: Do you take action?
Here is a candidate patch.dmoore: Do you take action?
Anyone else tested it?I've applied it in my local copy but didn't test.
Here is a candidate patch.
I thought we had done something to fix this in our SVN.Most files are set to match system EOL style, however, it appears as if the files added by Smart Indent are CR LF only.
Also, is there a good reason to put the brace completion stuff in cbEditor instead of the plugin base?I put it there so the editor has access to use it as fall-back if no plugin supports the current lexer. The Smart Indent plugins for languages that I am less familiar with just call this more-generic method, whereas the C++ plugin has its own specialized implementation (that I previously wrote - although, it occasionally has some issues, so I may have to look back at it again).
I put it there so the editor has access to use it as fall-back if no plugin supports the current lexer.
Attached.Did that patch change anything in comparison to the previous one? After applying this I see no differences to what I already had with the previous patch...?! ???
Attached.Did that patch change anything in comparison to the previous one? After applying this I see no differences to what I already had with the previous patch...?! ???
Also @Morten, if this is ok with you one of us should apply. (I haven't tested on windows, but nothing seems OS specific in this one)Feel free to do so - I've tested it under Windows meanwhile. It looks OK.
Did that patch change anything in comparison to the previous one? After applying this I see no differences to what I already had with the previous patch...?! ???The line endings are different... oh, LF and CR LF look exactly the same in your browser? ;)
If we are doing it for C/C++, why not python (and other languages) too?I guess simply no one got there yet.
Apologies for spacing and forgetting to give you credit in the log message, Alpha.No worries.
Fall-back for brace completion would have to be very conservative, because languages differ so greatly.Here is a fall-back (plus a small fix for the previous patch - it had read from the wrong environment variable). The language specific implementations will take some more time (and probably will require help from people who use those languages more frequently).
Index: src/sdk/cbeditor.cpp
===================================================================
--- src/sdk/cbeditor.cpp (revision 8496)
+++ src/sdk/cbeditor.cpp (working copy)
@@ -3076,9 +3076,9 @@
{
const wxChar ch = event.GetKey();
cbStyledTextCtrl* control = GetControl();
+ const int pos = control->GetCurrentPos();
if ( (ch == _T('\n')) || ( (control->GetEOLMode() == wxSCI_EOL_CR) && (ch == _T('\r')) ) )
{
- const int pos = control->GetCurrentPos();
const int currLine = control->LineFromPosition(pos);
const bool autoIndent = Manager::Get()->GetConfigManager(_T("editor"))->ReadBool(_T("/auto_indent"), true);
if (autoIndent && currLine > 0)
@@ -3093,9 +3093,27 @@
control->EndUndoAction();
}
}
- if( Manager::Get()->GetConfigManager(_T("editor"))->ReadBool(_T("/brace_completion"), true)
+ if( Manager::Get()->GetConfigManager(wxT("editor"))->ReadBool(wxT("/selection_brace_completion"), false)
|| control->IsBraceShortcutActive())
DoSelectionBraceCompletion(control, ch);
+ // brace completion
+ const wxString braces(wxT("([{)]}"));
+ const int braceIdx = braces.Find(ch);
+ if ( braceIdx != wxNOT_FOUND && pos == control->GetCurrentPos() // pos != curPos if selection brace completion succeeded
+ && Manager::Get()->GetConfigManager(wxT("editor"))->ReadBool(wxT("/brace_completion"), true))
+ {
+ if (control->GetCharAt(pos) == ch)
+ {
+ control->DeleteBack();
+ control->CharRight();
+ }
+ else if (braceIdx < (braces.Length() / 2))
+ {
+ const int closeIdx = braceIdx + (braces.Length() / 2);
+ if (control->GetCharAt(pos) != braces[closeIdx] || control->BraceMatch(pos) != wxNOT_FOUND)
+ control->InsertText(pos, braces[closeIdx]);
+ }
+ }
}
}
I did not make this a separate function because most languages will have very different requirements, so it would therefore remain relatively unused; do you agree?
I guess the tricky thing is that you probably don't want auto brace completion inside a string or comment, and different lexers have different style codes for their strings, but this would be hard to do right. (Doesn't look like your patch deals with this?)
cbStyledTextCtrl::IsComment()
cbStyledTextCtrl::IsString()
Index: src/plugins/contrib/SmartIndent/PythonSmartIndent.cpp
===================================================================
--- src/plugins/contrib/SmartIndent/PythonSmartIndent.cpp (revision 8500)
+++ src/plugins/contrib/SmartIndent/PythonSmartIndent.cpp (working copy)
@@ -71,6 +71,18 @@
}
}
+ bool braceCompleted = false;
if ( SelectionBraceCompletionEnabled() || stc->IsBraceShortcutActive() )
- ed->DoSelectionBraceCompletion(stc, ch);
+ braceCompleted = ed->DoSelectionBraceCompletion(stc, ch);
+ if (!braceCompleted && BraceCompletionEnabled())
+ {
+ ed->DoBraceCompletion(stc, ch);
+ if ( !(stc->IsComment(stc->GetStyleAt(pos)) || stc->IsComment(stc->GetStyleAt(pos - 2)))
+ && (ch == wxT('"') || ch == wxT('\'')) )
+ {
+ const wxString tripleQuote(3, ch);
+ if (stc->GetTextRange(pos - 3, pos) == tripleQuote && !stc->IsString(stc->GetStyleAt(pos - 4)))
+ stc->InsertText(pos, tripleQuote);
+ }
+ }
}
Tested and works well enough for me.It doesn't compile under wx2.9.x. this line:
if ((wxChar)GetCharAt(nextPos) != braces[closeIdx] || BraceMatch(nextPos) != wxNOT_FOUND)Yes. Not nice and I don't know if it would work for all Unicode characters... but yes. :-)
Attached I have re-factored to cbStyledTextCtrl (plus a slight improvement to brace completion).Oh dear... I'm afraid I just screwed the compatibility with the patch after the last commits of mine (renaming of SmartIndent). Maybe you can provide an updated version? Sorry - I didn't have that in mind.
Ok, I'm leaving this one to you guys.I am not really looking into it. Please continue testing, if possible. I was just the one breaking it. :P
Oh dear... I'm afraid I just screwed the compatibility with the patch after the last commits of mine (renaming of SmartIndent). Maybe you can provide an updated version? Sorry - I didn't have that in mind.Not a problem; update attached.
OK. If Morten doesn't break anything in between, ;D I will test and commit tonight.I'll keep my fingers away - I promise...
Committed rev 8514.Uh-oh... looks like I killed three of the lexers:
Index: src/sdk/resources/lexers/lexer_batch.xml
===================================================================
--- src/sdk/resources/lexers/lexer_batch.xml (revision 8529)
+++ src/sdk/resources/lexers/lexer_batch.xml (working copy)
@@ -78,7 +78,6 @@
BoxCommentMid=""
BoxCommentEnd=""
CaseSensitive="0"
- CaseSensitive="1"
LexerCommentStyles="1"
LexerCharacterStyles=""
LexerStringStyles=""
Index: src/sdk/resources/lexers/lexer_css.xml
===================================================================
--- src/sdk/resources/lexers/lexer_css.xml (revision 8529)
+++ src/sdk/resources/lexers/lexer_css.xml (working copy)
@@ -110,7 +110,6 @@
BoxCommentMid=" * "
BoxCommentEnd=" */"
CaseSensitive="0"
- CaseSensitive="1"
LexerCommentStyles="9"
LexerCharacterStyles=""
LexerStringStyles="13,14"
Index: src/sdk/resources/lexers/lexer_cmake.xml
===================================================================
--- src/sdk/resources/lexers/lexer_cmake.xml (revision 8529)
+++ src/sdk/resources/lexers/lexer_cmake.xml (working copy)
@@ -542,10 +542,7 @@
CaseSensitive="0"
LexerCommentStyles="1"
LexerStringStyles="2,3,4"
- CaseSensitive="1"
- LexerCommentStyles="1"
LexerCharacterStyles=""
- LexerStringStyles="2,3,4"
LexerPreprocessorStyles=""/>
</Lexer>
</CodeBlocks_lexer_properties>