Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

added python code completion plugin

  • Loading branch information...
commit 97a9ca74b1c90c0b8e136b3ebfbf5d0797b1b62e 1 parent ea963d9
Adam Hitchcock authored
145 after/ftplugin/python_pydiction.vim
... ... @@ -0,0 +1,145 @@
  1 +" ============================================================================
  2 +" python_pydiction.vim - Module and Keyword completion for Python
  3 +" ============================================================================
  4 +"
  5 +" Author: Ryan Kulla (rkulla AT gmail DOT com)
  6 +" Version: 1.2, for Vim 7
  7 +" URL: http://www.vim.org/scripts/script.php?script_id=850
  8 +" Last Modified: July 22th, 2009
  9 +" Installation: On Linux, put this file in ~/.vim/after/ftplugin/
  10 +" On Windows, put this file in C:\vim\vimfiles\ftplugin\
  11 +" (assuming you installed vim in C:\vim\).
  12 +" You may install the other files anywhere.
  13 +" In .vimrc, add the following:
  14 +" filetype plugin on
  15 +" let g:pydiction_location = 'path/to/complete-dict'
  16 +" Optionally, you set the completion menu height like:
  17 +" let g:pydiction_menu_height = 20
  18 +" The default menu height is 15
  19 +" To do case-sensitive searches, set noignorecase (:set noic).
  20 +" Usage: Type part of a Python keyword, module name, attribute or method,
  21 +" then hit the TAB key and it will auto-complete (as long as it
  22 +" exists in the complete-dict file.
  23 +" You can also use Shift-Tab to Tab backwards.
  24 +" License: BSD
  25 +" Copyright: Copyright (c) 2003-2009 Ryan Kulla
  26 +" All rights reserved.
  27 +"
  28 +" Redistribution and use in source and binary forms, with or without
  29 +" modification, are permitted provided that the following conditions
  30 +" are met:
  31 +" 1. Redistributions of source code must retain the above copyright
  32 +" notice, this list of conditions and the following disclaimer.
  33 +" 2. Redistributions in binary form must reproduce the above
  34 +" copyright notice, this list of conditions and the following
  35 +" disclaimer in the documentation and/or other materials provided
  36 +" with the distribution.
  37 +" 3. The name of the author may not be used to endorse or promote
  38 +" products derived from this software without specific prior
  39 +" written permission.
  40 +"
  41 +" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
  42 +" OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  43 +" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  44 +" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  45 +" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  46 +" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  47 +" GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  48 +" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  49 +" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  50 +" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  51 +" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  52 +"
  53 +"
  54 +
  55 +if v:version < 700
  56 + echoerr "Pydiction requires vim version 7 or greater."
  57 + finish
  58 +endif
  59 +
  60 +
  61 +" Make the Tab key do python code completion:
  62 +inoremap <silent> <buffer> <Tab>
  63 + \<C-R>=<SID>SetVals()<CR>
  64 + \<C-R>=<SID>TabComplete('down')<CR>
  65 + \<C-R>=<SID>RestoreVals()<CR>
  66 +
  67 +" Make Shift+Tab do python code completion in the reverse direction:
  68 +inoremap <silent> <buffer> <S-Tab>
  69 + \<C-R>=<SID>SetVals()<CR>
  70 + \<C-R>=<SID>TabComplete('up')<CR>
  71 + \<C-R>=<SID>RestoreVals()<CR>
  72 +
  73 +
  74 +if !exists("*s:TabComplete")
  75 + function! s:TabComplete(direction)
  76 + " Check if the char before the char under the cursor is an
  77 + " underscore, letter, number, dot or opening parentheses.
  78 + " If it is, and if the popup menu is not visible, use
  79 + " I_CTRL-X_CTRL-K ('dictionary' only completion)--otherwise,
  80 + " use I_CTRL-N to scroll downward through the popup menu or
  81 + " use I_CTRL-P to scroll upward through the popup menu,
  82 + " depending on the value of a:direction.
  83 + " If the char is some other character, insert a normal Tab:
  84 + if searchpos('[_a-zA-Z0-9.(]\%#', 'nb') != [0, 0]
  85 + if !pumvisible()
  86 + return "\<C-X>\<C-K>"
  87 + else
  88 + if a:direction == 'down'
  89 + return "\<C-N>"
  90 + else
  91 + return "\<C-P>"
  92 + endif
  93 + endif
  94 + else
  95 + return "\<Tab>"
  96 + endif
  97 + endfunction
  98 +endif
  99 +
  100 +
  101 +if !exists("*s:SetVals")
  102 + function! s:SetVals()
  103 + " Save and change any config values we need.
  104 +
  105 + " Temporarily change isk to treat periods and opening
  106 + " parenthesis as part of a keyword -- so we can complete
  107 + " python modules and functions:
  108 + let s:pydiction_save_isk = &iskeyword
  109 + setlocal iskeyword +=.,(
  110 +
  111 + " Save any current dictionaries the user has set:
  112 + let s:pydiction_save_dictions = &dictionary
  113 + " Temporarily use only pydiction's dictionary:
  114 + let &dictionary = g:pydiction_location
  115 +
  116 + " Save the ins-completion options the user has set:
  117 + let s:pydiction_save_cot = &completeopt
  118 + " Have the completion menu show up for one or more matches:
  119 + let &completeopt = "menu,menuone"
  120 +
  121 + " Set the popup menu height:
  122 + let s:pydiction_save_pumheight = &pumheight
  123 + if !exists('g:pydiction_menu_height')
  124 + let g:pydiction_menu_height = 15
  125 + endif
  126 + let &pumheight = g:pydiction_menu_height
  127 +
  128 + return ''
  129 + endfunction
  130 +endif
  131 +
  132 +
  133 +if !exists("*s:RestoreVals")
  134 + function! s:RestoreVals()
  135 + " Restore the user's initial values.
  136 +
  137 + let &dictionary = s:pydiction_save_dictions
  138 + let &completeopt = s:pydiction_save_cot
  139 + let &pumheight = s:pydiction_save_pumheight
  140 + let &iskeyword = s:pydiction_save_isk
  141 +
  142 + return ''
  143 + endfunction
  144 +endif
  145 +
348 ftplugin/pydiction/README.txt
... ... @@ -0,0 +1,348 @@
  1 +Description
  2 +===========
  3 +Pydiction allows you to Tab-complete Python code in Vim, including keywords, the standard library, and third-party modules.
  4 +
  5 +It consists of three main files:
  6 +
  7 + python_pydiction.vim -- This is an ftplugin you put in your non-system ftplugin directory (i.e., ~/.vim/after/ftplugin/, on Unix or C:\vim\vimfiles\ftplugin\, on Windows)
  8 + complete-dict -- This is a vim dictionary file that consists of Python keywords and modules. This is what python_pydiction.vim looks at to know which things are completable.
  9 + pydiction.py -- (Not required) This is a Python script that was used to generate complete-dict. You can optionally run this script to add more modules to complete-dict.
  10 +
  11 +
  12 +Install Details
  13 +===============
  14 +Unix/Linux: Put python_pydiction.vim in ~/.vim/after/ftplugin/ (If this directory doesn't already exist, create it. Vim will know to look there automatically.)
  15 +Windows: Put python_pydiction.vim in C:\vim\vimfiles\ftplugin (Assuming you installed Vim to C:\vim\).
  16 +
  17 +You may install the other files (complete-dict and pydiction.py) anywhere you want. For this example, we'll assume you put them in "C:\vim\vimfiles\ftplugin\pydiction\" (Do not put any file but python_pydiction.vim in the ftplugin\ directory, only .vim files should go there.)
  18 +
  19 +In your vimrc file, first add the following line to enable filetype plugins:
  20 +
  21 + filetype plugin on
  22 +
  23 +then make sure you set "g:pydiction_location" to the full path of where you installed complete-dict, i.e.:
  24 +
  25 + let g:pydiction_location = 'C:/vim/vimfiles/ftplugin/pydiction/complete-dict'
  26 +
  27 +You can optionally set the height of the completion menu by setting "g:pydiction_menu_height" in your vimrc. For example:
  28 +
  29 + let g:pydiction_menu_height = 20
  30 +
  31 +The default menu height is 15.
  32 +
  33 +Note: If you were using a version of Pydiction less than 1.0, make sure you delete the old pydiction way of doing things from your vimrc. You should ***NOT*** have this in your vimrc anymore:
  34 +
  35 + if has("autocmd")
  36 + autocmd FileType python set complete+=k/path/to/pydiction iskeyword+=.,(
  37 + endif " has("autocmd")
  38 +
  39 +
  40 +Usage
  41 +=====
  42 +Type part of a Python keyword, module name, attribute or method in "insert mode" in Vim, then hit the TAB key and it will auto-complete.
  43 +
  44 +For example, typing:
  45 +
  46 + raw<Tab>
  47 +
  48 +will bring up a menu of possibilities, such as:
  49 +
  50 + raw_input(
  51 + raw_unicode_escape_decode(
  52 + raw_unicode_escape_encode(
  53 +
  54 +Typing:
  55 +
  56 + os.p<Tab>
  57 +
  58 +pops up:
  59 +
  60 + os.pardir
  61 + os.path
  62 + os.pathconf(
  63 + os.pathconf_names
  64 + os.pathsep
  65 + os.pipe(
  66 + ...
  67 +
  68 +Typing:
  69 +
  70 + co<Tab>
  71 +
  72 +pops up:
  73 +
  74 + continue
  75 + coerce(
  76 + compile(
  77 + ...
  78 +
  79 +and so on.
  80 +
  81 +As of Pydiction 1.2, there's support for completing modules that were imported via "from module import submodule". For example, you could do:
  82 +
  83 + from xml.parsers import expat
  84 + expat.P<Tab>
  85 +
  86 +which expands to:
  87 +
  88 + expat.ParserCreate(
  89 +
  90 +You can also now use Shift-Tab to Tab backwards through the popup menu.
  91 +
  92 +If you feel you're getting different results in your completion menu, it's probably because you don't have Vim set to ignore case. You can remedy this with ":set noic"
  93 +
  94 +
  95 +Pydiction versus other forms of completion
  96 +==========================================
  97 +Pydiction can complete Python Keywords, as well as Python module names and their attributes and methods. It can also complete both the fully-qualified module names such as "module.method", as well as non-fully qualified names such as simply "method".
  98 +
  99 +Pydiction only uses the "Tab" key to complete, uses a special dictionary file to complete from, and only attempts to complete while editing Python files. This has the advantages of only requiring one keystroke to do completion and of not polluting all of your completion menus that you may be using for other types of completion, such as Vim's regular omni-completion, or other completion scripts that you may be running.
  100 +
  101 +Since pydiction uses a dictionary file of possible completion items, it can complete 3rd party modules much more accurately than other ways. You have full control over what it can and cannot complete. If it's unable to complete anything you can either use pydiction.py, to automatically add a new module's contents to the dictionary, or you can manually add them using a text editor. The dictionary is just a plain text file, which also makes it portable across all platforms. For example, if you're a PyQT user, you can add all the PyQT related modules to the dictionary file (complete-dict) by using pydiction.py. The latest default complete-dict already contains most of the standard library, all Python 2.x keywords, Pygame, OpenGL, wxPython, Twisted, PyQT4, ZSI, LDAP, numarray, PyGTK, MySQLdb, PyGreSQL, pyPgSQL, PythonCard, pyvorbis, bcrypt, openid, GnuPGInterface, OpenSSl, pygments and more.
  102 +
  103 +Also, because pydiction uses a dictionary file, you don't have to import a module before you can complete it, nor do you even have to have the module installed on your machine. This makes completion very fast since it doesn't need to do any type deducing. It also frees you up to use pydiction as a way of looking up what a module or submodule without having to install it first.
  104 +
  105 +If you want to, you can still use Vim 7's built-in omni-completion for Python (pythoncomplete.vim), and other forms of ins-completion, with Pydiction. In fact, they can all make a great team.
  106 +
  107 +Pydiction knows when you're completing a callable method or not and, if you are, it will automatically insert an opening parentheses.
  108 +
  109 +The Tab key will work as normal for everything else. Pydiction will only try to use the Tab key to complete Python code if you're editing a Python file and you first type part of some Python module or keyword.
  110 +
  111 +Pydiction doesn't even require Python support to be compiled into your version of Vim.
  112 +
  113 +
  114 +python_pydiction.vim (filetype plugin)
  115 +======================================
  116 +Pydiction will make it so the Tab key on your keyboard is able to complete python code.
  117 +
  118 +Version 1.0 and greater of Pydiction uses a new file called python_pydiction.vim, which is an ftplugin that only activates when you're editing a python file (e.g., you're editing a file with a ".py" extension or you've manually typed ":set filetype=python"). Past versions of pydiction didn't use a plugin and instead just required you to change the value of "isk" in your vimrc, which was not desirable. Version 1.0 and greater do not require you to manually change the value of isk. It now safely changes isk for you temporarily by only setting it while you're doing Tab-completion of Python code, and it automatically changes it back to its original value whenever Tab-completion isn't being activated. Again, only Tab-completion causes pydiction to activate; not even other forms of ins-completion, such as <Ctrl-x> or <Ctrl-n> completion will activate pydiction, so you're still free to use those other types of completion whenever you want to.
  119 +
  120 +Pydiction works by using Vim's ins-completion functionality by temporarily remapping the Tab key to do the same thing as I_CTRL-X_CTRL_K (dictionary only completion). This means that whenever you're editing a Python file, and you start typing the name of a python keyword or module, you can press the Tab key to complete it. For example, if you type "os.pa" and then press Tab, Pydiction will pop up a completion menu in Vim that will look something like:
  121 +
  122 + os.pardir
  123 + os.path
  124 + os.pathconf(
  125 + os.pathconf_names
  126 + os.path.
  127 + os.path.__all__
  128 + os.path.__builtins__
  129 + os.path.__doc__
  130 + ...
  131 +
  132 +Pressing Tab again while the menu is open will scroll down the menu so you can choose whatever item you want to go with, using the popup-menu keys:
  133 +
  134 + CTRL-Y Accept the currently selected match and stop completion.
  135 + <Space> Accept the currently selected match and insert a space.
  136 + CTRL-E Close the menu and not accept any match.
  137 + ....
  138 +
  139 +hitting Enter will accept the currently selected match, stop completion, and insert a newline, which is usually not what you want. Use CTRL-Y or <Space>, instead. See ":help popupmenu-keys" for more options.
  140 +
  141 +As of Pydiction 1.3, you can press Shift-Tab to Tab backwards as well.
  142 +
  143 +Pydiction temporarily sets completeopt to "menu,menuone", so that you can complete items that have one or more matches. It will set it back to whatever the original value you have completeopt set to when Tab-completion isn't being activated.
  144 +
  145 +By default, Pydiction ignores case while doing Tab-completion. If you want it to do case-sensitive searches, then set noignorecase (:set noic).
  146 +
  147 +
  148 +pydiction.py
  149 +============
  150 +Note: You can skip this section if you don't plan to add more modules to complete-dict yourself. Check if complete-dict already has the modules you intend to use.
  151 +
  152 +This is the Python script used to create the "complete-dict" Vim dictionary file. I have created and bundled a default complete-dict for your use. I created it using Ubuntu 9.04 Linux, so there won't be any real win32 specific support in it. You're free to run pydiction.py to add, or upgrade, as modules as you want. The dictionary file will still work if you're using windows, but it won't complete win32 related modules unless you tell it to.
  153 +
  154 +Usage: In a command prompt, run:
  155 +
  156 + $ python pydiction.py <module> ... [-v]
  157 +
  158 +(You need to have python 2.x installed.)
  159 +
  160 +Say you wanted to add a module called "mymodule" to complete-dict, do the following:
  161 +
  162 + $ python pydiction.py mymodule
  163 +
  164 +You can input more than one module name on the command-line, just separate them by spaces:
  165 +
  166 + $ python pydiction.py mymodule1 mymodule2 mymodule3
  167 +
  168 +The -v option will just write the results to stdout (standard output) instead of the complete-dict file.
  169 +
  170 +If the backfup file "complete-dict.last" doesn't exist in the current directory, pydiction.py will create it for you. You should always keep a backup of your last working dictionary in case anything goes wrong, as it can get tedious having to recreate the file from scratch.
  171 +
  172 +If complete-dict.last already exists, pydiction will ask you if you want to overwrite your old backup with the new backup.
  173 +
  174 +If you try to add a module that already exists in complete-dict, pydiction will tell you it already exists, so don't worry about adding duplicates. In fact, you can't add duplicates, every time pydiction.py runs it looks for and removes any duplicates in the file.
  175 +
  176 +When pydiction adds new modules to complete-dict, it does so in two phases. First, it adds the fully-qualified name of the module. For example:
  177 +
  178 + module.attribute
  179 + module.method(
  180 +
  181 +then it adds the non-fully qualified name:
  182 +
  183 + attribute
  184 + method(
  185 +
  186 +this allows you to complete your python code in the way that you imported it. E.g.:
  187 +
  188 + import module
  189 +
  190 +or:
  191 +
  192 + from module import method
  193 +
  194 +Say you want to complete "pygame.display.set_mode". If you imported Pygame using "import pygame", then you can Tab-complete using:
  195 +
  196 + pygame.di<Tab>
  197 +
  198 +to expand to "pygame.display.". Then type:
  199 +
  200 + se<Tab>
  201 +
  202 +to expand to "pygame.display.set_mode("
  203 +
  204 +Now say you imported using "from pygame import display". To expand to "display.set_mode(" just type:
  205 +
  206 + display.se<Tab>
  207 +
  208 +And if you imported using "from pygame.display import set_mode" just type:
  209 +
  210 + se<Tab>
  211 +
  212 +Keep in mind that if you don't use fully-qualified module names then you might get a lot of possible menu options popping up, so you may want to use more than just two letters before you hit Tab, to try to narrow down the list.
  213 +
  214 +As of Pydictoin 1.1, there is also limited support for string type method completion. For example:
  215 +
  216 + "".jo<Tab>"
  217 +
  218 +will expand to:
  219 +
  220 + "".join(
  221 +
  222 +make sure you type at least two letters of the method name if this doesn't seem to work.
  223 +
  224 +This only works for quoted strings, ie:
  225 +
  226 + 'foo bar'.st<Tab>
  227 +
  228 +to get
  229 +
  230 + 'foo bar'.startswith(
  231 +
  232 +but you can't yet do:
  233 +
  234 + s = 'foo bar'
  235 +
  236 + s.st<Tab>
  237 +
  238 +if you want that behavior you can still use Vim 7's omni-completion:
  239 +
  240 + s.st<Ctrl-x><Ctrl-o>
  241 +
  242 +which will also give you a preview window describing the methods as well as the argument list the methods take, e,g:
  243 +
  244 + startswith(prefix[, start[, end]])
  245 + strip([chars])
  246 +
  247 +To Tab-complete your own personal modules, you put your functions in a separate file to be reused, as you normally would. For example, say you put the following function in a file called "myFoo.py":
  248 +
  249 + def myBar():
  250 + print "hi"
  251 +
  252 +you would then need to add myFoo to complete-dict by doing:
  253 +
  254 + ./pydiction.py myFoo
  255 +
  256 +now you can complete myFoo.myBar() by doing:
  257 +
  258 + myFoo.my<Tab>
  259 +
  260 +You don't have to restart Vim after you update complete-dict.
  261 +
  262 +
  263 +complete-dict
  264 +=============
  265 +This is the Vim dictionary file that python_pydiction.vim reads from and pydiction.py writes to. Without this file, pydiction wouldn't know which Python keywords and modules it can Tab-complete.
  266 +
  267 +complete-dict is only an optional file in the sense that you can create your own complete-dict if you don't want to use the default one that is bundled with Pydiction. The default complete-dict gives you a major head start, as far as what you can Tab-complete, because I did my best to put all of the Python keywords, standard library and even some popular third party modules in it for you.
  268 +
  269 +The default complete-dict currently contains:
  270 +
  271 + Python keywords:
  272 +
  273 + and, del, for, is, raise, assert, elif, from, lambda, return, break, else, global, not, try, class, except, if, or, while, continue, exec, import, pass, yield, def, finally, in, print
  274 +
  275 + Most of the standard library and built ins:
  276 +
  277 + __builtin__, __future__, os, sys, time, re, sets, string, math, Tkinter, hashlib, urllib, pydoc, etc...
  278 +
  279 + It also contains some popular third-party libraries:
  280 +
  281 + Pygame, wxPython, Twisted, ZSI, LDAP, OpenGL, PyGTK, PyQT4, MySQLdb, PyGreSQL, pyPgSQL, SQLite, PythonCard, Numarray, pyvorbis, Bcrypt, OpenID, GnuPGInterface, OpenSSL and Pygments.
  282 +
  283 + Make sure you download the latest version of Pydiction to get the most up-to-date version of complete-dict. New modules are usually added to it every release.
  284 +
  285 +If you open complete-dict in your text editor you'll see sections in it for each module, such as:
  286 +
  287 + --- import os ---
  288 + os.EX_CANTCREAT
  289 + os.EX_CONFIG
  290 + os.EX_DATAERR
  291 + ...
  292 +
  293 + --- from os import * ---
  294 + EX_CANTCREAT
  295 + EX_CONFIG
  296 + EX_DATAERR
  297 + ...
  298 +
  299 +If certain attributes seem to be missing, it's probably because pydiction removed them because they were duplicates. This mainly happens with the non-fully qualified module sections. So first try searching the entire file for whatever string you assume is missing before you try adding it. For example, if you don't see:
  300 +
  301 + __doc__
  302 +
  303 +under:
  304 +
  305 + --- import sys ---
  306 +
  307 +it's probably because a previous module, such as "os", already has it.
  308 +
  309 +If you try to recreate complete-dict from scratch, you'll need to manually add the Python keywords back to it, as those aren't generated with pydiction.py.
  310 +
  311 +If you don't want certain things to Tab-complete, such as Python keywords or certain modules, simply delete them by hand from complete-dict.
  312 +
  313 +Pydiction doesn't ignore "private" attributes or methods. I.e., those starting (but not ending) with one or two underscores, e.g., "_foo" or "__foo". I have manually deleted things starting with a single underscore from the included complete-dict just to keep it a little more sane--since there were so many. In sticking with the Python tradition of not forcing things to be private, I have left it up to the user to decide how they want to treat their own things. If you want to delete them from your custom complete-dict's, you can use a regex to try to delete them, such as doing:
  314 +
  315 + :g/\._[a-zA-Z]/d
  316 + :g/^_[a-zA-Z]/d
  317 + :g/^\%(_\=[^_]\)*\zs__\%(.\{-}__\)\@!/d
  318 + etc...
  319 +
  320 +
  321 +Tips
  322 +====
  323 +-Say you create a custom object, called "S" by doing something like:
  324 +
  325 + S = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  326 +
  327 +you can complete dynamic object methods, such as "S.send()", by using Vim 7's omni-completion ftplugin (a.k.a "pythoncomplete.vim") by doing:
  328 +
  329 + S.s<Ctrl-x><Ctrl-o>
  330 +
  331 +-You may get unexpected results if you use autocomplpop.vim, supertab.vim or other completion or python plugins. Try disabling them individually to find out the culprit and please don't hesitate to e-mail me any workarounds or suggestions. Thanks.
  332 +
  333 +
  334 +License
  335 +=======
  336 +As of version 1.0, Pydiction is now under a BSD license instead of GPL.
  337 +
  338 +
  339 +Further reading
  340 +===============
  341 +:help ftplugin
  342 +:help 'complete
  343 +:help compl-dictionary
  344 +:help popupmenu-completion
  345 +:help popupmenu-keys
  346 +:help iskeyword
  347 +http://docs.python.org/modindex.html
  348 +
93,721 ftplugin/pydiction/complete-dict
93,721 additions, 0 deletions not shown
284 ftplugin/pydiction/pydiction.py
... ... @@ -0,0 +1,284 @@
  1 +#!/usr/bin/env python
  2 +# Last modified: July 23rd, 2009
  3 +"""
  4 +
  5 +pydiction.py 1.2 by Ryan Kulla (rkulla AT gmail DOT com).
  6 +
  7 +Description: Creates a Vim dictionary of Python module attributes for Vim's
  8 + completion feature. The created dictionary file is used by
  9 + the Vim ftplugin "python_pydiction.vim".
  10 +
  11 +Usage: pydiction.py <module> ... [-v]
  12 +Example: The following will append all the "time" and "math" modules'
  13 + attributes to a file, in the current directory, called "pydiction"
  14 + with and without the "time." and "math." prefix:
  15 + $ python pydiction.py time math
  16 + To print the output just to stdout, instead of appending to the file,
  17 + supply the -v option:
  18 + $ python pydiction.py -v time math
  19 +
  20 +License: BSD.
  21 +"""
  22 +
  23 +
  24 +__author__ = "Ryan Kulla (rkulla AT gmail DOT com)"
  25 +__version__ = "1.2"
  26 +__copyright__ = "Copyright (c) 2003-2009 Ryan Kulla"
  27 +
  28 +
  29 +import os
  30 +import sys
  31 +import types
  32 +import shutil
  33 +
  34 +
  35 +# Path/filename of the vim dictionary file to write to:
  36 +PYDICTION_DICT = r'complete-dict'
  37 +# Path/filename of the vim dictionary backup file:
  38 +PYDICTION_DICT_BACKUP = r'complete-dict.last'
  39 +
  40 +# Sentintal to test if we should only output to stdout:
  41 +STDOUT_ONLY = False
  42 +
  43 +
  44 +def get_submodules(module_name, submodules):
  45 + """Build a list of all the submodules of modules."""
  46 +
  47 + # Try to import a given module, so we can dir() it:
  48 + try:
  49 + imported_module = my_import(module_name)
  50 + except ImportError, err:
  51 + return submodules
  52 +
  53 + mod_attrs = dir(imported_module)
  54 +
  55 + for mod_attr in mod_attrs:
  56 + if type(getattr(imported_module, mod_attr)) is types.ModuleType:
  57 + submodules.append(module_name + '.' + mod_attr)
  58 +
  59 + return submodules
  60 +
  61 +
  62 +def write_dictionary(module_name):
  63 + """Write to module attributes to the vim dictionary file."""
  64 + prefix_on = '%s.%s'
  65 + prefix_on_callable = '%s.%s('
  66 + prefix_off = '%s'
  67 + prefix_off_callable = '%s('
  68 +
  69 + try:
  70 + imported_module = my_import(module_name)
  71 + except ImportError, err:
  72 + return
  73 +
  74 + mod_attrs = dir(imported_module)
  75 +
  76 + # Generate fully-qualified module names:
  77 + write_to.write('\n--- import %s ---\n' % module_name)
  78 + for mod_attr in mod_attrs:
  79 + if callable(getattr(imported_module, mod_attr)):
  80 + # If an attribute is callable, show an opening parentheses:
  81 + format = prefix_on_callable
  82 + else:
  83 + format = prefix_on
  84 + write_to.write(format % (module_name, mod_attr) + '\n')
  85 +
  86 + # Generate submodule names by themselves, for when someone does
  87 + # "from foo import bar" and wants to complete bar.baz.
  88 + # This works the same no matter how many .'s are in the module.
  89 + if module_name.count('.'):
  90 + # Get the "from" part of the module. E.g., 'xml.parsers'
  91 + # if the module name was 'xml.parsers.expat':
  92 + first_part = module_name[:module_name.rfind('.')]
  93 + # Get the "import" part of the module. E.g., 'expat'
  94 + # if the module name was 'xml.parsers.expat'
  95 + second_part = module_name[module_name.rfind('.') + 1:]
  96 + write_to.write('\n--- from %s import %s ---\n' %
  97 + (first_part, second_part))
  98 + for mod_attr in mod_attrs:
  99 + if callable(getattr(imported_module, mod_attr)):
  100 + format = prefix_on_callable
  101 + else:
  102 + format = prefix_on
  103 + write_to.write(format % (second_part, mod_attr) + '\n')
  104 +
  105 + # Generate non-fully-qualified module names:
  106 + write_to.write('\n--- from %s import * ---\n' % module_name)
  107 + for mod_attr in mod_attrs:
  108 + if callable(getattr(imported_module, mod_attr)):
  109 + format = prefix_off_callable
  110 + else:
  111 + format = prefix_off
  112 + write_to.write(format % mod_attr + '\n')
  113 +
  114 +
  115 +def my_import(name):
  116 + """Make __import__ import "package.module" formatted names."""
  117 + mod = __import__(name)
  118 + components = name.split('.')
  119 + for comp in components[1:]:
  120 + mod = getattr(mod, comp)
  121 + return mod
  122 +
  123 +
  124 +def remove_duplicates(seq, keep=()):
  125 + """
  126 +
  127 + Remove duplicates from a sequence while perserving order.
  128 +
  129 + The optional tuple argument "keep" can be given to specificy
  130 + each string you don't want to be removed as a duplicate.
  131 + """
  132 + seq2 = []
  133 + seen = set();
  134 + for i in seq:
  135 + if i in (keep):
  136 + seq2.append(i)
  137 + continue
  138 + elif i not in seen:
  139 + seq2.append(i)
  140 + seen.add(i)
  141 + return seq2
  142 +
  143 +
  144 +def get_yesno(msg="[Y/n]?"):
  145 + """
  146 +
  147 + Returns True if user inputs 'n', 'Y', "yes", "Yes"...
  148 + Returns False if user inputs 'n', 'N', "no", "No"...
  149 + If they enter an invalid option it tells them so and asks again.
  150 + Hitting Enter is equivalent to answering Yes.
  151 + Takes an optional message to display, defaults to "[Y/n]?".
  152 +
  153 + """
  154 + while True:
  155 + answer = raw_input(msg)
  156 + if answer == '':
  157 + return True
  158 + elif len(answer):
  159 + answer = answer.lower()[0]
  160 + if answer == 'y':
  161 + return True
  162 + break
  163 + elif answer == 'n':
  164 + return False
  165 + break
  166 + else:
  167 + print "Invalid option. Please try again."
  168 + continue
  169 +
  170 +
  171 +def main(write_to):
  172 + """Generate a dictionary for Vim of python module attributes."""
  173 + submodules = []
  174 +
  175 + for module_name in sys.argv[1:]:
  176 + try:
  177 + imported_module = my_import(module_name)
  178 + except ImportError, err:
  179 + print "Couldn't import: %s. %s" % (module_name, err)
  180 + sys.argv.remove(module_name)
  181 +
  182 + cli_modules = sys.argv[1:]
  183 +
  184 + # Step through each command line argument:
  185 + for module_name in cli_modules:
  186 + print "Trying module: %s" % module_name
  187 + submodules = get_submodules(module_name, submodules)
  188 +
  189 + # Step through the current module's submodules:
  190 + for submodule_name in submodules:
  191 + submodules = get_submodules(submodule_name, submodules)
  192 +
  193 + # Add the top-level modules to the list too:
  194 + for module_name in cli_modules:
  195 + submodules.append(module_name)
  196 +
  197 + submodules.sort()
  198 +
  199 + # Step through all of the modules and submodules to create the dict file:
  200 + for submodule_name in submodules:
  201 + write_dictionary(submodule_name)
  202 +
  203 + if STDOUT_ONLY:
  204 + return
  205 +
  206 + # Close and Reopen the file for reading and remove all duplicate lines:
  207 + write_to.close()
  208 + print "Removing duplicates..."
  209 + f = open(PYDICTION_DICT, 'r')
  210 + file_lines = f.readlines()
  211 + file_lines = remove_duplicates(file_lines, ('\n'))
  212 + f.close()
  213 +
  214 + # Delete the original file:
  215 + os.unlink(PYDICTION_DICT)
  216 +
  217 + # Recreate the file, this time it won't have any duplicates lines:
  218 + f = open(PYDICTION_DICT, 'w')
  219 + for attr in file_lines:
  220 + f.write(attr)
  221 + f.close()
  222 + print "Done."
  223 +
  224 +
  225 +if __name__ == '__main__':
  226 + """Process the command line."""
  227 +
  228 + if sys.version_info[0:2] < (2, 3):
  229 + sys.exit("You need a Python 2.x version of at least Python 2.3")
  230 +
  231 + if len(sys.argv) <= 1:
  232 + sys.exit("%s requires at least one argument. None given." %
  233 + sys.argv[0])
  234 +
  235 + if '-v' in sys.argv:
  236 + write_to = sys.stdout
  237 + sys.argv.remove('-v')
  238 + STDOUT_ONLY = True
  239 + elif os.path.exists(PYDICTION_DICT):
  240 + # See if any of the given modules have already been pydiction'd:
  241 + f = open(PYDICTION_DICT, 'r')
  242 + file_lines = f.readlines()
  243 + for module_name in sys.argv[1:]:
  244 + for line in file_lines:
  245 + if line.find('--- import %s ' % module_name) != -1:
  246 + print '"%s" already exists in %s. Skipping...' % \
  247 + (module_name, PYDICTION_DICT)
  248 + sys.argv.remove(module_name)
  249 + break
  250 + f.close()
  251 +
  252 + if len(sys.argv) < 2:
  253 + # Check if there's still enough command-line arguments:
  254 + sys.exit("Nothing new to do. Aborting.")
  255 +
  256 + if os.path.exists(PYDICTION_DICT_BACKUP):
  257 + answer = get_yesno('Overwrite existing backup "%s" [Y/n]? ' % \
  258 + PYDICTION_DICT_BACKUP)
  259 + if (answer):
  260 + print "Backing up old dictionary to: %s" % \
  261 + PYDICTION_DICT_BACKUP
  262 + try:
  263 + shutil.copyfile(PYDICTION_DICT, PYDICTION_DICT_BACKUP)
  264 + except IOError, err:
  265 + print "Couldn't back up %s. %s" % (PYDICTION_DICT, err)
  266 + else:
  267 + print "Skipping backup..."
  268 +
  269 + print 'Appending to: "%s"' % PYDICTION_DICT
  270 + else:
  271 + print "Backing up current %s to %s" % \
  272 + (PYDICTION_DICT, PYDICTION_DICT_BACKUP)
  273 + try:
  274 + shutil.copyfile(PYDICTION_DICT, PYDICTION_DICT_BACKUP)
  275 + except IOError, err:
  276 + print "Couldn't back up %s. %s" % (PYDICTION_DICT, err)
  277 + else:
  278 + print 'Creating file: "%s"' % PYDICTION_DICT
  279 +
  280 +
  281 + if not STDOUT_ONLY:
  282 + write_to = open(PYDICTION_DICT, 'a')
  283 +
  284 + main(write_to)
86 snippets/python.snippets
... ... @@ -0,0 +1,86 @@
  1 +snippet #!
  2 + #!/usr/bin/env python
  3 +
  4 +snippet imp
  5 + import ${1:module}
  6 +# Module Docstring
  7 +snippet docs
  8 + '''
  9 + File: ${1:`Filename('$1.py', 'foo.py')`}
  10 + Author: ${2:`g:snips_author`}
  11 + Description: ${3}
  12 + '''
  13 +snippet while
  14 + while ${1:condition}:
  15 + ${2:# code...}
  16 +snippet for
  17 + for ${1:needle} in ${2:haystack}:
  18 + ${3:# code...}
  19 +# New Class
  20 +snippet class
  21 + class ${1:ClassName}(${2:object}):
  22 + """${3:docstring for $1}"""
  23 + def __init__(self, ${4:arg}):
  24 + ${5:super($1, self).__init__()}
  25 + self.$4 = $4
  26 + ${6}
  27 +# New Function
  28 +snippet def
  29 + def ${1:fname}(${2:`indent('.') ? 'self' : ''`}):
  30 + """${3:docstring for $1}"""
  31 + ${4:pass}
  32 +snippet deff
  33 + def ${1:fname}(${2:`indent('.') ? 'self' : ''`}):
  34 + ${3}
  35 +# New Method
  36 +snippet defs
  37 + def ${1:mname}(self, ${2:arg}):
  38 + ${3:pass}
  39 +# New Property
  40 +snippet property
  41 + def ${1:foo}():
  42 + doc = "${2:The $1 property.}"
  43 + def fget(self):
  44 + ${3:return self._$1}
  45 + def fset(self, value):
  46 + ${4:self._$1 = value}
  47 +# Lambda
  48 +snippet lambda
  49 + ${1:var} = lambda ${2:vars} : ${3:action}
  50 +snippet try Try/Except
  51 + try:
  52 + ${1:pass}
  53 + except ${2:Exception}, ${3:e}:
  54 + ${4:raise $3}
  55 +snippet try Try/Except/Else
  56 + try:
  57 + ${1:pass}
  58 + except ${2:Exception}, ${3:e}:
  59 + ${4:raise $3}
  60 + else:
  61 + ${5:pass}
  62 +snippet try Try/Except/Finally
  63 + try:
  64 + ${1:pass}
  65 + except ${2:Exception}, ${3:e}:
  66 + ${4:raise $3}
  67 + finally:
  68 + ${5:pass}
  69 +snippet try Try/Except/Else/Finally
  70 + try:
  71 + ${1:pass}
  72 + except ${2:Exception}, ${3:e}:
  73 + ${4:raise $3}
  74 + else:
  75 + ${5:pass}
  76 + finally:
  77 + ${6:pass}
  78 +# if __name__ == '__main__':
  79 +snippet ifmain
  80 + if __name__ == '__main__':
  81 + ${1:main()}
  82 +# __magic__
  83 +snippet _
  84 + __${1:init}__${2}
  85 +
  86 +

0 comments on commit 97a9ca7

Please sign in to comment.
Something went wrong with that request. Please try again.