1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-04-14 15:19:12 +08:00

feat(layer): add framework#django layer

This commit is contained in:
Wang Shidong 2022-05-07 08:03:49 +08:00 committed by GitHub
parent 0fe1d4b9de
commit 8277b6789f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 1465 additions and 119 deletions

View File

@ -0,0 +1,24 @@
"=============================================================================
" django.vim --- django project support in SpaceVim
" Copyright (c) 2016-2019 Wang Shidong & Contributors
" Author: Wang Shidong < wsdjeg@outlook.com >
" URL: https://spacevim.org
" License: GPLv3
"=============================================================================
""
" @section framework#django, layers-framework-django
" @parentsection layers
" The `framework#django` layer provides code completion and syntax highlight for django.
" This layer is not enabled by default, to enable it:
" >
" [[layers]]
" name = 'framework#django'
" <
"
function! SpaceVim#layers#framework#django#plugins() abort
let plugins = []
call add(plugins, [g:_spacevim_root_dir . 'bundle/django-plus.vim', {'merged' : 0}])
return plugins
endfunction

View File

@ -0,0 +1,20 @@
The MIT License
Copyright (c) 2016 Tommy Allen
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,79 @@
<p align="center"><img align="center" alt="django-plus.vim" src="doc/django-plus.png?raw=true"></p>
---
Improvements to the handling of Django related files in Vim, some of which are
based on Steve Losh's `htmldjango` scripts.
## Why?
Django support in Vim sucks.
| What Sucks? | Sucks? |
|:-----------------------------------------------------------------|:-------:|
| Hard-coded `htmldjango` filetype for any `.html` file | **Yes** |
| HTML indentation | **Yes** |
| `QuerySet` completions | **Yes** |
| `settings.py` variable completions | **Yes** |
| Template tag and filter completions | **Yes** |
| Template file completion for `{% include %}` and `{% extends %}` | **Yes** |
| Template file completion for rendering functions | **Yes** |
To help you understand the difference this plugin makes, I used science:
![science](doc/science.png?raw=true)
As you can see, one line goes up. However, the other line doesn't go up that
much. It doesn't get any clearer than that.
## Improvements
A summary of improvements to Django development in Vim.
### General
* Django is detected by searching parent directories for clues that indicate
the current file is within a Django project.
* `b:is_django` is set in any file that's within a Django project. This could
be useful for your personal scripts.
* `b:is_django_settings` is set if the file is `settings.py` or if the file is
in the same directory as `settings.py`. (`b:is_django` will still be set)
* Optionally append `.django` to the `filetype` for files found within a Django
project.
* If a Django project's `manage.py` script is found, completions will include
your settings and templatetags found in `INSTALLED_APPS`.
* `g:django_filetypes` takes a list of glob patterns to *append* the `django`
filetype to matching files. e.g. `*.xml` will have the filetype
`xml.django` if the file is found in a Django project.
### Python
* Completions for Django settings when `b:is_django_settings` is present.
* Completions for `settings.` when `b:is_django` is present in a `.py` file.
* Completions for template files when using `render()`, `get_template()`,
`render_to_string()`, `render_to_response()`, or `template_name =`.
* QuerySets could be lurking anywhere. That's why QuerySet completions will be
included for basically anything after a period.
* If you are using `Ultisnips`, Django snippets are enabled and
`UltiSnips#FileTypeChanged()` is called to ensure that `:UltiSnipsEdit` opens
`django.snippets` by default instead of `python.snippets`.
### HTML
* The filetype is set to `htmldjango` when editing HTML files.
* Basic completions for template tags and filters.
* Completions for template files when using `{% extends %}` or `{% include %}`.
* Django tags are indented correctly, including custom tags.
* `matchit` configuration for Django tags, including custom tags.
Additionally, the cursor is placed at the beginning of the tag name.
* Tag and variable blocks are highlighted within script tags, style tags, and
HTML attributes.
* If you are using Ultisnips, HTML snippets are enabled and
`UltiSnips#FileTypeChanged()` is called to ensure that `:UltiSnipsEdit` opens
`htmldjango.snippets` by default instead of `html.snippets`.
[deoplete]: https://github.com/Shougo/deoplete.nvim

View File

@ -0,0 +1,29 @@
if exists('b:did_django_ftplugin') || !exists('b:is_django')
finish
endif
let b:did_django_ftplugin = 1
let b:orig_omnifunc = &l:omnifunc
setlocal omnifunc=djangoplus#complete
if exists(':UltiSnipsEdit')
" Add HTML snippets
UltiSnipsAddFiletypes html
endif
if exists('loaded_matchit')
let b:match_ignorecase = 1
let b:match_skip = 's:Comment'
let b:match_words = '<:>,' .
\ '<\@<=[ou]l\>[^>]*\%(>\|$\):<\@<=li\>:<\@<=/[ou]l>,' .
\ '<\@<=dl\>[^>]*\%(>\|$\):<\@<=d[td]\>:<\@<=/dl>,' .
\ '<\@<=\([^/][^ \t>]*\)[^>]*\%(>\|$\):<\@<=/\1>,' .
\ '{% *if .*%}:{% *else *%}:{% *endif *%},' .
\ '\%({% *\)\@<=\%(end\)\@!\(\i\+\) .*%}:\%({% *\)\@<=end\1 .*%}'
endif
autocmd BufWritePost <buffer> call djangoplus#scan_template_tags()
call djangoplus#scan_template_tags()

View File

@ -0,0 +1,32 @@
if exists('b:did_django_ftplugin') || !exists('b:is_django')
finish
endif
let b:did_django_ftplugin = 1
let b:orig_omnifunc = &l:omnifunc
if !has('python') && b:orig_omnifunc ==# 'pythoncomplete#Complete'
let b:orig_omnifunc = ''
endif
setlocal omnifunc=djangoplus#complete
if exists(':UltiSnipsAddFiletypes')
" Add Django snippets
UltiSnipsAddFiletypes django
endif
if exists(':ImpSort')
function! s:django_sort(a, b) abort
return impsort#sort_top('^django', a:a, a:b)
endfunction
if get(g:, 'django_impsort_top', 1)
let b:impsort_method_prefix = [function('s:django_sort')]
\ + get(g:, 'impsort_method_imports', ['alpha', 'length'])
let b:impsort_method_group = [function('s:django_sort')]
\ + get(g:, 'impsort_method_group', ['length', 'alpha'])
let b:impsort_method_module = [function('s:django_sort')]
\ + get(g:, 'impsort_method_module', ['depth', 'length', 'alpha'])
endif
endif

View File

@ -0,0 +1,20 @@
" HTML is tricky as hell. Any number of plugins could want involvement in the
" indentation. From what I've seen, they chain the previous indentexpr making
" the b:did_indent check a little pointless. Since running as an
" 'after/indent' script, do not unlet b:did_indent before including
" indent/html.vim since it should already be loaded by now.
runtime! indent/html.vim
let b:did_indent = 1
if &l:indentexpr == ''
if &l:cindent
let &l:indentexpr = 'cindent(v:lnum)'
else
let &l:indentexpr = 'indent(prevnonblank(v:lnum-1))'
endif
endif
let b:djangoplus_indentexpr = &l:indentexpr
setlocal indentexpr=djangoplus#htmldjango_indent()
setlocal indentkeys=o,O,*<Return>,{,},o,O,!^F,<>>

