Author Topic: Python Code Completion  (Read 52573 times)

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 11939
    • Travis build status
Re: Python Code Completion
« Reply #15 on: October 18, 2012, 03:38:40 pm »
Yes, this is probably the first step.
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline MortenMacFly

  • Administrator
  • Lives here!
  • *****
  • Posts: 9496
Re: Python Code Completion
« Reply #16 on: October 18, 2012, 04:33:41 pm »
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.
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: http://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: http://wiki.codeblocks.org/index.php?title=FAQ

Offline dmoore

  • Developer
  • Lives here!
  • *****
  • Posts: 1576
Re: Python Code Completion
« Reply #17 on: October 18, 2012, 05:58:50 pm »
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?

Offline MortenMacFly

  • Administrator
  • Lives here!
  • *****
  • Posts: 9496
Re: Python Code Completion
« Reply #18 on: October 18, 2012, 08:11:38 pm »
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...
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: http://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: http://wiki.codeblocks.org/index.php?title=FAQ

Offline dmoore

  • Developer
  • Lives here!
  • *****
  • Posts: 1576
Re: Python Code Completion
« Reply #19 on: October 18, 2012, 10:06:51 pm »
That's fine I'll follow up with him later. I see he registers handlers for cbEVT_COMPLETE_CODE and cbEVT_SHOW_CALL_TIP which the CC plugin (and not the SDK!) post messages to. I have now added the same handlers in the python code completion plugin.

Attached is a patch to get rid of some of the noise from the CC plugin on python and fortran files, which is really just a sequence of lexer checks scattered throughout the code like this:

Code: [Select]
           //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.
« Last Edit: October 18, 2012, 10:11:41 pm by dmoore »

Offline MortenMacFly

  • Administrator
  • Lives here!
  • *****
  • Posts: 9496
Re: Python Code Completion
« Reply #20 on: October 19, 2012, 06:48:20 am »
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
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: http://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: http://wiki.codeblocks.org/index.php?title=FAQ

Offline MortenMacFly

  • Administrator
  • Lives here!
  • *****
  • Posts: 9496
Re: Python Code Completion
« Reply #21 on: October 19, 2012, 06:59:10 am »
...going through all my email again, I found the patch of the Fortran guy again. NOtice that its indeed better to query filegroups and masks, because of customisation of the file extensions that are rather common in the Fortran world.

Code: [Select]
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()
 };
 
« Last Edit: October 19, 2012, 07:00:51 am by MortenMacFly »
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: http://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: http://wiki.codeblocks.org/index.php?title=FAQ

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 11939
    • Travis build status
Re: Python Code Completion
« Reply #22 on: October 19, 2012, 09:16:20 am »
This patch looks rather ugly. C++ CC must not care about other file types.
The check should be something like If file is C/C++ process it otherwise do nothing.
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline MortenMacFly

  • Administrator
  • Lives here!
  • *****
  • Posts: 9496
Re: Python Code Completion
« Reply #23 on: October 19, 2012, 10:04:21 am »
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.
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: http://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: http://wiki.codeblocks.org/index.php?title=FAQ

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 11939
    • Travis build status
Re: Python Code Completion
« Reply #24 on: October 19, 2012, 10:11:30 am »
What I meant is not only to trust the editor style - this might be wrong.
Do we have a function we could trust?
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline MortenMacFly

  • Administrator
  • Lives here!
  • *****
  • Posts: 9496
Re: Python Code Completion
« Reply #25 on: October 19, 2012, 11:34:14 am »
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.

But better than either only checking for the editor style or only checking for the file types and mask is probably doing both in a proper way.
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: http://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: http://wiki.codeblocks.org/index.php?title=FAQ

Offline dmoore

  • Developer
  • Lives here!
  • *****
  • Posts: 1576
Re: Python Code Completion
« Reply #26 on: October 19, 2012, 02:24:59 pm »
For the UI I thought it would be more reliable to trust the Lexer:

* C++ std headers have no extension
* Python scripts on unix are often missing an extension (they do usually have shebang and so could be inferred)
* As Rick has mentioned to me in the past, CC can be used for C like languages, hence we dont want to just restrict CC to C/C++
* The user can switch the highlight mode of a file. When they do i think their intent should be respected by CC.
* Note that i dont think either patch affects what the parser parses, just the files it offers a UI for. CC has a UI to control the parser i think.

So how about a more refined version. Each plugin has public member bool IsProviderFor(cbEditor *ed). That can do whatever checks that plugin prefers. For CC itself, since it is fallback, its method would be

Code: [Select]
For each CC plugin instance except me:
    if Plugin.IsProviderFor(ed):
        return false
return true
« Last Edit: October 19, 2012, 02:35:32 pm by dmoore »

Offline MortenMacFly

  • Administrator
  • Lives here!
  • *****
  • Posts: 9496
Re: Python Code Completion
« Reply #27 on: October 19, 2012, 02:48:25 pm »
For CC itself, since it is fallback, its method would be

Code: [Select]
For each CC plugin instance except me:
    if Plugin.IsProviderFor(ed):
        return false
return true

Yes, I think it should be something like that. Similar to what we actually do with plugins:
if Plugin.OffersFor(CC, Debugger...) [Do something.]
It can / has to be handled with CC plugins, too.

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.
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: http://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: http://wiki.codeblocks.org/index.php?title=FAQ

Offline dmoore

  • Developer
  • Lives here!
  • *****
  • Posts: 1576
Re: Python Code Completion
« Reply #28 on: October 19, 2012, 03:04:53 pm »
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.

I think that will need to wait until we refactor stuff into the SDK. Right now CC provides a couple of UI bits that all plugins use (call tip and completion) but plugins must provide their own symbol tree, right click menu options etc. Defining more complicated fallback behavior as you are proposing above will require more extensive reworking.

Offline dmoore

  • Developer
  • Lives here!
  • *****
  • Posts: 1576
Re: Python Code Completion
« Reply #29 on: October 24, 2012, 03:36:41 am »
Here's a revised patch to try. I've made the needed change to the fortran plugin as well.

(EDIT: Patch revised again, thx OllyDbg)

Code: [Select]
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);
« Last Edit: October 24, 2012, 05:35:40 am by dmoore »