I remember alpha mentioning that they were hardcoded on the clang code completion thread.
But I believe this bug was cause by my commit rev9920.
Here, I have create two empty virtual function:
/** read Parser options from configure file */
virtual void ReadOptions() {}
/** write Parse options to configure file */
virtual void WriteOptions() {}
But in NativeParser's constructor
NativeParser::NativeParser() :
m_TimerParsingOneByOne(this, idTimerParsingOneByOne),
m_ClassBrowser(nullptr),
m_ClassBrowserIsFloating(false),
m_ImageList(nullptr),
m_ParserPerWorkspace(false),
m_EditorStartWord(-1),
m_EditorEndWord(-1),
m_LastAISearchWasGlobal(false),
m_LastControl(nullptr),
m_LastFunctionIndex(-1),
m_LastFuncTokenIdx(-1),
m_LastLine(-1),
m_LastResult(-1)
{
m_TempParser = new ParserBase;
m_Parser = m_TempParser;
The temp parser will call:
ParserBase::ParserBase()
{
m_TokenTree = new TokenTree;
m_TempTokenTree = new TokenTree;
ReadOptions();
}
Thus, ReadOptions() does nothing.
But ReadOptions() does do some jobs in
void Parser::ReadOptions()
{
ConfigManager* cfg = Manager::Get()->GetConfigManager(_T("code_completion"));
// one-time default settings change: upgrade everyone
bool force_all_on = !cfg->ReadBool(_T("/parser_defaults_changed"), false);
if (force_all_on)
{
cfg->Write(_T("/parser_defaults_changed"), true);
cfg->Write(_T("/parser_follow_local_includes"), true);
cfg->Write(_T("/parser_follow_global_includes"), true);
cfg->Write(_T("/want_preprocessor"), true);
cfg->Write(_T("/parse_complex_macros"), true);
}
// Page "Code Completion"
m_Options.useSmartSense = cfg->ReadBool(_T("/use_SmartSense"), true);
m_Options.whileTyping = cfg->ReadBool(_T("/while_typing"), true);
m_Options.caseSensitive = cfg->ReadBool(_T("/case_sensitive"), false);
// Page "C / C++ parser"
m_Options.followLocalIncludes = cfg->ReadBool(_T("/parser_follow_local_includes"), true);
m_Options.followGlobalIncludes = cfg->ReadBool(_T("/parser_follow_global_includes"), true);
m_Options.wantPreprocessor = cfg->ReadBool(_T("/want_preprocessor"), true);
m_Options.parseComplexMacros = cfg->ReadBool(_T("/parse_complex_macros"), true);
// Page "Symbol browser"
m_BrowserOptions.showInheritance = cfg->ReadBool(_T("/browser_show_inheritance"), false);
m_BrowserOptions.expandNS = cfg->ReadBool(_T("/browser_expand_ns"), false);
m_BrowserOptions.treeMembers = cfg->ReadBool(_T("/browser_tree_members"), true);
// Token tree
m_BrowserOptions.displayFilter = (BrowserDisplayFilter)cfg->ReadInt(_T("/browser_display_filter"), bdfFile);
m_BrowserOptions.sortType = (BrowserSortType)cfg->ReadInt(_T("/browser_sort_type"), bstKind);
// Page "Documentation:
m_Options.storeDocumentation = cfg->ReadBool(_T("/use_documentation_helper"), false);
// force re-read of file types
ParserCommon::EFileType ft_dummy = ParserCommon::FileType(wxEmptyString, true);
wxUnusedVar(ft_dummy);
}
I'm thinking a solution.
Hi,ollydbg,thank you for your reply.Is there a special edition when revision reaches 10000? :)
I don't know, you may ask our release managers. ;D
I've tested the new revision,but it looks like that the bug is not fixed yet.
Now code completion's setting can be saved correctly, but the setting does not take effect at all.
e.g, I disable the code completion first,then restart IDE.When opening a project and trying to type
something, code completion window poped up unexpected.
I'm sorry I can't upload two attachments once so I merge them into one.
This is another but, currently all the codecompletion's settings were related to CodeCompletion plugin, not the SDK.
We have a general code completion interface in SDK(this was done by our dev Alpha), so I see that the SDK should have some options for this.
I just debugged a little.
At F:\cb_sf_git\trunk\src\plugins\codecompletion\codecompletion.cpp:927
[debug]> bt 30
[debug]#0 CodeCompletion::GetAutocompList (this=0x6ceb368, isAuto=true, ed=0x14f76e80, tknStart=@0x22f8cc: 46, tknEnd=@0x22f8d0: 46) at F:\cb_sf_git\trunk\src\plugins\codecompletion\codecompletion.cpp:927
[debug]#1 0x0109f09b in CCManager::OnCompleteCode (this=0x14f291a8, event=...) at F:\cb_sf_git\trunk\src\sdk\ccmanager.cpp:427
[debug]#2 0x0129e4ab in cbEventFunctor<CCManager, CodeBlocksEvent>::Call (this=0x14f2ecc8, event=...) at F:\cb_sf_git\trunk\src\include\cbfunctor.h:49
[debug]#3 0x01108c2a in Manager::ProcessEvent (this=0x52fbda0, event=...) at F:\cb_sf_git\trunk\src\sdk\manager.cpp:263
[debug]#4 0x010a1ec6 in CCManager::OnTimer (this=0x14f291a8, event=...) at F:\cb_sf_git\trunk\src\sdk\ccmanager.cpp:957
[debug]#5 0x627015f1 in wxAppConsole::HandleEvent(wxEvtHandler*, void (wxEvtHandler::*)(wxEvent&), wxEvent&) const () from E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\lib\gcc_dll\wxmsw28u_gcc_custom.dll
[debug]#6 0x6276a07e in wxEvtHandler::ProcessEventIfMatches(wxEventTableEntryBase const&, wxEvtHandler*, wxEvent&) () from E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\lib\gcc_dll\wxmsw28u_gcc_custom.dll
[debug]#7 0x6276a457 in wxEvtHandler::SearchDynamicEventTable(wxEvent&) () from E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\lib\gcc_dll\wxmsw28u_gcc_custom.dll
[debug]#8 0x6276a514 in wxEvtHandler::ProcessEvent(wxEvent&) () from E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\lib\gcc_dll\wxmsw28u_gcc_custom.dll
[debug]#9 0x62837a80 in wxTimerBase::Notify() () from E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\lib\gcc_dll\wxmsw28u_gcc_custom.dll
[debug]#10 0x62799836 in wxTimerWndProc(HWND__*, unsigned int, unsigned int, long)@16 () from E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\lib\gcc_dll\wxmsw28u_gcc_custom.dll
[debug]#11 0x7e418734 in USER32!GetDC () from C:\WINDOWS\system32\user32.dll
[debug]#12 0x00030a6c in ?? ()
[debug]#13 0x00000113 in ?? ()
[debug]#14 0x00000009 in ?? ()
[debug]#15 0x00000000 in ?? ()
[debug]>>>>>>cb_gdb:
And the code:
std::vector<CodeCompletion::CCToken> CodeCompletion::GetAutocompList(bool isAuto, cbEditor* ed, int& tknStart, int& tknEnd)
{
std::vector<CCToken> tokens;
if (!IsAttached() || !m_InitDone)
return tokens;
cbStyledTextCtrl* stc = ed->GetControl();
const int style = stc->GetStyleAt(tknEnd);
const wxChar curChar = stc->GetCharAt(tknEnd - 1);
if (isAuto) // filter illogical cases of auto-launch
{
if ( ( curChar == wxT(':') // scope operator
&& stc->GetCharAt(tknEnd - 2) != wxT(':') )
|| ( curChar == wxT('>') // '->'
&& stc->GetCharAt(tknEnd - 2) != wxT('-') )
|| ( wxString(wxT("<\"/")).Find(curChar) != wxNOT_FOUND // #include directive
&& !stc->IsPreprocessor(style) ) )
{
return tokens;
}
}
const int lineIndentPos = stc->GetLineIndentPosition(stc->GetCurrentLine());
const wxChar lineFirstChar = stc->GetCharAt(lineIndentPos);
if (lineFirstChar == wxT('#'))
{
const int startPos = stc->WordStartPosition(lineIndentPos + 1, true);
const int endPos = stc->WordEndPosition(lineIndentPos + 1, true);
const wxString str = stc->GetTextRange(startPos, endPos);
if (str == wxT("include") && tknEnd > endPos)
{
DoCodeCompleteIncludes(ed, tknStart, tknEnd, tokens);
}
else if (endPos >= tknEnd && tknEnd > lineIndentPos)
DoCodeCompletePreprocessor(tknStart, tknEnd, ed, tokens);
else if ( ( str == wxT("define")
|| str == wxT("if")
|| str == wxT("ifdef")
|| str == wxT("ifndef")
|| str == wxT("elif")
|| str == wxT("elifdef")
|| str == wxT("elifndef")
|| str == wxT("undef") )
&& tknEnd > endPos )
{
DoCodeComplete(tknEnd, ed, tokens, true);
}
return tokens;
}
else if (curChar == wxT('#'))
return tokens;
else if (lineFirstChar == wxT(':') && curChar == _T(':'))
return tokens;
if ( stc->IsString(style)
|| stc->IsComment(style)
|| stc->IsCharacter(style)
|| stc->IsPreprocessor(style) )
{
return tokens;
}
DoCodeComplete(tknEnd, ed, tokens);
return tokens;
}
Here, we can add a if condition to solve(workaround) this issue.
std::vector<CodeCompletion::CCToken> CodeCompletion::GetAutocompList(bool isAuto, cbEditor* ed, int& tknStart, int& tknEnd)
{
std::vector<CCToken> tokens;
if (!IsAttached() || !m_InitDone || Code suggestion is not allowed)
return tokens;
But I think the condition should be put in SDK, not the single codecompletion plugin.
EDIT:
We can use this variable
// for CC
m_UseCodeCompletion = cfg->ReadBool(_T("/use_code_completion"), true);
Similar like the usage below:
void CodeCompletion::EditorEventHook(cbEditor* editor, wxScintillaEvent& event)
{
if (!IsAttached() || !m_InitDone || !m_UseCodeCompletion)
{
event.Skip();
return;
}
if ( !IsProviderFor(editor) )
{
event.Skip();
return;
}
cbStyledTextCtrl* control = editor->GetControl();
if (event.GetEventType() == wxEVT_SCI_CHARADDED)
{ TRACE(_T("wxEVT_SCI_CHARADDED")); }
else if (event.GetEventType() == wxEVT_SCI_CHANGE)
{ TRACE(_T("wxEVT_SCI_CHANGE")); }
else if (event.GetEventType() == wxEVT_SCI_KEY)
{ TRACE(_T("wxEVT_SCI_KEY")); }
else if (event.GetEventType() == wxEVT_SCI_MODIFIED)
{ TRACE(_T("wxEVT_SCI_MODIFIED")); }
else if (event.GetEventType() == wxEVT_SCI_AUTOCOMP_SELECTION)
{ TRACE(_T("wxEVT_SCI_AUTOCOMP_SELECTION")); }
else if (event.GetEventType() == wxEVT_SCI_AUTOCOMP_CANCELLED)
{ TRACE(_T("wxEVT_SCI_AUTOCOMP_CANCELLED")); }
if ( m_NativeParser.GetParser().Options().whileTyping
&& ( (event.GetModificationType() & wxSCI_MOD_INSERTTEXT)
|| (event.GetModificationType() & wxSCI_MOD_DELETETEXT) ) )
{
m_NeedReparse = true;
}
if (control->GetCurrentLine() != m_CurrentLine)
{
if (m_NeedReparse)
{
TRACE(_T("CodeCompletion::EditorEventHook: Starting m_TimerRealtimeParsing."));
m_TimerRealtimeParsing.Start(REALTIME_PARSING_DELAY, wxTIMER_ONE_SHOT);
m_CurrentLength = control->GetLength();
m_NeedReparse = false;
}
if (event.GetEventType() == wxEVT_SCI_UPDATEUI)
{
m_ToolbarNeedRefresh = true;
TRACE(_T("CodeCompletion::EditorEventHook: Starting m_TimerToolbar."));
if (m_TimerEditorActivated.IsRunning())
m_TimerToolbar.Start(EDITOR_ACTIVATED_DELAY + 1, wxTIMER_ONE_SHOT);
else
m_TimerToolbar.Start(TOOLBAR_REFRESH_DELAY, wxTIMER_ONE_SHOT);
}
}
// allow others to handle this event
event.Skip();
}
If it is this CC plugin specifically that we do not want acting (but allow another xyzCC plugin to still run), then CC should return ccpsInactive from CodeCompletion::GetProviderStatusFor() (possibly needing to call CCManager::NotifyPluginStatus() if this is changed during runtime to force a recheck of options).
If all code completion should be globally disabled, then that is a config option that should be implemented within CCManager (probably at the top of CCManager::OnCompleteCode()). I guess I never did build a dialogue for CCManager though... :-\
Hi, Alpha, I add the code at the beginning of CodeCompletion::GetProviderStatusFor(cbEditor* ed), and code completion is diabled correctly.
if (!m_UseCodeCompletion)
return ccpsInactive;
Some member variables about code completion options, like m_CCAutoLaunch, m_CCAutoLaunchChars, m_CCLaunchDelay, m_CCFillupChars, are declared but never used. I remember these options worked fine in previous revision. I compare working copy with previous copy, and find that they were removed from CodeCompletion::EditorEventHook in rev 9690 as dead code, so changing these settings of code completion takes no effect.