View File

@ -0,0 +1,10 @@
if exists('b:did_django_syntax') || &l:filetype =~# '^html'
finish
endif
let b:did_django_syntax = 1
let b:django_orig_syntax = get(b:, 'current_syntax', 'django')
unlet! b:current_syntax
runtime! syntax/django.vim
let b:current_syntax = b:django_orig_syntax
unlet b:django_orig_syntax

View File

@ -0,0 +1,15 @@
let s:old = b:current_syntax
unlet b:current_syntax
syntax include @HTML $VIMRUNTIME/syntax/html.vim
syntax region djangoVerbatimBlock start="{%\s*verbatim\s*%}" end="{%\s*endverbatim\s*%}" transparent contains=@HTML containedin=ALL
syntax match djangoVerbatimTagBlock #{%\s*\%(end\)\?verbatim\s*%}# containedin=djangoVerbatimBlock
syntax cluster djangoBlocks add=djangoVerbatimBlock,djangoVerbatimTagBlock
" Highlight tag and variable blocks inside of scripts, styles, and attributes
syntax region djangoNestedTagBlock start="{%" end="%}" contained contains=djangoStatement,djangoFilter,djangoArgument,djangoTagError display containedin=htmlString,javaScript,javaScriptStringD,javaScriptStringN,jsStringS,jsStringD,cssStyle,cssDefinition
syntax region djangoNestedVarBlock start="{{" end="}}" contained contains=djangoFilter,djangoArgument,djangoVarError display containedin=htmlString,javaScript,javaScriptStringD,javaScriptStringN,jsStringS,jsStringD,cssStyle,cssDefinition
syntax cluster djangoBlocks add=djangoNestedTagBlock,djangoNestedVarBlock
highlight default link djangoNestedVarBlock djangoVarBlock
highlight default link djangoNestedTagBlock djangoTagBlock
highlight default link djangoVerbatimTagBlock djangoTagBlock

View File

@ -0,0 +1,14 @@
if !exists('b:is_django')
finish
endif
syntax match djangoQueryObject #\.objects\.#hs=s+1,he=e-1 containedin=TOP,pythonString,pythonComment
syntax match djangoModelsModule #\<models\.#he=e-1 containedin=TOP,pythonString,pythonComment
syntax match djangoModelField #\k\+Field\># containedin=TOP,pythonString,pythonComment
syntax keyword djangoModelField ForeignKey containedin=TOP,pythonString,pythonComment
syntax match djangoSettingsObject "\<settings\."he=e-1 containedin=TOP,pythonString,pythonComment
highlight default link djangoQueryObject Special
highlight default link djangoModelsModule Special
highlight default link djangoModelField Type
highlight default link djangoSettingsObject Special

View File

