Implemented UltiSnipsAddFiletypes

It makes it possible to add filetypes in ftplugin/ft.vim or manually while editing.
This commit is contained in:
Holger Rapp 2012-04-01 16:42:34 +02:00
parent 9d35d72a25
commit bfce5af642
5 changed files with 84 additions and 47 deletions

View File

@ -179,6 +179,29 @@ g:UltiSnipsSnippetsDir
'filetype' is "cpp", then :UltiSnipsEdit will open
"~/.vim/mydir/UltiSnips/cpp.snippets".
*:UltiSnipsAddFiletypes*
The UltiSnipsAddFiletypes command allows for explicit merging of other snippet
filetypes for the current buffer. For example if you edit a .rst file, but
also want the Lua snippets to be available you can issue the command >
:UltiSnipsAddFiletypes rst.lua
using the dotted filetype syntax. Order is important, the first filetype in
this list will be the one used for UltiSnipsEdit and the list is
ordered by evaluation priority. Consequently, you might add this to your
ftplugin/rails.vim >
:UltiSnipsAddFiletypes rails.ruby
I mention rails first, because I want to edit rails snippet when using
UltiSnipsEdit and because rails snippet should overwrite equivalent ruby
snippets. The priority will now be rails -> ruby -> all. If you have some
special programming snippets that should have lower priority than your ruby
snippets you can call >
:UltiSnipsAddFiletypes ruby.programming
The priority will then be rails -> ruby -> programming -> all.
3.2 Triggers *UltiSnips-triggers*
------------

6
ftdetect/UltiSnips.vim Normal file
View File

@ -0,0 +1,6 @@
" This has to be called before ftplugins are loaded. Therefore
" it is here in ftdetect though it maybe shouldn't
if has("autocmd")
autocmd FileType * call UltiSnips_FileTypeChanged()
endif

View File

@ -82,7 +82,7 @@ function! UltiSnipsEdit(...)
if a:0 == 1 && a:1 != ''
let type = a:1
else
exec g:_uspy "vim.command(\"let type = '%s'\" % UltiSnips_Manager.filetype)"
exec g:_uspy "vim.command(\"let type = '%s'\" % UltiSnips_Manager.primary_filetype)"
endif
exec g:_uspy "vim.command(\"let file = '%s'\" % UltiSnips_Manager.file_to_edit(vim.eval(\"type\")))"
@ -99,6 +99,14 @@ endfunction
" edit snippets, default of current file type or the specified type
command! -nargs=? UltiSnipsEdit :call UltiSnipsEdit(<q-args>)
" Global Commands {{{
function! UltiSnipsAddFiletypes(filetypes)
exec g:_uspy "UltiSnips_Manager.add_buffer_filetypes('" . a:filetypes . ".all')"
return ""
endfunction
command! -nargs=1 UltiSnipsAddFiletypes :call UltiSnipsAddFiletypes(<q-args>)
"" }}}
" FUNCTIONS {{{
@ -145,7 +153,8 @@ function! UltiSnips_JumpForwards()
endfunction
function! UltiSnips_FileTypeChanged()
exec g:_uspy "UltiSnips_Manager.ensure_snippets_loaded()"
exec g:_uspy "UltiSnips_Manager.reset_buffer_filetypes()"
exec g:_uspy "UltiSnips_Manager.add_buffer_filetypes('" . &ft . "')"
return ""
endfunction
@ -173,6 +182,7 @@ endfunction
function! UltiSnips_MapKeys()
" Map the keys correctly
if g:UltiSnipsExpandTrigger == g:UltiSnipsJumpForwardTrigger
exec "inoremap <silent> " . g:UltiSnipsExpandTrigger . " <C-R>=UltiSnips_ExpandSnippetOrJump()<cr>"
exec "snoremap <silent> " . g:UltiSnipsExpandTrigger . " <Esc>:call UltiSnips_ExpandSnippetOrJump()<cr>"
else

View File

