Using Vim with Django
This page is intended to be used as a collection of hints for using the Vim editor with Django.
TOC(inline, UsingVimWithDjango)
Tips
Vim Modeline
To ensure that all developers are using a standard tab format (as long as they are using Vim), you can add a Vim modeline (special comment) to your files, to set people in the same mode for that file. Example:
# vim: ai ts=4 sts=4 et sw=4
Tab Setting Reference for Python and Vim
It is also highly recommended to configure shiftwidth, tabstop and softtabstop for Vim, add the following lines into your .vimrc:
autocmd FileType python set sw=4 autocmd FileType python set ts=4 autocmd FileType python set sts=4
Plugins
YouCompleteMe
YouCompleteMe is a fast, as-you-type, fuzzy-search code completion engine for Vim, it provide a Jedi-based completion engine for Python.
Lines below are recommended settings for YCM:
let g:ycm_collect_identifiers_from_tags_files = 1 " Let YCM read tags from Ctags file let g:ycm_use_ultisnips_completer = 1 " Default 1, just ensure let g:ycm_seed_identifiers_with_syntax = 1 " Completion for programming language's keyword let g:ycm_complete_in_comments = 1 " Completion in comments let g:ycm_complete_in_strings = 1 " Completion in string
Ultisnips.vim
UltiSnips is the ultimate solution for snippets in Vim, it is written in python and works perfectly with YouCompleteMe.
Lines below are recommended settings for Ultisnips to be working with YouCompleteMe:
let g:UltiSnipsExpandTrigger = "<c-j>" let g:UltiSnipsJumpForwardTrigger = "<c-j>" let g:UltiSnipsJumpBackwardTrigger = "<c-p>" let g:UltiSnipsListSnippets = "<c-k>" "List possible snippets based on current file
There is large library of hand-crafted snippets for Django in vim-snippets (see more) that work perfectly with UltiSnips
Please note that the way UltiSnips
loads snippets will depend on current filetype. This can be set for Django with :setfiletype python.django
or if further automation is needed good choice would be django-plus plugin that detects django projects and sets correct filetype (htmldjango/django)
XMLEdit.vim
The xmledit.vim plugin is really useful for editing XML and HTML files. It makes tag completion easy and allows you to bounce between start and end tags.
Syntax for templates
Dave Hodder has contributed standard Vim syntax files.
If you are interested in rolling your own, this is a simple addition to let Vim deal with Django template syntax:
Create the file:
$VIM/vimfiles/after/syntax/html.vim
with the following content:
syn region djangotagmarkers start="{{" end="}}" syn region djangovariablemarkers start="{%" end="%}" command! -nargs=+ HiLink hi def link <args> HiLink djangotagmarkers PreProc HiLink djangovariablemarkers PreProc delcommand HiLink
Vim 7.1 or newer includes support for "htmldjango" documents out of the box. With filetype on
on your ~/.vimrc
configuration file, vim will automatically tell apart "htmldjango" documents from regular html ones. Just make sure that at least one of the first 10 lines in your html document matches the following regex from the start:
{%\s*\(extends\|block\|load\)\>\|{#\s\+
If you are not familiar with regexes, these are the possible options:
{% extends {% block {% load {#
Project.vim
The Project plugin adds IDE file organisation functionality to Vim.
Something like the following could be used to view a project's files. It looks scary but is definitely worth trying.
Django Project=/path/to/project CD=. filter="[^_]*.py" { settings.py urls.py apps=apps { Polls=polls { views.py models.py } ToDo=todo { views.py models.py } media=mediaDir { images=imagesDir { } } }
Such a structure can also be created by using the built-in '\C' command which will recurse through the whole directory tree.
Tag List
The taglist plugin is probably similar to Project but can also look inside Python files to display classes and functions. (It requires the ctags program installed on your system, which probably comes with most Linuxes and is easily installed via MacPorts (or fink as "exuberant-ctags") on OS X.)
Additionally, I created a shell-function, inspired by Jeremy Jones, to create a new taglist-list when you pass it the path to a Django project directory:
djvim() { gvim "+cd $1" "+TlistAddFilesRecursive . [^_]*py\|*html\|*css" +TlistOpen }
Pyflakes
Deprecated and it will be replaced by Syntastic. The must-have features of pyflakes-vim have been merged into Syntastic, which has a plugin-based syntax checking backend. This means you can check many different languages on the fly. I recommend using Syntastic unless you're mostly just editing Python.
The pyflakes plugin highlights common Python errors like misspelling a variable name on the fly. It also warns about unused imports, redefined functions, etc.
This plugin is fast enough that it registers itself with vim hooks for leaving insert mode and saving a buffer, so that the warnings are always up to date.
Syntastic
Syntastic is a syntax checking plugin that runs files through external syntax checkers and displays any resulting errors to the user. This can be done on demand, or automatically as files are saved. If syntax errors are detected, the user is notified and is happy because they didn't have to compile their code or execute their script to find them.
Mappings
I have this in my vimrc to make file jumps between relative django files easier.
let g:last_relative_dir = '' nnoremap \1 :call RelatedFile ("models.py")<cr> nnoremap \2 :call RelatedFile ("views.py")<cr> nnoremap \3 :call RelatedFile ("urls.py")<cr> nnoremap \4 :call RelatedFile ("admin.py")<cr> nnoremap \5 :call RelatedFile ("tests.py")<cr> nnoremap \6 :call RelatedFile ( "templates/" )<cr> nnoremap \7 :call RelatedFile ( "templatetags/" )<cr> nnoremap \8 :call RelatedFile ( "management/" )<cr> nnoremap \0 :e settings.py<cr> nnoremap \9 :e urls.py<cr> fun! RelatedFile(file) #This is to check that the directory looks djangoish if filereadable(expand("%:h"). '/models.py') || isdirectory(expand("%:h") . "/templatetags/") exec "edit %:h/" . a:file let g:last_relative_dir = expand("%:h") . '/' return '' endif if g:last_relative_dir != '' exec "edit " . g:last_relative_dir . a:file return '' endif echo "Cant determine where relative file is : " . a:file return '' endfun fun SetAppDir() if filereadable(expand("%:h"). '/models.py') || isdirectory(expand("%:h") . "/templatetags/") let g:last_relative_dir = expand("%:h") . '/' return '' endif endfun autocmd BufEnter *.py call SetAppDir()
Surround Mappings
These are additional surroundings for the surround plugin:
let b:surround_{char2nr("v")} = "{{ \r }}" let b:surround_{char2nr("{")} = "{{ \r }}" let b:surround_{char2nr("%")} = "{% \r %}" let b:surround_{char2nr("b")} = "{% block \1block name: \1 %}\r{% endblock \1\1 %}" let b:surround_{char2nr("i")} = "{% if \1condition: \1 %}\r{% endif %}" let b:surround_{char2nr("w")} = "{% with \1with: \1 %}\r{% endwith %}" let b:surround_{char2nr("f")} = "{% for \1for loop: \1 %}\r{% endfor %}" let b:surround_{char2nr("c")} = "{% comment %}\r{% endcomment %}"
Put the above in ~/.vim/ftplugin/htmldjango.vim. Examples in visual mode (select some text first):
- type 'Sv' or 'S{' for a variable
- type 'Sb' for a block
- type 'Si' for an if statement
- type 'Sw' for a with statement
- type 'Sc' for a comment
- type 'Sf' for a for statement
- type 'S%' for other template tags
Pony.vim
Pony.vim is a plugin for working with Django projects. Basic go-to-file commands are available for common Django files, with tab-completion for app names :
- :Dadmin [app] -> [app]/admin.py
- :Dmodels [app] -> [app]/models.py
- :Dsettings [app] -> [app]/settings.py
- :Dtests [app] -> [app]/tests.py
- :Durls [app] -> [app]/urls.py
- Dviews [app] -> [app]/views.py
The manage.py script is wrapped with completion and a few shortcuts :
- :Dmanage -> manage.py
- :Drunserver -> manage.py runserver
- :Dsyncdb -> manage.py syncdb
- :Dshell -> manage.py shell
- :Ddbshell -> manage.py dbshell
Visit the repository on GitHub for more information.
Eclipse
A combination of Eclipse + Aptana studio plugin (Django code completion, auto-import and much more) + vrapper plugin (vim emulation) or viplugin if you prefer, is a decent solution if you want a full-blown IDE with code completion and quick access to django specific commands such as syncdb, starting an interactive django shell, etc. Alternatively you could try Aptana studio standalone, with a vim plugin, however I experienced issues with vrapper in Aptana standalone, that I didn't have with the Aptana plugin.
Suggestions
Django Project Manager: By panosl
The idea is to create a plugin, that will wrap the functionality of django-admin/manage.py along with project.vim.
This will one to create a new django project from within vim, and generating a Project file with all the files pre-specified. This could be extended to allow, the creation of apps within the project, leveraging the usage of manage.py.
So a regular session would be:
:djsp [projectname] # This will in turn generate the required Project file with all the files of the project.
:djsa [appname] # This will create a new app, and update the Project file with the new data regarding the application.
At this point, this is enough, even though we could still wrap a bit more of django-admin/manage, by allowing inner commands to launch/stop the test server and similar additions.
In my opinion this would help with django development and help focus more on the development that usually happens within the editor, which in our case, is ofcourse (G)Vim.
Comments
These are some notes for anyone considering writing this plugin.
- Vim has the 'read' command which can read the output from a command into a buffer using the pling operator. E.g. :read !dir will read a directory listing into the current buffer.
- Vim has special buffers for storing different types of output. See :help special-buffers and :help cwindow
- The Project plugin has the function CreateEntriesFromDir() which can be used to create new entries. Passing '1' as the arguement will create a recursive entry which would be most appropriate for creating Django entries.
- The Project plugin allows users to use a different project file from the default. It could be that the new plugin generates a project specific file when a new django project is created.
The following code can used to create Project entries in a buffer. Note that various settings will be altered by the call to DoSetup so it's probably best to use a new buffer.
function! GetProjectSNR() if exists(":Project") let a_sav = @a redir @a exec "silent function" redir END let funclist = @a let @a = a_sav let func = split(split(matchstr(funclist,'.SNR.\{-}GenerateEntry'),'\n')[-1])[1] return matchlist(func, '\(.*\)G')[1] endif endfunction function! Test() let SNR = GetProjectSNR() call {SNR}DoSetup() call {SNR}DoEntryFromDir(0, line("."), 'test', 'c:\temp', 'c:\temp', '', '', '*', 0, 0) return '' endfunction
Grabbing the SNR isn't pretty but seems to work and prevents having to recreate the work done in Project.
It would be useful for the plugin to grab any tracebacks and place the cursor in a suitable spot.
Attachments (5)
-
python.vim
(572 bytes
) - added by 19 years ago.
Sample ftplugin file containing SnippetsEmu abbreviations for Django models
-
django.tar.gz
(4.6 KB
) - added by 19 years ago.
Unzip this file in your ~/.vim/ directory to install snippetsEmu.vim and Django specific abbreviations
-
django-vim-taglist.png
(56.7 KB
) - added by 18 years ago.
screenshot of vim with the taglist plugin
-
django_url_snippets.vim
(544 bytes
) - added by 16 years ago.
SnippetsEmu for urls.py
-
django_view_snippets.vim
(310 bytes
) - added by 16 years ago.
SnippetsEmu for views.py
Download all attachments as: .zip