@ -0,0 +1,341 @@
let s:completion_script = expand('<sfile>:p:h:h').'/bin/completions.py'
let s:template_finder_script = expand('<sfile>:p:h:h').'/bin/template_finder.py'
let s:default_tags = [
\ 'block', 'cache', 'for', 'if', 'with', 'autoescape',
\ 'comment', 'filter', 'spaceless', 'verbatim']
let s:default_tags_pat = join(s:default_tags, '\|')
let s:midtags = '\(empty\|else\|elif\)'
let s:template_shell_find_enabled = executable('python')
let s:template_functions = join([
\ 'render([^,]\+,',
\ 'get_template(',
\ 'render_to_string(',
\ 'render_to_response(',
\ 'template_name\s*=',
\ ], '\|')
function! s:get_completions() abort
let group = ''
let sig = ''
let doc = ''
let out = {}
" This is really stupid, but whatever.
for item in split(system('python "'.s:completion_script.'" 2>/dev/null'), "\n")
if item =~# '^##'
if !empty(group) && !empty(sig)
call add(out[group], [sig, substitute(doc, '\\\\n', "\n", 'g')])
endif
let sig = item[2:]
let doc = ''
if group =~# '^htmldjango'
let sig = matchstr(sig, '\%({% \||\)\zs\i\+\ze')
endif
elseif item =~# '^@@'
if !empty(group) && !empty(sig)
call add(out[group], [sig, substitute(doc, '\\\\n', "\n", 'g')])
let sig = ''
let doc = ''
endif
let group = item[2:]
if !has_key(out, group)
let out[group] = []
endif
else
let doc .= item
endif
endfor
return out
endfunction
function! djangoplus#get_completions(group) abort
if !exists('s:completions')
" Get completions from the shell's python interpreter. This allows the
" completions to actually match the version of Django that's in use.
let s:completions = s:get_completions()
endif
if has_key(s:completions, a:group)
return s:completions[a:group]
endif
return []
endfunction
" Run the existing omnifunc if it exists.
function! s:default_completion(findstart, base) abort
if exists('b:orig_omnifunc') && !empty(b:orig_omnifunc)
" Restore the view after calling the original omnifunc.
" It seems that cursor could move in the function while using Deoplete.
let view = winsaveview()
let ret = call(b:orig_omnifunc, [a:findstart, a:base])
call winrestview(view)
return ret
endif
if a:findstart == 1
return -2
else
return []
endif
endfunction
function! s:init_python() abort
let s:pydo = ''
if has('python3')
let s:pydo = 'py3do'
execute 'py3file' s:template_finder_script
elseif has('python')
let s:pydo = 'pydo'
execute 'pyfile' s:template_finder_script
endif
endfunction
function! s:get_templates() abort
if exists('s:template_cache')
return s:template_cache
endif
if !exists('s:pydo')
call s:init_python()
endif
let apppaths = join(map(copy(djangoplus#get_completions('apppaths')), 'v:val[0]'), ',')
if !empty(s:pydo)
" execute s:pydo 'app_paths = []'
" for item in apppaths
" execute s:pydo 'add_app_path("'.item.'")'
" endfor
execute s:pydo 'djangoplus_find_templates("'.getcwd().'", "'.apppaths.'")'
else
if s:template_shell_find_enabled
let s:template_cache = split(system('python "'.s:template_finder_script.'" "'.getcwd().'"'), "\n")
else
let s:template_cache = []
endif
endif
if !exists('s:template_cache')
let s:template_cache = []
endif
return copy(s:template_cache)
endfunction
function! djangoplus#clear_template_cache() abort
unlet! s:template_cache
endfunction
" Completions for Django python and HTML files.
function! djangoplus#complete(findstart, base) abort
if !exists('b:orig_omnifunc') || !exists('b:is_django')
return s:default_completion(a:findstart, a:base)
endif
if a:findstart == 1
let s:do_assignment = 0
let s:do_completion = 0
let s:do_mix = 0
let s:kind = ''
let line = strpart(getline(line('.')), 0, col('.') - 1)
let idx = -1
let source_set = ''
if &l:filetype =~# '\<python\>'
if exists('b:is_django_settings')
" In settings files, show setting completions
let idx = match(line, '\<\zs\i*$')
let s:do_mix = !has('nvim')
let s:kind = 'conf'
let source_set = 'settings'
elseif line =~# '\<settings\.\i*$'
" Matched right after `settings.`
let idx = match(line, '\<settings\.\zs\i*$')
let s:kind = 'conf'
let source_set = 'settings'
elseif line =~# '\.objects\.\i*$'
" Matched right after `.objects.`
let idx = match(line, '\.objects\.\zs\i*$')
let s:kind = 'qs'
let source_set = 'queryset'
elseif line =~# '\i\+\.\i*$'
" Any dot, but mix results with the previous completion function
let idx = match(line, '\.\zs\i*$')
let s:do_mix = !has('nvim')
let s:kind = 'qs'
let source_set = 'queryset'
elseif line =~# '\<\%('.s:template_functions.'\)\s*[''"]\zs\f*$'
let idx = match(line, '\f*$')
let s:kind = 'tpl'
endif
elseif &l:filetype =~# '\<htmldjango\>'
if line =~# '{%\s\+\i*$'
let idx = match(line, '{%\s\+\zs\i*$')
let s:kind = 'tag'
let source_set = 'htmldjangotags'
elseif line =~# '|\i*$'
let idx = match(line, '|\zs\i*$')
let s:kind = 'filt'
let source_set = 'htmldjangofilters'
elseif line =~# '{% \%(include\|extends\)\>\s\+[''"]\zs\f*$'
let idx = match(line, '\f*$')
let s:kind = 'tpl'
endif
endif
if idx != -1
let s:do_completion = 1
let s:do_assignment = source_set == 'settings' && strpart(line, 0, idx) !~ '=.*'
let s:source = djangoplus#get_completions(source_set)
if source_set == 'settings' || source_set =~# '^htmldjango'
let s:word_pattern = '\i\+\ze'
else
let s:word_pattern = '\i\+\ze\%(\|\_$\)'
endif
if s:do_mix
" Let the original omnifunc do its thing
let s:orig_omnifunc_start = s:default_completion(1, '')
endif
return idx
endif
elseif s:do_completion
let completions = []
if s:kind == 'tpl'
let templates = s:get_templates()
for path in templates
if stridx(path, a:base) == 0
call add(completions, {
\ 'word': path,
\ 'abbr': path,
\ 'info': path,
\ 'icase': 0,
\ 'kind': s:kind,
\ 'menu': '[Dj+]',
\ })
endif
endfor
else
for item in s:source
let word = matchstr(item[0], s:word_pattern)
if word =~? '^'.a:base
call add(completions, {
\ 'word': word,
\ 'abbr': item[0].(s:do_assignment ? ' = ' : ''),
\ 'info': item[0]."\n\n".item[1],
\ 'icase': 0,
\ 'kind': s:kind,
\ 'menu': '[Dj+]',
\ })
endif
endfor
endif
if s:do_mix
let orig_base = strpart(getline(v:lnum), s:orig_omnifunc_start)
return s:default_completion(s:orig_omnifunc_start, orig_base) + completions
endif
return completions
endif
return s:default_completion(a:findstart, a:base)
endfunction
" Tag scanning. This sets b:blocktags by searching for {% end* %} tags
" allowing custom tags to be indented correctly as well.
function! djangoplus#scan_template_tags() abort
let view = winsaveview()
let reg_val = getreg('a')
let reg_type = getregtype('a')
" Cobble together all matching lines...
normal! qaq
silent g/{%\s\+\<end\S\+\>/y A
let matches = getreg('a')
call setreg('a', reg_val, reg_type)
call histdel('search', -1)
let @/ = histget('search', -1)
call winrestview(view)
let blocktags = []
" ...then strip out the garbage and split on whitespace
for tag in split(substitute(matches,
\ '\%(\%(\_^\|\_.\{-}\){%\s\+\<end\(\i\+\)\>\)\%([^{]*\)\|.*$', '\1 ', 'g'))
if index(s:default_tags, tag) == -1 && index(blocktags, tag) == -1
call add(blocktags, tag)
endif
endfor
if !empty(blocktags)
let b:blocktags = join(blocktags, '\|')
endif
endfunction
" Note: The after/ftplugin/htmldjango.vim script fills `b:blocktags` with more
" blocks it finds on load/save.
function! djangoplus#htmldjango_indent(...) abort
if a:0 && a:1 == '.'
let v:lnum = line('.')
elseif a:0 && a:1 =~ '^\d'
let v:lnum = a:1
endif
let vcol = col('.')
call cursor(v:lnum,vcol)
exe 'let ind = '.b:djangoplus_indentexpr
let lnum = prevnonblank(v:lnum-1)
let pnb = getline(lnum)
let cur = getline(v:lnum)
let tagstart = '.*' . '{%-\?\s*'
let tagend = '.*-\?%}' . '.*'
let blocktags = s:default_tags_pat
let buffer_tags = get(b:, 'blocktags', '')
if !empty(buffer_tags)
let blocktags .= '\|'.buffer_tags
endif
let blocktags = '\('.blocktags.'\)'
let pnb_blockstart = pnb =~# tagstart . blocktags . tagend
let pnb_blockend = pnb =~# tagstart . 'end' . blocktags . tagend
let pnb_blockmid = pnb =~# tagstart . s:midtags . tagend
let cur_blockstart = cur =~# tagstart . blocktags . tagend
let cur_blockend = cur =~# tagstart . 'end' . blocktags . tagend
let cur_blockmid = cur =~# tagstart . s:midtags . tagend
if pnb_blockstart && !pnb_blockend && pnb_blockstart != pnb_blockend
let ind = ind + &sw
elseif pnb_blockmid && !pnb_blockend && pnb_blockmid != pnb_blockstart && pnb_blockmid != pnb_blockend
let ind = ind + &sw
endif
if cur_blockend && !cur_blockstart && cur_blockend != cur_blockstart
let ind = ind - &sw
elseif cur_blockmid && cur_blockmid != cur_blockstart && cur_blockmid != cur_blockend
let ind = ind - &sw
endif
return ind
endfunction

View File

@ -0,0 +1,221 @@
" Django is detected by looking for clues of a Django project. Directories
" have been traversed are cached to speed up subsequent scans.
let s:seen = {}
let s:django_app_modules = [
\ 'admin',
\ 'apps',
\ 'managers',
\ 'migrations',
\ 'models',
\ 'templatetags',
\ 'tests',
\ 'urls',
\ 'views',
\ ]
let s:django_app_dirs = [
\ 'static',
\ 'templates',
\ ]
let s:pathsep = expand('/')
let s:pathsep_p = escape(s:pathsep, '\')
" Test a file name to see if it's a python module.
function! s:has_module(dirname, module)
return filereadable(a:dirname.'/'.a:module.'.py')
\ || filereadable(a:dirname.'/'.a:module.'/__init__.py')
endfunction
" Test a directory for a management script>
function! s:is_django_project(dirname)
if filereadable(a:dirname.'/manage.py')
let $_DJANGOPLUS_MANAGEMENT = a:dirname.'/manage.py'
return 1
endif
return 0
endfunction
function! s:settings_path() abort
if exists('s:django_conf_path')
return s:django_conf_path
endif
if !exists('$_DJANGOPLUS_MANAGEMENT') || !filereadable($_DJANGOPLUS_MANAGEMENT)
return ''
endif
for line in readfile($_DJANGOPLUS_MANAGEMENT)
let module = matchstr(line,
\ '\(["'']\)DJANGO_SETTINGS_MODULE\1,'
\.'\s*\(["'']\)\zs\%(\2\@!.\)\+\ze\2')
if !empty(module)
if module =~# '\.'
let module_path = join(split(module, '\.'), s:pathsep)
else
let module_path = module
endif
let module_path = fnamemodify($_DJANGOPLUS_MANAGEMENT, ':h')
\.s:pathsep.module_path
let conf_path = ''
if filereadable(module_path.'.py')
let conf_path = fnamemodify(module_path, ':h')
elseif filereadable(module_path.'/__init__.py')
let conf_path = module_path
endif
if !empty(conf_path)
let s:django_conf_path = conf_path
return s:django_conf_path
endif
endif
endfor
return ''
endfunction
function! s:is_django_settings(filename) abort
let settings_path = s:settings_path()
if empty(settings_path)
return 0
endif
return a:filename =~# '^'.settings_path.s:pathsep_p
endfunction
" Test a directory to see if it looks like a Django app.
function! s:is_django_app(dirname)
let min_matches = 2
let dirname = a:dirname
if filereadable(dirname.'/__init__.py')
" Apps are modules
let match_count = 0
for name in s:django_app_dirs
if isdirectory(dirname.'/'.name)
let match_count += 1
if match_count >= min_matches
return 1
endif
endif
endfor
for name in s:django_app_modules
if s:has_module(dirname, name)
let match_count += 1
if match_count >= match_count
return 1
endif
endif
endfor
endif
return 0
endfunction
" Scan parents for a match
function! s:scan(filename, func) abort
if empty(a:filename)
return 0
endif
let dirname = fnamemodify(a:filename, ':p:h')
let last_dir = ''
let depth = 0
let max_depth = get(g:, 'django_max_scan_depth', 10)
while depth < max_depth && dirname != last_dir && dirname !~ '^\/*$'
let last_dir = dirname
if has_key(s:seen, dirname)
if s:seen[dirname]
return 1
else
let dirname = fnamemodify(dirname, ':h')
continue
endif
endif
if call(a:func, [dirname])
let s:seen[dirname] = 1
return 1
endif
let s:seen[dirname] = 0
let depth += 1
let dirname = fnamemodify(dirname, ':h')
endwhile
return 0
endfunction
" Perform a quick check to see if the the current directory is a Django
" project. Returns 0 or 1 if the current directory is a Django project, and
" -1 if it's not.
function! s:simple_django_project(filename)
let cwd = getcwd()
if !has_key(s:seen, cwd)
let s:seen[cwd] = s:is_django_project(cwd)
endif
return s:seen[cwd] ? a:filename =~# '^'.escape(cwd, '.\^$[]').s:pathsep_p : -1
endfunction
" Detect Django related files
function! djangoplus#detect#filetype(filename) abort
if empty(a:filename)
return
endif
let is_django = s:simple_django_project(a:filename)
if is_django == -1
" Since the current directory isn't a Django project, perform a more
" exhaustive scan.
let is_django = s:scan(a:filename, 's:is_django_project')
\ || s:scan(a:filename, 's:is_django_app')
endif
if is_django
let b:is_django = 1
let filedir = fnamemodify(a:filename, ':h')
autocmd! CursorHold <buffer> call djangoplus#clear_template_cache()
if a:filename =~? '\.html\?$'
setfiletype htmldjango
elseif s:is_django_settings(a:filename)
setfiletype python
let b:is_django_settings = 1
elseif a:filename =~# '\.py$'
setfiletype python
else
for pat in get(g:, 'django_filetypes', [])
if a:filename =~# glob2regpat(pat)
let bft = &l:filetype
if !empty(bft)
let bft .= '.django'
else
let bft = 'django'
endif
execute 'setfiletype' bft
endif
endfor
for ft in split(&l:filetype, '\.')
execute 'runtime! ftplugin/'.ft.'.vim'
execute 'runtime! after/ftplugin/'.ft.'.vim'
endfor
endif
endif
endfunction

View File

@ -0,0 +1,204 @@
"""Print completions
- @@ prefix is a completion group.
- ## prefix is a completion word.
- All other lines are documentation.
"""
import os
import re
import sys
import inspect
from glob import glob
try:
import django
except ImportError:
sys.exit(0)
if django and '_DJANGOPLUS_MANAGEMENT' in os.environ:
script = os.getenv('_DJANGOPLUS_MANAGEMENT')
base = os.path.abspath(os.path.dirname(script))
settings_module = ''
with open(script) as fp:
m = re.search(r'(["\'])DJANGO_SETTINGS_MODULE\1,\s+(["\'])([^\2]+?)\2', fp.read())
if m:
settings_module = m.group(3)
os.environ['DJANGO_SETTINGS_MODULE'] = settings_module
if settings_module:
os.chdir(base)
orig_path = sys.path[:]
if base not in sys.path:
sys.path.insert(0, base)
try:
django.setup()
except:
pass
path_components = [base] + settings_module.split('.')[:-1] + ['*.py']
settings = glob(os.path.join(*path_components))
else:
settings = []
from django.apps import apps
else:
django.setup = lambda: False
from django.apps.registry import apps
apps.apps_ready = True
settings = []
from django.conf import global_settings
from django.core.exceptions import ImproperlyConfigured, AppRegistryNotReady
from django.db.models.query import QuerySet
print('@@apppaths')
try:
for app_config in apps.get_app_configs():
print('##%s' % app_config.path)
except AppRegistryNotReady:
pass
try:
from django.conf import settings as djsettings
tpldirs = set(getattr(djsettings, 'TEMPLATE_DIRS', []))
if not isinstance(tpldirs, set):
tpldirs = set()
for tplconf in getattr(djsettings, 'TEMPLATES', []):
if 'DIRS' in tplconf:
tpldirs.update(tplconf['DIRS'])
for tpldir in tpldirs:
print('##tpl|%s' % tpldir)
except:
pass
try:
from django.template import library
from django.template.backends import django as tplbackend
def import_library(module):
return library.import_library(module)
def get_installed_libraries():
for module in tplbackend.get_installed_libraries().values():
try:
yield library.import_library(module)
except (ImproperlyConfigured, library.InvalidTemplateLibrary):
continue
except ImportError:
from pkgutil import walk_packages
from django.template import base as tplbase
def import_library(module):
return tplbase.import_library(module)
def get_installed_libraries():
for module in tplbase.get_templatetags_modules():
try:
pkg = tplbase.import_module(module)
except:
pass
for entry in walk_packages(pkg.__path__, pkg.__name__ + '.'):
try:
module = tplbase.import_module(entry[1])
if hasattr(module, 'register'):
yield module.register
except (ImproperlyConfigured, ImportError):
pass
def func_signature(obj):
if hasattr(inspect, 'signature'):
return '%s%s' % (obj.__name__, str(inspect.signature(obj)))
else:
return '%s%s' % (obj.__name__,
inspect.formatargspec(*inspect.getargspec(obj)))
completions = {
'settings': [],
'queryset': [],
}
filename = global_settings.__file__
base, ext = os.path.splitext(filename)
if ext == '.pyc':
filename = base + '.py'
settings.insert(0, filename)
seen_settings = set()
seen_tags = set()
seen_filters = set()
def print_tags(tags):
if not tags:
return
print('@@htmldjangotags')
for tagname, tagfunc in tags.items():
if tagname in seen_tags:
continue
seen_tags.add(tagname)
print('##{%% %s %%}' % tagname)
print((inspect.getdoc(tagfunc) or '').replace('\n', '\\n'))
def print_filters(filters):
if not filters:
return
print('@@htmldjangofilters')
for filtername, filterfunc in filters.items():
if filtername in seen_filters:
continue
seen_filters.add(filtername)
print('##|%s' % filtername)
print((inspect.getdoc(filterfunc) or '').replace('\n', '\\n'))
print('@@settings')
for filename in settings:
with open(filename, 'rt') as fp:
for doc, var in re.findall('^((?:\s*# .+\n)*)?\s*([0-9A-Z_]+) =',
fp.read(), re.M):
if var in seen_settings:
continue
seen_settings.add(var)
print('##' + var)
print('\\n'.join(x.strip('# ') for x
in doc.split('\n')).strip())
print('@@queryset')
for item in dir(QuerySet):
if item.startswith('__'):
continue
obj = getattr(QuerySet, item)
if hasattr(obj, '__call__'):
print('##' + func_signature(obj))
print((inspect.getdoc(obj) or '').replace('\n', '\\n'))
else:
print('##' + item)
print_tags(import_library('django.template.defaulttags').tags)
print_filters(import_library('django.template.defaultfilters').filters)
try:
for lib in get_installed_libraries():
print_tags(lib.tags)
print_filters(lib.filters)
except AppRegistryNotReady:
pass
# Make sure the completion parser finishes
print('##')

View File

@ -0,0 +1,79 @@
import os
exclude_dirs = (
'.hg',
'.git',
'.svn',
'node_modules',
'__pycache__',
)
def djangoplus_find_templates(cwd, app_paths, cmdline=False):
templates = set()
project_paths = []
app_paths = app_paths.split(',')
for file in os.listdir(cwd):
path = os.path.join(cwd, file)
if file[0] == '.' or not os.path.isdir(path) or file in exclude_dirs:
continue
if path not in app_paths and not os.path.exists(os.path.join(path, '__init__.py')):
continue
if path not in app_paths:
project_paths.append(path)
template_paths = set()
for i, path in enumerate(app_paths):
if path.startswith('tpl|'):
path = path[4:]
elif os.path.split(path)[-1] == 'templates':
pass
else:
path = os.path.join(path, 'templates')
if not os.path.exists(path):
path = ''
if not path or path in template_paths:
continue
template_paths.add(path)
for root, dirs, files in os.walk(path):
directory = root[len(path)+1:]
if directory:
templates.add('%s/' % directory)
templates.update(os.path.join(root, x)[len(path)+1:] for x in files)
for path in project_paths:
for root, dirs, files in os.walk(path):
dirs[:] = [d for d in dirs if d not in exclude_dirs]
parts = root.split(os.path.sep)
if 'templates' not in parts:
continue
i = parts.index('templates')
i += sum(len(x) for x in parts[:i+1]) + 1
directory = root[i:]
if directory:
templates.add('%s/' % directory)
templates.update(os.path.join(root, x)[i:] for x in files)
templates = list(sorted(templates, key=lambda x:
(len(x.split(os.path.sep)), x)))
try:
import vim # noqa F811
vim.command('let s:template_cache = %s' % repr(templates).replace("u'", "'"))
except ImportError:
print('\n'.join(templates))
if __name__ == "__main__":
try:
import vim # noqa F401
except ImportError:
djangoplus_find_templates(os.getcwd(), '', 1)

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,208 @@
*django-plus.txt* *django-plus*
$$\ ~
$$ | $$\ ~
$$$$$$$ |$$\ $$$$$$\ $$$$$$$\ $$$$$$\ $$$$$$\ $$ | ~
$$ __$$ |\__| \____$$\ $$ __$$\ $$ __$$\ $$ __$$\$$$$$$$$\ ~
$$ / $$ |$$\ $$$$$$$ |$$ | $$ |$$ / $$ |$$ / $$ \__$$ __| ~
$$ | $$ |$$ |$$ __$$ |$$ | $$ |$$ | $$ |$$ | $$ | $$ | ~
\$$$$$$$ |$$ |\$$$$$$$ |$$ | $$ |\$$$$$$$ |\$$$$$$ | \__| ~
\_______|$$ | \_______|\__| \__| \____$$ | \______/ ~
$$\ $$ | $$\ $$ | ~
\$$$$$$ | \$$$$$$ | ~
\______/ \______/ ~
==============================================================================
CONTENTS *django-plus-contents*
Intro |django-plus-intro|
Settings |django-plus-settings|
Completions |django-plus-completions|
Python Improvements |django-plus-python|
HTML Improvements |django-plus-html|
Useful Plugins |django-plus-plugins|
License |django-plus-license|
==============================================================================
INTRO *django-plus-intro*
This plugin can be found on Github:
https://github.com/tweekmonster/django-plus.vim
The following variables are set when a file within a Django project is
detected:
*b:is_django*
b:is_django Set for any opened file that's within a Django
project.
*b:is_django_settings*
b:is_django_settings Set for any opened file that ends with `settings.py`
or is a file that's within a directory that contains
`settings.py`
==============================================================================
SETTINGS *django-plus-settings*
*g:django_max_scan_depth*
g:django_max_scan_depth
The maximum number of parent directories to scan
for a Django project. The default is `10` which is a
pretty reasonable depth. If your directory
structure goes deeper for files you are actually
editing, you might want to think about restructuring.
*g:django_filetypes*
g:django_filetypes A list of filename patterns. Each pattern must be a
|wildcard| pattern. If a file matches, the 'filetype'
will be updated to include `.django`
For example: Matching `*.xml` will set the 'filetype'
to `xml.django`
Note: Look at `$VIMRUNTIME/syntax/django.vim`.
The `django` filetype is for templates, NOT python
scripts. Things may not work the way you expect if
you use `python.django` as a filetype for Python
scripts. Snippet plugins are treating the `django`
filetype incorrectly. You could say that the built in
syntax script got it wrong, but it was wrong first.
*g:django_impsort_top*
g:django_impsort_top If enabled, configures |impsort| to sort Django
imports to the top of import groups. Since this is
configured as an ftplugin and sets up buffer
variables, you must restart Vim for this to take
effect.
Requires `impsort.vim` to be installed.
See: |django-plus-plugins|
Default: `1`
==============================================================================
COMPLETIONS *django-plus-completions*
Completions are found by running an external Python script the first time
completions are used. If you are using Neovim, a completion source for
`deoplete.nvim` is included.
Default settings and template tags & filters will be available for completion.
In files related to settings, no prefix is needed to get completions. In all
other files, you need to type `settings.` to trigger completions.
QuerySet completions will be displayed after `.` (periods) since it's not easy
to determine if a variable is a QuerySet object. The default completions are
displayed before QuerySet completions. If `.objects.` appears before the
cursor, QuerySet comletions will be displayed exclusively.
In `htmldjango` files, completions for template tags will be displayed after
`{%` and filters will be displayed after `|` (pipe character). These
completions will only complete words, not entire tag/filter. Expanding the
`%%` snippet will give you an easy way to create block tags.
If `manage.py` is found during a scan, it will be used to get your project's
settings, and template tags & filters. Django's app registry will be
populated to get tags & filters. For settings, all Python scripts found in
the same directory as `settings.py` will be scanned for uppercase variable
names.
==============================================================================
PYTHON IMPROVEMENTS *django-plus-python*
* Completions for Django settings when `b:is_django_settings` is present.
* Completions for `settings.` when `b:is_django` is present in a `.py` file.
* QuerySets could be lurking anywhere. That's why QuerySet completions will
be included for basically anything after a period.
* If you are using `Ultisnips`, Django snippets are enabled and
`UltiSnips#FileTypeChanged()` is called to ensure that `:UltiSnipsEdit` opens
`django.snippets` by default instead of `python.snippets`.
==============================================================================
HTML IMPROVEMENTS *django-plus-html*
* The filetype is set to `htmldjango` when editing HTML files.
* Basic completions for template tags and filters.
* Django tags are indented correctly, including custom tags.
* `matchit` configuration for Django tags, including custom tags.
Additionally, the cursor is placed at the beginning of the tag name.
* Tag and variable blocks are highlighted within script tags, style tags, and
HTML attributes.
* If you are using Ultisnips, HTML snippets are enabled and
`UltiSnips#FileTypeChanged()` is called to ensure that `:UltiSnipsEdit` opens
`htmldjango.snippets` by default instead of `html.snippets`.
==============================================================================
PLUGINS *django-plus-plugins*
This is a list of plugins that are useful for getting the most out of Django+
or making Django development a little more pleasant.
{vim-jedi} - Provides accurate completions as well as other productivity
related features.
URL: https://github.com/davidhalter/jedi-vim
{UltiSnips} - A snippet engine for Vim. You will need to install/create
snippets.
URL: https://github.com/SirVer/ultisnips
{vim-snippets} - A good source for pre-made snippets.
URL: https://github.com/honza/vim-snippets
{impsort.vim} - Sort your import lines.
URL: https://github.com/tweekmonster/impsort.vim
If you are using Neovim:
{deoplete.nvim} - An excellent asynchronous completion engine.
URL: https://github.com/Shougo/deoplete.nvim
{deoplete-jedi} - Uses Jedi to get Python completions. It is exceptionally
fast, but is _only_ a completion source. {vim-jedi} will still be useful, but
its completions need to be disabled.
URL: https://github.com/zchee/deoplete-jedi
==============================================================================
LICENSE *django-plus-license*
The MIT License
Copyright (c) 2016 Tommy Allen
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
vim:tw=78:ts=8:noet:ft=help:norl:

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,4 @@
augroup filetypedetect
" Since templates can be anything, check any file.
autocmd BufRead,BufNewFile * call djangoplus#detect#filetype(expand('<afile>:p'))
augroup END

View File

@ -0,0 +1,34 @@
import re
from .base import Base
_high_priority_re = re.compile(
r'(?:'
r'(?:\.objects\.\w*)|'
r'(?:\bsettings\.\w*)|'
r'(?:\{%\s+(?:include|extends)\s+["\'][\w/]+)|'
r'(?:(?:render\([^,]+,|get_template\(|render_to_string\(|render_to_response\(|template_name\s*=)\s*["\'][\w/]*)'
r')$'
)
class Source(Base):
def __init__(self, vim):
super(Source, self).__init__(vim)
self.name = 'django'
self.mark = ''
self.filetypes = ['python', 'htmldjango']
self.input_pattern = '.\.\w*$|\|\w*$|\{%\s+\w*$'
def get_complete_position(self, context):
self.rank = 10
line = context.get('input')
if line and _high_priority_re.search(line):
self.rank = 9000
return self.vim.call('djangoplus#complete', 1, '')
def gather_candidates(self, context):
candidates = self.vim.call('djangoplus#complete', 0,
context['complete_str'])
return candidates

View File

@ -109,125 +109,126 @@ CONTENTS *SpaceVim-contents*
14. exprfold..................................|SpaceVim-layers-exprfold|
15. foldsearch..............................|SpaceVim-layers-foldsearch|
16. format......................................|SpaceVim-layers-format|
17. fzf............................................|SpaceVim-layers-fzf|
18. git............................................|SpaceVim-layers-git|
19. github......................................|SpaceVim-layers-github|
20. gtags........................................|SpaceVim-layers-gtags|
21. incsearch................................|SpaceVim-layers-incsearch|
22. indentmove..............................|SpaceVim-layers-indentmove|
23. lang#WebAssembly..................|SpaceVim-layers-lang-WebAssembly|
24. lang#actionscript................|SpaceVim-layers-lang-actionscript|
25. lang#agda................................|SpaceVim-layers-lang-agda|
26. lang#asciidoc........................|SpaceVim-layers-lang-asciidoc|
27. lang#asepctj..........................|SpaceVim-layers-lang-asepctj|
28. lang#assembly........................|SpaceVim-layers-lang-assembly|
29. lang#autohotkey....................|SpaceVim-layers-lang-autohotkey|
30. lang#autoit............................|SpaceVim-layers-lang-autoit|
31. lang#batch..............................|SpaceVim-layers-lang-batch|
32. lang#c......................................|SpaceVim-layers-lang-c|
33. lang#chapel............................|SpaceVim-layers-lang-chapel|
34. lang#clojure..........................|SpaceVim-layers-lang-clojure|
35. lang#coffeescript................|SpaceVim-layers-lang-coffeescript|
36. lang#crystal..........................|SpaceVim-layers-lang-crystal|
37. lang#csharp............................|SpaceVim-layers-lang-csharp|
38. lang#d......................................|SpaceVim-layers-lang-d|
39. lang#dart................................|SpaceVim-layers-lang-dart|
40. lang#dockerfile....................|SpaceVim-layers-lang-dockerfile|
41. lang#e......................................|SpaceVim-layers-lang-e|
42. lang#eiffel............................|SpaceVim-layers-lang-eiffel|
43. lang#elixir............................|SpaceVim-layers-lang-elixir|
44. lang#elm..................................|SpaceVim-layers-lang-elm|
45. lang#erlang............................|SpaceVim-layers-lang-erlang|
46. lang#extra..............................|SpaceVim-layers-lang-extra|
47. lang#fennel............................|SpaceVim-layers-lang-fennel|
48. lang#forth..............................|SpaceVim-layers-lang-forth|
49. lang#fortran..........................|SpaceVim-layers-lang-fortran|
50. lang#foxpro............................|SpaceVim-layers-lang-foxpro|
51. lang#fsharp............................|SpaceVim-layers-lang-fsharp|
52. lang#go....................................|SpaceVim-layers-lang-go|
53. lang#goby................................|SpaceVim-layers-lang-goby|
54. lang#gosu................................|SpaceVim-layers-lang-gosu|
55. lang#graphql..........................|SpaceVim-layers-lang-graphql|
56. lang#groovy............................|SpaceVim-layers-lang-groovy|
57. lang#hack................................|SpaceVim-layers-lang-hack|
58. lang#haskell..........................|SpaceVim-layers-lang-haskell|
59. lang#haxe................................|SpaceVim-layers-lang-haxe|
60. lang#html................................|SpaceVim-layers-lang-html|
61. lang#hy....................................|SpaceVim-layers-lang-hy|
62. lang#idris..............................|SpaceVim-layers-lang-idris|
63. lang#io....................................|SpaceVim-layers-lang-io|
64. lang#j......................................|SpaceVim-layers-lang-j|
65. lang#janet..............................|SpaceVim-layers-lang-janet|
66. lang#java................................|SpaceVim-layers-lang-java|
67. lang#javascript....................|SpaceVim-layers-lang-javascript|
68. lang#jr....................................|SpaceVim-layers-lang-jr|
69. lang#json................................|SpaceVim-layers-lang-json|
70. lang#julia..............................|SpaceVim-layers-lang-julia|
71. lang#kotlin............................|SpaceVim-layers-lang-kotlin|
72. lang#latex..............................|SpaceVim-layers-lang-latex|
73. lang#lisp................................|SpaceVim-layers-lang-lisp|
74. lang#livescript....................|SpaceVim-layers-lang-livescript|
75. lang#lua..................................|SpaceVim-layers-lang-lua|
76. lang#markdown........................|SpaceVim-layers-lang-markdown|
77. lang#moonscript....................|SpaceVim-layers-lang-moonscript|
78. lang#nim..................................|SpaceVim-layers-lang-nim|
79. lang#nix..................................|SpaceVim-layers-lang-nix|
80. lang#ocaml..............................|SpaceVim-layers-lang-ocaml|
81. lang#octave............................|SpaceVim-layers-lang-octave|
82. lang#pact................................|SpaceVim-layers-lang-pact|
83. lang#pascal............................|SpaceVim-layers-lang-pascal|
84. lang#perl................................|SpaceVim-layers-lang-perl|
85. lang#php..................................|SpaceVim-layers-lang-php|
86. lang#plantuml........................|SpaceVim-layers-lang-plantuml|
87. lang#pony................................|SpaceVim-layers-lang-pony|
88. lang#processing....................|SpaceVim-layers-lang-processing|
89. lang#prolog............................|SpaceVim-layers-lang-prolog|
90. lang#puppet............................|SpaceVim-layers-lang-puppet|
91. lang#purescript....................|SpaceVim-layers-lang-purescript|
92. lang#python............................|SpaceVim-layers-lang-python|
93. lang#racket............................|SpaceVim-layers-lang-racket|
94. lang#racket...............................|SpaceVim-layers-lang-red|
95. lang#reason............................|SpaceVim-layers-lang-reason|
96. lang#ring...................................|SpaceVim-layers-lang-r|
97. lang#ring................................|SpaceVim-layers-lang-ring|
98. lang#ruby................................|SpaceVim-layers-lang-ruby|
99. lang#rust................................|SpaceVim-layers-lang-rust|
100. lang#scala.............................|SpaceVim-layers-lang-scala|
101. lang#scheme...........................|SpaceVim-layers-lang-scheme|
102. lang#sh...................................|SpaceVim-layers-lang-sh|
103. lang#smalltalk.....................|SpaceVim-layers-lang-smalltalk|
104. lang#sml.................................|SpaceVim-layers-lang-sml|
105. lang#swig..............................|SpaceVim-layers-lang-swift|
106. lang#swig...............................|SpaceVim-layers-lang-swig|
107. lang#tcl.................................|SpaceVim-layers-lang-tcl|
108. lang#teal...............................|SpaceVim-layers-lang-teal|
109. lang#toml...............................|SpaceVim-layers-lang-toml|
110. lang#typescript...................|SpaceVim-layers-lang-typescript|
111. lang#v.....................................|SpaceVim-layers-lang-v|
112. lang#vala...............................|SpaceVim-layers-lang-vala|
113. lang#vbnet.............................|SpaceVim-layers-lang-vbnet|
114. lang#verilog.........................|SpaceVim-layers-lang-verilog|
115. lang#vim.................................|SpaceVim-layers-lang-vim|
116. lang#vue.................................|SpaceVim-layers-lang-vue|
117. lang#wdl.................................|SpaceVim-layers-lang-wdl|
118. lang#wolfram.........................|SpaceVim-layers-lang-wolfram|
119. lang#xml.................................|SpaceVim-layers-lang-xml|
120. lang#xquery...........................|SpaceVim-layers-lang-xquery|
121. lang#zig.................................|SpaceVim-layers-lang-zig|
122. language server protocol......................|SpaceVim-layers-lsp|
123. leaderf...................................|SpaceVim-layers-leaderf|
124. mail.........................................|SpaceVim-layers-mail|
125. operator.................................|SpaceVim-layers-operator|
126. shell.......................................|SpaceVim-layers-shell|
127. ssh...........................................|SpaceVim-layers-ssh|
128. test.........................................|SpaceVim-layers-test|
129. tmux.........................................|SpaceVim-layers-tmux|
130. tools#dash.............................|SpaceVim-layers-tools-dash|
131. tools#mpv...............................|SpaceVim-layers-tools-mpv|
132. tools#zeal.............................|SpaceVim-layers-tools-zeal|
133. treesitter.............................|SpaceVim-layers-treesitter|
134. ui.............................................|SpaceVim-layers-ui|
135. unite.......................................|SpaceVim-layers-unite|
17. framework#django..................|SpaceVim-layers-framework-django|
18. fzf............................................|SpaceVim-layers-fzf|
19. git............................................|SpaceVim-layers-git|
20. github......................................|SpaceVim-layers-github|
21. gtags........................................|SpaceVim-layers-gtags|
22. incsearch................................|SpaceVim-layers-incsearch|
23. indentmove..............................|SpaceVim-layers-indentmove|
24. lang#WebAssembly..................|SpaceVim-layers-lang-WebAssembly|
25. lang#actionscript................|SpaceVim-layers-lang-actionscript|
26. lang#agda................................|SpaceVim-layers-lang-agda|
27. lang#asciidoc........................|SpaceVim-layers-lang-asciidoc|
28. lang#asepctj..........................|SpaceVim-layers-lang-asepctj|
29. lang#assembly........................|SpaceVim-layers-lang-assembly|
30. lang#autohotkey....................|SpaceVim-layers-lang-autohotkey|
31. lang#autoit............................|SpaceVim-layers-lang-autoit|
32. lang#batch..............................|SpaceVim-layers-lang-batch|
33. lang#c......................................|SpaceVim-layers-lang-c|
34. lang#chapel............................|SpaceVim-layers-lang-chapel|
35. lang#clojure..........................|SpaceVim-layers-lang-clojure|
36. lang#coffeescript................|SpaceVim-layers-lang-coffeescript|
37. lang#crystal..........................|SpaceVim-layers-lang-crystal|
38. lang#csharp............................|SpaceVim-layers-lang-csharp|
39. lang#d......................................|SpaceVim-layers-lang-d|
40. lang#dart................................|SpaceVim-layers-lang-dart|
41. lang#dockerfile....................|SpaceVim-layers-lang-dockerfile|
42. lang#e......................................|SpaceVim-layers-lang-e|
43. lang#eiffel............................|SpaceVim-layers-lang-eiffel|
44. lang#elixir............................|SpaceVim-layers-lang-elixir|
45. lang#elm..................................|SpaceVim-layers-lang-elm|
46. lang#erlang............................|SpaceVim-layers-lang-erlang|
47. lang#extra..............................|SpaceVim-layers-lang-extra|
48. lang#fennel............................|SpaceVim-layers-lang-fennel|
49. lang#forth..............................|SpaceVim-layers-lang-forth|
50. lang#fortran..........................|SpaceVim-layers-lang-fortran|
51. lang#foxpro............................|SpaceVim-layers-lang-foxpro|
52. lang#fsharp............................|SpaceVim-layers-lang-fsharp|
53. lang#go....................................|SpaceVim-layers-lang-go|
54. lang#goby................................|SpaceVim-layers-lang-goby|
55. lang#gosu................................|SpaceVim-layers-lang-gosu|
56. lang#graphql..........................|SpaceVim-layers-lang-graphql|
57. lang#groovy............................|SpaceVim-layers-lang-groovy|
58. lang#hack................................|SpaceVim-layers-lang-hack|
59. lang#haskell..........................|SpaceVim-layers-lang-haskell|
60. lang#haxe................................|SpaceVim-layers-lang-haxe|
61. lang#html................................|SpaceVim-layers-lang-html|
62. lang#hy....................................|SpaceVim-layers-lang-hy|
63. lang#idris..............................|SpaceVim-layers-lang-idris|
64. lang#io....................................|SpaceVim-layers-lang-io|
65. lang#j......................................|SpaceVim-layers-lang-j|
66. lang#janet..............................|SpaceVim-layers-lang-janet|
67. lang#java................................|SpaceVim-layers-lang-java|
68. lang#javascript....................|SpaceVim-layers-lang-javascript|
69. lang#jr....................................|SpaceVim-layers-lang-jr|
70. lang#json................................|SpaceVim-layers-lang-json|
71. lang#julia..............................|SpaceVim-layers-lang-julia|
72. lang#kotlin............................|SpaceVim-layers-lang-kotlin|
73. lang#latex..............................|SpaceVim-layers-lang-latex|
74. lang#lisp................................|SpaceVim-layers-lang-lisp|
75. lang#livescript....................|SpaceVim-layers-lang-livescript|
76. lang#lua..................................|SpaceVim-layers-lang-lua|
77. lang#markdown........................|SpaceVim-layers-lang-markdown|
78. lang#moonscript....................|SpaceVim-layers-lang-moonscript|
79. lang#nim..................................|SpaceVim-layers-lang-nim|
80. lang#nix..................................|SpaceVim-layers-lang-nix|
81. lang#ocaml..............................|SpaceVim-layers-lang-ocaml|
82. lang#octave............................|SpaceVim-layers-lang-octave|
83. lang#pact................................|SpaceVim-layers-lang-pact|
84. lang#pascal............................|SpaceVim-layers-lang-pascal|
85. lang#perl................................|SpaceVim-layers-lang-perl|
86. lang#php..................................|SpaceVim-layers-lang-php|
87. lang#plantuml........................|SpaceVim-layers-lang-plantuml|
88. lang#pony................................|SpaceVim-layers-lang-pony|
89. lang#processing....................|SpaceVim-layers-lang-processing|
90. lang#prolog............................|SpaceVim-layers-lang-prolog|
91. lang#puppet............................|SpaceVim-layers-lang-puppet|
92. lang#purescript....................|SpaceVim-layers-lang-purescript|
93. lang#python............................|SpaceVim-layers-lang-python|
94. lang#racket............................|SpaceVim-layers-lang-racket|
95. lang#racket...............................|SpaceVim-layers-lang-red|
96. lang#reason............................|SpaceVim-layers-lang-reason|
97. lang#ring...................................|SpaceVim-layers-lang-r|
98. lang#ring................................|SpaceVim-layers-lang-ring|
99. lang#ruby................................|SpaceVim-layers-lang-ruby|
100. lang#rust...............................|SpaceVim-layers-lang-rust|
101. lang#scala.............................|SpaceVim-layers-lang-scala|
102. lang#scheme...........................|SpaceVim-layers-lang-scheme|
103. lang#sh...................................|SpaceVim-layers-lang-sh|
104. lang#smalltalk.....................|SpaceVim-layers-lang-smalltalk|
105. lang#sml.................................|SpaceVim-layers-lang-sml|
106. lang#swig..............................|SpaceVim-layers-lang-swift|
107. lang#swig...............................|SpaceVim-layers-lang-swig|
108. lang#tcl.................................|SpaceVim-layers-lang-tcl|
109. lang#teal...............................|SpaceVim-layers-lang-teal|
110. lang#toml...............................|SpaceVim-layers-lang-toml|
111. lang#typescript...................|SpaceVim-layers-lang-typescript|
112. lang#v.....................................|SpaceVim-layers-lang-v|
113. lang#vala...............................|SpaceVim-layers-lang-vala|
114. lang#vbnet.............................|SpaceVim-layers-lang-vbnet|
115. lang#verilog.........................|SpaceVim-layers-lang-verilog|
116. lang#vim.................................|SpaceVim-layers-lang-vim|
117. lang#vue.................................|SpaceVim-layers-lang-vue|
118. lang#wdl.................................|SpaceVim-layers-lang-wdl|
119. lang#wolfram.........................|SpaceVim-layers-lang-wolfram|
120. lang#xml.................................|SpaceVim-layers-lang-xml|
121. lang#xquery...........................|SpaceVim-layers-lang-xquery|
122. lang#zig.................................|SpaceVim-layers-lang-zig|
123. language server protocol......................|SpaceVim-layers-lsp|
124. leaderf...................................|SpaceVim-layers-leaderf|
125. mail.........................................|SpaceVim-layers-mail|
126. operator.................................|SpaceVim-layers-operator|
127. shell.......................................|SpaceVim-layers-shell|
128. ssh...........................................|SpaceVim-layers-ssh|
129. test.........................................|SpaceVim-layers-test|
130. tmux.........................................|SpaceVim-layers-tmux|
131. tools#dash.............................|SpaceVim-layers-tools-dash|
132. tools#mpv...............................|SpaceVim-layers-tools-mpv|
133. tools#zeal.............................|SpaceVim-layers-tools-zeal|
134. treesitter.............................|SpaceVim-layers-treesitter|
135. ui.............................................|SpaceVim-layers-ui|
136. unite.......................................|SpaceVim-layers-unite|
7. Usage....................................................|SpaceVim-usage|
1. alternate file........................|SpaceVim-usage-alternate-file|
2. buffers-and-files..................|SpaceVim-usage-buffers-and-files|
@ -2055,6 +2056,17 @@ KEY BINDINGS
<
==============================================================================
FRAMEWORK#DJANGO *SpaceVim-layers-framework-django*
The `framework#django` layer provides code completion and syntax highlight for
django. This layer is not enabled by default, to enable it:
>
[[layers]]
name = 'framework#django'
<
==============================================================================
FZF *SpaceVim-layers-fzf*