@ -2,7 +2,7 @@
# encoding: utf-8
from functools import wraps
from collections import deque
from collections import deque, defaultdict
import glob
import hashlib
import os
@ -55,9 +55,9 @@ class _SnippetDictionary(object):
else:
return [ s for s in self.snippets if s.could_match(trigger) ]
@property
def snippets(self):
return self._added + self._snippets
snippets = property(snippets)
def clear_snippets(self, triggers=[]):
"""Remove all snippets that match each trigger in triggers.
@ -74,9 +74,9 @@ class _SnippetDictionary(object):
self._snippets = []
self._added = []
@property
def files(self):
return self._files
files = property(files)
def reset(self):
self._snippets = []
@ -374,22 +374,22 @@ class Snippet(object):
return match
@property
def overwrites_previous(self):
return "!" in self._opts
overwrites_previous = property(overwrites_previous)
@property
def description(self):
return ("(%s) %s" % (self._t, self._d)).strip()
description = property(description)
@property
def trigger(self):
return self._t
trigger = property(trigger)
@property
def matched(self):
""" The last text that was matched. """
return self._matched
matched = property(matched)
def launch(self, text_before, visual_content, parent, start, end):
indent = self._INDENT.match(text_before).group(0)
@ -516,6 +516,7 @@ class SnippetManager(object):
self._vstate = VimState()
self._test_error = test_error
self._snippets = {}
self._filetypes = defaultdict(lambda: ['all'])
self._visual_content = VisualContentPreserver()
while len(self._csnippets):
@ -780,7 +781,8 @@ class SnippetManager(object):
before the cursor. If possible is True, then get all
possible matches.
"""
filetypes = self.ensure_snippets_loaded()
self._ensure_all_loaded()
filetypes = self._filetypes[_vim.buf.nr][::-1]
found_snippets = []
for ft in filetypes:
@ -869,11 +871,11 @@ class SnippetManager(object):
return True
@property
def _cs(self):
if not len(self._csnippets):
return None
return self._csnippets[-1]
_cs = property(_cs)
def _parse_snippets(self, ft, fn, file_data=None):
self.add_snippet_file(ft, fn)
@ -915,19 +917,15 @@ class SnippetManager(object):
return ret
def _filetypes(self, dotft=None):
if dotft is None:
dotft = _vim.eval("&filetype")
@property
def primary_filetype(self):
""" Property for the primary filetype. This filetype
will be edited when UltiSnipsEdit is called
without any arguments.
"""
return self._filetypes[_vim.buf.nr][0]
fts = dotft.split(".") + [ "all" ]
return [ft for ft in fts[::-1] if ft]
def filetype(self):
""" Property for the current (undotted) filetype. """
return self._filetypes()[-1]
filetype = property(filetype)
def file_to_edit(self, ft=None):
def file_to_edit(self, ft):
""" Gets a file to edit based on the given filetype.
If no filetype is given, uses the current filetype from Vim.
@ -935,9 +933,6 @@ class SnippetManager(object):
If a non-shipped file already exists, it uses it.
Otherwise uses a file in ~/.vim/ or ~/vimfiles
"""
if not ft:
ft = self.filetype
edit = None
existing = self.base_snippet_files_for(ft, False)
filename = ft + ".snippets"
@ -966,21 +961,6 @@ class SnippetManager(object):
return edit
def base_snippet_files(self, dotft=None):
""" Returns a list of all snippet files for the given filetype.
If no filetype is given, uses furrent filetype.
If the filetype is dotted (e.g. 'cuda.cpp.c') then it is split and
each filetype is checked.
"""
ret = []
filetypes = self._filetypes(dotft)
for ft in filetypes:
ret += self.base_snippet_files_for(ft)
return ret
# Loading
def _load_snippets_for(self, ft):
self.snippet_dict(ft).reset()
@ -1027,16 +1007,30 @@ class SnippetManager(object):
self._ensure_loaded(parent, checked)
def ensure_snippets_loaded(self):
def _ensure_all_loaded(self):
for ft in self._filetypes[_vim.buf.nr]:
self._ensure_loaded(ft)
def reset_buffer_filetypes(self):
if _vim.buf.nr in self._filetypes:
del self._filetypes[_vim.buf.nr]
def add_buffer_filetypes(self, ft):
""" Checks for changes in the list of snippet files or the contents
of the snippet files and reloads them if necessary.
"""
filetypes = self._filetypes()
buf_fts = self._filetypes[_vim.buf.nr]
idx = -1
for ft in ft.split("."):
ft = ft.strip()
if not ft: continue
try:
idx = buf_fts.index(ft)
except ValueError:
self._filetypes[_vim.buf.nr].insert(idx + 1, ft)
idx += 1
for ft in filetypes:
self._ensure_loaded(ft)
return filetypes
self._ensure_all_loaded()
def _find_snippets(self, ft, trigger, potentially = False, seen=None):
"""

View File

@ -41,6 +41,10 @@ class VimBuffer(object):
before, after = as_unicode(line[:col]), as_unicode(line[col:])
return before, after
@property
def nr(self):
return int(eval("bufnr('%')"))
def cursor():
"""
The current windows cursor. Note that this is 0 based in col and 0