svn checkout svn://svn.berlios.de/cbilplugin/trunk/PythonCodeCompletion
I see we have C/C++ code completion plugin(in trunk), Fortran code completion plugin, python code completion plugin. Maybe, we need to a common interface for all those plugins. ;)
* the shortcut keys (e.g. ctrl + space, ctrl+shift+space) worked for all CC plugins.Isn't this the case when all CC plugins call event.Ski() in their handler accordingly?
* For symbol browsing (which I haven't even begun to implement for python yet), share the symbol tab in the manager pane across plugins, though not sure how feasible that is. How would one separate the symbols for different languages?I would prefer having a separate UI for the languages, like done with Fortran. Because for mixed language projects (i.e. Fortran is often mixed with C/C++) this is the only way to go.
* the goto declaration/implementation stuff had a shared GUI (or at least didn't show inappropriately).I don't get it: Did it have a shared UI (when/where is it it gone?!) or do you wish it had one?!
* the shortcut keys (e.g. ctrl + space, ctrl+shift+space) worked for all CC plugins.Isn't this the case when all CC plugins call event.Ski() in their handler accordingly?
m_EditMenu->Append(idMenuCodeComplete, _("Complete code\tCtrl-Space"));
m_EditMenu->Append(idMenuShowCallTip, _("Show call tip\tCtrl-Shift-Space"));
I would prefer having a separate UI for the languages, like done with Fortran. Because for mixed language projects (i.e. Fortran is often mixed with C/C++) this is the only way to go.
* the goto declaration/implementation stuff had a shared GUI (or at least didn't show inappropriately).I don't get it: Did it have a shared UI (when/where is it it gone?!) or do you wish it had one?!
pos = menuBar->FindMenu(_("Sea&rch"));
if (pos != wxNOT_FOUND)
{
m_SearchMenu = menuBar->GetMenu(pos);
m_SearchMenu->Append(idMenuGotoFunction, _("Goto function...\tCtrl-Alt-G"));
m_SearchMenu->Append(idMenuGotoPrevFunction, _("Goto previous function\tCtrl-PgUp"));
m_SearchMenu->Append(idMenuGotoNextFunction, _("Goto next function\tCtrl-PgDn"));
m_SearchMenu->Append(idMenuGotoDeclaration, _("Goto declaration\tCtrl-Shift-."));
m_SearchMenu->Append(idMenuGotoImplementation, _("Goto implementation\tCtrl-."));
m_SearchMenu->Append(idMenuFindReferences, _("Find references\tAlt-."));
m_SearchMenu->Append(idMenuOpenIncludeFile, _("Open include file\tCtrl-Alt-."));
}
No because the menu items are provided by the Code Completion plugin and not the SDKUnderstood and makes sense.
Well I think it would be useful to at least have them share the symbols tab.But how would you differ symbols with the same name coming from different CC's? And also, syncing the symbols tab with the user's selection and re-freshing it becomes an issues, especially if it is thread based (as it is now). I think having a symbol tab for each language is not too much and makes it way easier to handle. Maybe a CC plugin can "request" such a tab from the SDK.
So no it doesn't have a shared UI and never did because the CC plugin currently provides those menu options. [...]Well - so altogether this sounds like a similar concept as for the debugger, isn't it? Sharing the dialogs via the SDK and having the plugins to specialise it. It would be unique (I've never heard of an IDE having such) but sounds good.
But how would you differ symbols with the same name coming from different CC's? And also, syncing the symbols tab with the user's selection and re-freshing it becomes an issues, especially if it is thread based (as it is now). I think having a symbol tab for each language is not too much and makes it way easier to handle. Maybe a CC plugin can "request" such a tab from the SDK.You'll have a combobox with the current language showed by the symbol browser. Changing the value in the combo could change the UI - ask the plugin to build the correct UI.
You'll have a combobox with the current language showed by the symbol browser. Changing the value in the combo could change the UI - ask the plugin to build the correct UI.
You'll have a combobox with the current language showed by the symbol browser. Changing the value in the combo could change the UI - ask the plugin to build the correct UI.I am still not really convinced. If you have large projects with a lot of CC members, building the UI every time you switch really takes time and can be avoided if you have just two symbol browser that both would need no update when switching between them. You can see this now already with the C++ tree, if you enable "workspace level".
...If you have large projects with a lot of CC members, building the UI every time you switch really takes time...When switching the language the only operations that will happen will be oldPanel->Hide() and newPanel->Show(). The plugins will keep all panels up to date and full with the correct data.
When switching the language the only operations that will happen will be oldPanel->Hide() and newPanel->Show().True, but it wouldn't allow you to have i.e. both symbol trees under each other, which may be desired. If that's possible, too I am fine with it. Remember, that in mixed-code project you switch rather often from one to another language. So seeing i.e. all relevant methods of your project together is helpful for navigation.
What happens with Fortran files?I recall a chat I had with the Fortran plugin maintainer. Maybe you should ask him first, before implementing such. IIRC he solved it somehow and provided a patch. Sore there might be an API already in place for that.
What happens with Fortran files?I recall a chat I had with the Fortran plugin maintainer. Maybe you should ask him first, before implementing such. IIRC he solved it somehow and provided a patch. Sore there might be an API already in place for that.
Did we accept a patch for this or does he just maintain patches for the repackaged C::B he releases?IIRC he sent me something. But honestly I don't recall what I did with it because it conflicted with the re-factoring of the SmartIdent feature. Its best to ask him again. I cannot have a closer look atm...
//WORKAROUND FOR PYTHON/FORTRAN
cbStyledTextCtrl *control = ed->GetControl();
if (control->GetLexer() == wxSCI_LEX_PYTHON || control->GetLexer() == wxSCI_LEX_F77 || control->GetLexer() == wxSCI_LEX_FORTRAN)
return;
Realize this is a bit of a hack, but it will do the job until we refactor parts of CC to the SDK.No problem - I'll try. What makes me wonder is that this is needed in so many places?! :o
Index: codecompletion.cpp
===================================================================
--- codecompletion.cpp (revision 7604)
+++ codecompletion.cpp (working copy)
@@ -57,6 +57,7 @@
#include "parser/tokenizer.h"
#include "selectincludefile.h"
#include "ccdebuginfo.h"
+#include "filegroupsandmasks.h"
#define CC_CODECOMPLETION_DEBUG_OUTPUT 0
@@ -809,6 +810,12 @@
if (type == mtEditorManager)
{
+ if (cbEditor* ed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor())
+ {
+ if (IsFortranFile(ed->GetShortName()))
+ return;
+ }
+
wxString NameUnderCursor;
bool IsInclude = false;
const bool nameUnderCursor = EditorHasNameUnderCursor(NameUnderCursor, IsInclude);
@@ -930,6 +937,21 @@
m_NativeParser.CreateClassBrowser();
+ // determine Fortran Source file group index
+ m_FortranGroupIdx = -1;
+ const FilesGroupsAndMasks* fgam = Manager::Get()->GetProjectManager()->GetFilesGroupsAndMasks();
+ if (fgam)
+ {
+ for (unsigned int i = 0; i < fgam->GetGroupsCount(); i++)
+ {
+ if (fgam->GetGroupName(i).Lower().Contains(_T("fortran")))
+ {
+ m_FortranGroupIdx = i;
+ break;
+ }
+ }
+ }
+
// hook to editors
EditorHooks::HookFunctorBase* myhook = new EditorHooks::HookFunctor<CodeCompletion>(this, &CodeCompletion::EditorEventHook);
m_EditorHookId = EditorHooks::RegisterHook(myhook);
@@ -1505,6 +1527,9 @@
if (!ed)
return;
+ if (IsFortranFile(ed->GetShortName()))
+ return;
+
// calculate the size of the calltips window
int pos = ed->GetControl()->GetCurrentPos();
wxPoint p = ed->GetControl()->PointFromPosition(pos); // relative point
@@ -1745,6 +1770,9 @@
if (!ed)
return;
+ if (IsFortranFile(ed->GetShortName()))
+ return;
+
cbStyledTextCtrl* control = ed->GetControl();
const int pos = control->GetCurrentPos();
const int style = control->GetStyleAt(pos);
@@ -2593,6 +2621,12 @@
return;
}
+ if (IsFortranFile(ed->GetShortName()))
+ {
+ event.Skip();
+ return;
+ }
+
if (ed->GetControl()->CallTipActive())
ed->GetControl()->CallTipCancel();
// CCLogger::Get()->DebugLog(F(_T("CodeCompletion::OnValueTooltip: %p"), ed));
@@ -3174,6 +3208,12 @@
return;
}
+ if (IsFortranFile(editor->GetShortName()))
+ {
+ event.Skip();
+ return;
+ }
+
cbStyledTextCtrl* control = editor->GetControl();
// if (event.GetEventType() == wxEVT_SCI_CHARADDED)
@@ -3493,3 +3533,19 @@
if (m_NativeParser.ReparseFile(project, m_LastFile))
CCLogger::Get()->DebugLog(_T("Reparsing when typing for editor ") + m_LastFile);
}
+
+bool CodeCompletion::IsFortranFile(wxString fileName)
+{
+ bool isFort = false;
+ if (m_FortranGroupIdx != -1)
+ {
+ const FilesGroupsAndMasks* fgam = Manager::Get()->GetProjectManager()->GetFilesGroupsAndMasks();
+ if (fgam)
+ {
+ if ( fileName.Find('.',true) != wxNOT_FOUND &&
+ fgam->MatchesMask(fileName.AfterLast('.').Prepend(_T(".")), m_FortranGroupIdx) )
+ isFort = true;
+ }
+ }
+ return isFort;
+}
Index: codecompletion.h
===================================================================
--- codecompletion.h (revision 7604)
+++ codecompletion.h (working copy)
@@ -235,6 +235,9 @@
/** delayed running of editor activated event, only the last activated editor should be considered*/
void OnEditorActivatedTimer(wxTimerEvent& event);
+ /** determines if file is Fortran file */
+ bool IsFortranFile(wxString fileName);
+
/** Not used*/
int m_PageIndex;
/** Indicates CC's initialization is done*/
@@ -329,6 +332,9 @@
typedef std::map<cbProject*, wxArrayString> ReparsingMap;
ReparsingMap m_ReparsingMap;
+ /** index of Fortran Source file group */
+ int m_FortranGroupIdx;
+
DECLARE_EVENT_TABLE()
};
The check should be something like If file is C/C++ process it otherwise do nothing.I didn't mean to apply it, I was showing it for reference. In the end in your patch, don't you check for other "filetypes" than C/C+, too? What I meant is not only to trust the editor style - this might be wrong.
What I meant is not only to trust the editor style - this might be wrong.Do we have a function we could trust?
Not atm.What I meant is not only to trust the editor style - this might be wrong.Do we have a function we could trust?
For each CC plugin instance except me:
if Plugin.IsProviderFor(ed):
return false
return true
For CC itself, since it is fallback, its method would beYes, I think it should be something like that. Similar to what we actually do with plugins:CodeFor each CC plugin instance except me:
if Plugin.IsProviderFor(ed):
return false
return true
BTW: We should also consider several CC plugins for one language, like Clang and Ctags - if one fails, the other can be queried as fallback. While working on the integration of Erans CC into C::B I was facing such. So in the code above, not only return "false", but do some more intelligent stuff, like "if generally responsible, do CC and return "true", but if the not enough information to complete, return false and let others try"... You get the idea.
Index: src/plugins/codecompletion/codecompletion.cpp
===================================================================
--- src/plugins/codecompletion/codecompletion.cpp (revision 8464)
+++ src/plugins/codecompletion/codecompletion.cpp (working copy)
@@ -727,8 +727,12 @@
if ( ParserCommon::FileType(filename) == ParserCommon::ftOther
&& Manager::Get()->GetPluginManager()->IsFileExtRegistered(filename) )
return;
+
+ if(!IsProviderFor(ed))
+ return;
}
+
wxString NameUnderCursor;
bool IsInclude = false;
const bool nameUnderCursor = CodeCompletionHelper::EditorHasNameUnderCursor(NameUnderCursor, IsInclude);
@@ -825,6 +829,16 @@
return true;
}
+bool CodeCompletion::IsProviderFor(cbEditor *ed)
+{
+ PluginsArray pa=Manager::Get()->GetPluginManager()->GetCodeCompletionOffers();
+ for(unsigned int i = 0; i < pa.Count(); ++i)
+ if(pa[i]!=this && static_cast<cbCodeCompletionPlugin*>(pa[i])->IsProviderFor(ed))
+ return false;
+ return true;
+}
+
+
int CodeCompletion::CodeComplete()
{
if (!IsAttached() || !m_InitDone)
@@ -835,6 +849,9 @@
if (!ed)
return -3;
+ if(!IsProviderFor(ed))
+ return -3;
+
FileType ft = FileTypeOf(ed->GetShortName());
const bool caseSens = m_NativeParser.GetParser().Options().caseSensitive;
@@ -1015,6 +1032,9 @@
if (!ed)
return;
+ if(!IsProviderFor(ed))
+ return;
+
wxString filename = ed->GetShortName();
if ( ParserCommon::FileType(filename) == ParserCommon::ftOther
&& Manager::Get()->GetPluginManager()->IsFileExtRegistered(filename) )
@@ -1342,6 +1362,9 @@
return;
}
+ if(!IsProviderFor(editor))
+ return;
+
cbStyledTextCtrl* control = editor->GetControl();
if (event.GetEventType() == wxEVT_SCI_CHARADDED)
Index: src/plugins/codecompletion/codecompletion.h
===================================================================
--- src/plugins/codecompletion/codecompletion.h (revision 8464)
+++ src/plugins/codecompletion/codecompletion.h (working copy)
@@ -89,6 +89,7 @@
virtual wxArrayString GetCallTips() { return wxArrayString(); }
virtual int CodeComplete();
virtual void ShowCallTip();
+ virtual bool IsProviderFor(cbEditor *ed);
/** give auto suggestions on preprocessor directives*/
void CodeCompletePreprocessor();
Index: src/sdk/cbplugin.cpp
===================================================================
--- src/sdk/cbplugin.cpp (revision 8464)
+++ src/sdk/cbplugin.cpp (working copy)
@@ -1216,6 +1216,7 @@
return -1;
}
+
//ToDo: Is this c++ only?
int cbSmartIndentPlugin::GetFirstBraceInLine(cbStyledTextCtrl* stc, int string_style)const
{
Index: src/include/cbplugin.h
===================================================================
--- src/include/cbplugin.h (revision 8464)
+++ src/include/cbplugin.h (working copy)
@@ -743,6 +743,24 @@
virtual wxArrayString GetCallTips() = 0;
virtual int CodeComplete() = 0;
virtual void ShowCallTip() = 0;
+ /** @brief Does this plugin handle code completion for the editor cb?
+ *
+ * A plugin should override this function to indicate whether it will
+ * provide completion and call tips for the editor. The plugin should
+ * then prepare to handle codecomplete and calltip menu messages if
+ * it returns true. To implement this function, plugins will usually
+ * check the mimetype of the file or the current lexer (highlight
+ * language).
+ *
+ * Note: Currently the core CC plugin provides a default CodeCompletion
+ * implementation for any file type that is not provided for by any
+ * other CC plugins. The calltip and main menu options that can be handled
+ * by any CC plugin is also supplied by the core CC plugin.
+ *
+ * @param cb The editor for which code completion
+ * @return return true if the plugin handles completion for this editor,
+ * false otherwise*/
+ virtual bool IsProviderFor(cbEditor* /*cb*/) { return false; }
};
/** @brief Base class for wizard plugins
@@ -857,6 +875,7 @@
/** Get the last non-whitespace character from position in line */
wxChar GetNextNonWhitespaceCharOfLine(cbStyledTextCtrl* stc, int position = -1, int *pos = 0)const;
+
bool AutoIndentEnabled()const;
bool SmartIndentEnabled()const;
bool BraceSmartIndentEnabled()const;
Index: src/plugins/contrib/FortranProject/fortranproject.cpp
===================================================================
--- src/plugins/contrib/FortranProject/fortranproject.cpp (revision 27)
+++ src/plugins/contrib/FortranProject/fortranproject.cpp (working copy)
@@ -1226,6 +1226,16 @@
return -5;
}
+bool FortranProject::IsProviderFor(cbEditor *cb)
+{
+ if (!ed
+ || !m_pNativeParser->IsFileFortran(ed->GetShortName())
+ || !Manager::Get()->GetConfigManager(_T("fortran_project"))->ReadBool(_T("/use_code_completion"), true))
+ {
+ return false;
+ }
+ return true;
+}
+
void FortranProject::ShowCallTip()
{
if (!IsAttached() || !m_InitDone)
Index: src/plugins/contrib/FortranProject/fortranproject.h
===================================================================
--- src/plugins/contrib/FortranProject/fortranproject.h (revision 27)
+++ src/plugins/contrib/FortranProject/fortranproject.h (working copy)
@@ -46,6 +46,7 @@
virtual wxArrayString GetCallTips();
virtual int CodeComplete();
virtual void ShowCallTip();
+ virtual bool IsProviderFor(cbEditor *cb);
void OnCodeComplete(wxCommandEvent& event);
void OnShowCallTip(wxCommandEvent& event);
void CompleteCodeEvt(CodeBlocksEvent& event);
+bool FortranProject::IsProviderFor(cbEditor *cb)
+{
+ if (!ed
+ || !m_pNativeParser->IsFileFortran(ed->GetShortName())
+ || !Manager::Get()->GetConfigManager(_T("fortran_project"))->ReadBool(_T("/use_code_completion"), true))
+ {
+ return;
+ }
+}
+
Here's a revised patch to try. I've made the needed change to the fortran plugin as well.This patch does not apply for me. :-\ Furthermore, it won't work with Fortran as you provide a cbEditor* cb via the interface and then use "ed->" internally.
However, after applying this patch manually and adjusting the tiny issues I am now testing...
As should now be clear I didn't test the FORTRAN bitsMaybe darmar can do some trials, too. He might have something to contribute... I'll send him a PM.
Here's a revised patch to try. I've made the needed change to the fortran plugin as well.
Index: src/plugins/codecompletion/codecompletion.cpp
===================================================================
--- src/plugins/codecompletion/codecompletion.cpp (revision 8464)
@@ -727,8 +727,12 @@
if ( ParserCommon::FileType(filename) == ParserCommon::ftOther
&& Manager::Get()->GetPluginManager()->IsFileExtRegistered(filename) )
return;
void FortranProject::RegisterFileExtensions()
{
PluginManager* plugman = Manager::Get()->GetPluginManager();
StringSet fileExts;
m_pNativeParser->GetFortranFileExts(fileExts);
plugman->RegisterCCFileExts(_T("FortranProject"), fileExts);
}
Aren't these the same extensions as used for Syntax highlighting? (configured in Settings->Editor->SyntaxHighlighting->Filemasks)Yes, ...so what? Id that bad? ???
if (fgm->GetGroupName(i) == _T("Sources") && fgm->MatchesMask(ext, i))
return ftSource;
if (fgm->GetGroupName(i) == _T("Headers") && fgm->MatchesMask(ext, i))
return ftHeader;
if (fgm->GetGroupName(i).Contains(_T("Source")) && fgm->MatchesMask(ext, i))
return ftSource;
if (fgm->GetGroupName(i).Contains(_T("Header")) && fgm->MatchesMask(ext, i))
return ftHeader;
So I have to configure the same thing twice? Once for syntax highlighting and a second time for CC?Aren't these the same extensions as used for Syntax highlighting? (configured in Settings->Editor->SyntaxHighlighting->Filemasks)Yes, ...so what? Id that bad? ???
Aren't these the same extensions as used for Syntax highlighting? (configured in Settings->Editor->SyntaxHighlighting->Filemasks)
CodeIndex: src/plugins/codecompletion/codecompletion.cpp
===================================================================
--- src/plugins/codecompletion/codecompletion.cpp (revision 8464)
@@ -727,8 +727,12 @@
if ( ParserCommon::FileType(filename) == ParserCommon::ftOther
&& Manager::Get()->GetPluginManager()->IsFileExtRegistered(filename) )
return;
The idea is the same as in dmoore's patch. The function "IsFileExtRegistered" is doing similar thing as "IsProviderFor(ed)" in this patch.
Is it only the plugins other than CC that register files? So only IsFileExtRegistered returns true only for Fortran files if only CC and fortran plugins are installed?
For python, I thought it made the most sense to rely on the lexer to decide what to offer python code completion for, but basing it on file extensions might make the most sense in other cases.
The patch I proposed leaves it to the plugin to decide what it wants to do.
I have attached a patch for codecompletion.cpp. I have deleted calls to 'IsFileExtRegistered' in this patch also.So - this seems pretty much complete and does what I should do. @dmoore: are you happy with his, too? It looks fine here, after a few hours of testing... Looks like the "least common denominator" we were looking for... ;-)
I haven't had time to look, but everything darmar said sounds good to me, so commit away unless you want me to test.Committed with credits. Whats missing are the adjustments to the Fortran project plugin - darmar will take case I guess... ;D
Now working nicely with PythonCodeCompletion plugin.Well done then. :-)
They are unused any more and can be deleted, I think.Done in trunk. Thank you!
dmoore: Do you follow Alpha's changes to the CC in this branch https://github.com/alpha0010/codeblocks_sf/compare/cc_interface?
Is there enough ready to be able to do anything with it yet? Testing out his work with Python would obviously be a good test.I think so. API for auto-complete popups, documentation popups, tooltips, and calltips are present and (mostly) functional. These subsystems still contain some hardcoded defaults, but other than that, I believe it is ready for a test with Python. (Be prepared for uncaught bugs and frequent API breaks though ::).)
I think so. API for auto-complete popups, documentation popups, tooltips, and calltips are present and (mostly) functional. These subsystems still contain some hardcoded defaults, but other than that, I believe it is ready for a test with Python. (Be prepared for uncaught bugs and frequent API breaks though ::).)