From 37da0f3e739a190f5fa076b4762af53cd23b64d6 Mon Sep 17 00:00:00 2001 From: Robert Meerman Date: Tue, 16 Aug 2011 15:34:04 +0100 Subject: [PATCH 1/7] Feature: Callable parameter completion Prior to this patch opening parenthesis were not considered part of the current word, so a completion token such as ``myfunc(`` would never test positive for a trailing ``(``. --- ftplugin/pythoncomplete.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ftplugin/pythoncomplete.vim b/ftplugin/pythoncomplete.vim index 57add71..7bda2bf 100644 --- a/ftplugin/pythoncomplete.vim +++ b/ftplugin/pythoncomplete.vim @@ -74,7 +74,7 @@ function! pythoncomplete#Complete(findstart, base) while idx > 0 let idx -= 1 let c = line[idx] - if c =~ '\w' || c =~ '\.' + if c =~ '\w' || c =~ '\.' || c == "(" let cword = c . cword continue elseif strlen(cword) > 0 || idx == 0 From c754544da42b65f0af48b5452e60e97f3cc93745 Mon Sep 17 00:00:00 2001 From: Robert Meerman Date: Tue, 16 Aug 2011 15:35:06 +0100 Subject: [PATCH 2/7] Fix: Completion of class initialiser parameters This patch fixes completion of parameters required by a class when creating a new instance. For example completing ``MyClass(`` should take the parameters from ``MyClass.__init__``. The ``_ctor`` closure within ``Completer.get_arguments`` always raised a NameError exception because the function signature named its incoming argument ``obj`` rather than ``class_ob``. --- ftplugin/pythoncomplete.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ftplugin/pythoncomplete.vim b/ftplugin/pythoncomplete.vim index 7bda2bf..15ece75 100644 --- a/ftplugin/pythoncomplete.vim +++ b/ftplugin/pythoncomplete.vim @@ -157,7 +157,7 @@ class Completer(object): return doc.replace('"',' ').replace("'",' ') def get_arguments(self,func_obj): - def _ctor(obj): + def _ctor(class_ob): try: return class_ob.__init__.im_func except AttributeError: for base in class_ob.__bases__: From 53d77192d86b1730a0f492df0c06bb38ed942d1d Mon Sep 17 00:00:00 2001 From: Robert Meerman Date: Tue, 16 Aug 2011 15:35:41 +0100 Subject: [PATCH 3/7] Fix: Parameter completion for meta-classes The test that determined if ``func_obj`` is a class did not cope with meta-classes (which are both a class, and a type). Generally ``type()`` is not a robust way to reason about the Python objects, so this patch replaces all checks of the form:: type(foo) == types.FooType with calls to the ``inspect`` module, for instance:: inspect.isclass(foo) inspect.ismethod(foo) inspect.isfuction(foo) --- ftplugin/pythoncomplete.vim | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/ftplugin/pythoncomplete.vim b/ftplugin/pythoncomplete.vim index 15ece75..db4ced1 100644 --- a/ftplugin/pythoncomplete.vim +++ b/ftplugin/pythoncomplete.vim @@ -88,7 +88,7 @@ endfunction function! s:DefPython() python << PYTHONEOF -import sys, tokenize, cStringIO, types +import sys, tokenize, cStringIO, inspect from token import NAME, DEDENT, NEWLINE, STRING debugstmts=[] @@ -165,13 +165,15 @@ class Completer(object): if rc is not None: return rc return None + # Avoid "type(foo) == types.ClassType", it rejects meta-classes + arg_offset = 1 - if type(func_obj) == types.ClassType: func_obj = _ctor(func_obj) - elif type(func_obj) == types.MethodType: func_obj = func_obj.im_func + if inspect.isclass(func_obj): func_obj = _ctor(func_obj) + elif inspect.ismethod(func_obj): func_obj = func_obj.im_func else: arg_offset = 0 - + arg_text='' - if type(func_obj) in [types.FunctionType, types.LambdaType]: + if inspect.isfunction(func_obj): try: cd = func_obj.func_code real_args = cd.co_varnames[arg_offset:cd.co_argcount] @@ -503,10 +505,10 @@ class PyParser: newscope = Scope('result',0) scp = self.currentscope while scp != None: - if type(scp) == Function: + if inspect.isfunction(scp): slice = 0 #Handle 'self' params - if scp.parent != None and type(scp.parent) == Class: + if scp.parent != None and inspect.isclass(scp.parent): slice = 1 newscope.local('%s = %s' % (scp.params[0],scp.parent.name)) for p in scp.params[slice:]: From 8a727d5add1622c4f18713a4140720390342df44 Mon Sep 17 00:00:00 2001 From: Robert Meerman Date: Tue, 16 Aug 2011 15:36:59 +0100 Subject: [PATCH 4/7] Change: Parameter completion now has spaces between parameters Completed parameters are space and comma seperated, instead of just being comma seperated. Old behaviour:: myfunc(a,b,c) New behaviour:: myfunc(a, b, c) This better matches common practice, and the exampels in PEP 8 [1]_. If this upsets established users, a configuration variable could be created to control it. .. [1] http://www.python.org/dev/peps/pep-0008/ --- ftplugin/pythoncomplete.vim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ftplugin/pythoncomplete.vim b/ftplugin/pythoncomplete.vim index db4ced1..191f442 100644 --- a/ftplugin/pythoncomplete.vim +++ b/ftplugin/pythoncomplete.vim @@ -185,7 +185,7 @@ class Completer(object): items.append("...") if func_obj.func_code.co_flags & 0x8: items.append("***") - arg_text = (','.join(items)) + ')' + arg_text = (', '.join(items)) + ')' except: dbg("arg completion: %s: %s" % (sys.exc_info()[0],sys.exc_info()[1])) From c90856c1104a9d7e05bc58ee23d65602a28fe24d Mon Sep 17 00:00:00 2001 From: Robert Meerman Date: Tue, 16 Aug 2011 15:37:25 +0100 Subject: [PATCH 5/7] Trivial: Added trailing newline to end of source file, to keep git happy --- ftplugin/pythoncomplete.vim | 1 + 1 file changed, 1 insertion(+) diff --git a/ftplugin/pythoncomplete.vim b/ftplugin/pythoncomplete.vim index 191f442..716cd06 100644 --- a/ftplugin/pythoncomplete.vim +++ b/ftplugin/pythoncomplete.vim @@ -625,3 +625,4 @@ endfunction call s:DefPython() " vim: set et ts=4: + From 0d9ccb3188eb3a2089d5633d6cf7a1fe3aecfe83 Mon Sep 17 00:00:00 2001 From: Robert Meerman Date: Sat, 4 Feb 2012 22:01:01 +0000 Subject: [PATCH 6/7] Fix compatability with Vim (v7.3) ftplugin detection. This patch renames ``pythoncomplete.py`` to ``python_complete.py`` since the latter is automatically loaded by Vim (tested with v7.3). Using Vim's tracing feature (e.g. ``vim -Vtrace.log somefile.py``) I discovered that Vim does not automatically load ``$HOME/.vim/ftplugin/pythoncomplete.vim`` without additional configuration, it only considers the following:: Searching for ftplugin/python.vim ftplugin/python_*.vim ftplugin/python/*.vim in $HOME/.vim /var/lib/vim/addons /usr/share/vim/vimfiles /usr/share/vim/vim73 /usr/share/vim/vimfiles/after /var/lib/vim/addons/after $HOME/.vim/after Note that the default distribution of Vim v7.3 [1]_ includes `ftplugin/python.vim` which contains the following line:: setlocal omnifunc=pythoncomplete#Complete This conflicts with the changed introduced in this patch, and is no longer needed (since this script now sets 'omnifunc' itself). .. [1] At least, it does on Ubuntu v11.10's "vim-runtime" package, version "2:7.3.154+hg~74503f6ee649-2ubuntu3" --- ftplugin/{pythoncomplete.vim => python_complete.vim} | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) rename ftplugin/{pythoncomplete.vim => python_complete.vim} (98%) diff --git a/ftplugin/pythoncomplete.vim b/ftplugin/python_complete.vim similarity index 98% rename from ftplugin/pythoncomplete.vim rename to ftplugin/python_complete.vim index 716cd06..d08fab2 100644 --- a/ftplugin/pythoncomplete.vim +++ b/ftplugin/python_complete.vim @@ -39,14 +39,18 @@ " Yeah, I skipped a version number - 0.4 was never public. " It was a bugfix version on top of 0.3. This is a complete " rewrite. -" + +if exists("b:loaded_python_complete") | finish | endif +let b:loaded_python_complete = 1 if !has('python') echo "Error: Required vim compiled with +python" finish endif -function! pythoncomplete#Complete(findstart, base) +setlocal omnifunc=python_complete#Complete + +function! python_complete#Complete(findstart, base) "findstart = 1 when we need to get the text length if a:findstart == 1 let line = getline('.') @@ -82,7 +86,7 @@ function! pythoncomplete#Complete(findstart, base) endif endwhile execute "python vimcomplete('" . cword . "', '" . a:base . "')" - return g:pythoncomplete_completions + return g:python_complete_completions endif endfunction @@ -133,7 +137,7 @@ def vimcomplete(context,match): if dictstr[-1] == ',': dictstr = dictstr[:-1] dictstr += ']' #dbg("dict: %s" % dictstr) - vim.command("silent let g:pythoncomplete_completions = %s" % dictstr) + vim.command("silent let g:python_complete_completions = %s" % dictstr) #dbg("Completion dict:\n%s" % all) except vim.error: dbg("VIM Error: %s" % vim.error) From ee51a2436144384f06648af2a361904bc5352b99 Mon Sep 17 00:00:00 2001 From: Robert Meerman Date: Sat, 11 Feb 2012 15:27:24 +0000 Subject: [PATCH 7/7] Change installation direction from ftplugin/ to after/ftplugin/ Until the stock `ftplugin/python.vim` drops its definition for 'omnifunc' `python_complete.vim` must be loaded after system defaults to ensure it is actually used. Should this version of `python_complete.vim` become the new stock version, users should install future updates into `$HOME/.vim/ftplugin`, since a guard at the top of the script will preventing existing definitions being replaced. --- {ftplugin => after/ftplugin}/python_complete.vim | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {ftplugin => after/ftplugin}/python_complete.vim (100%) diff --git a/ftplugin/python_complete.vim b/after/ftplugin/python_complete.vim similarity index 100% rename from ftplugin/python_complete.vim rename to after/ftplugin/python_complete.vim