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 'filetype' is "cpp", then :UltiSnipsEdit will open
"~/.vim/mydir/UltiSnips/cpp.snippets". "~/.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* 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 != '' if a:0 == 1 && a:1 != ''
let type = a:1 let type = a:1
else 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 endif
exec g:_uspy "vim.command(\"let file = '%s'\" % UltiSnips_Manager.file_to_edit(vim.eval(\"type\")))" 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 " edit snippets, default of current file type or the specified type
command! -nargs=? UltiSnipsEdit :call UltiSnipsEdit(<q-args>) 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 {{{ " FUNCTIONS {{{
@ -145,7 +153,8 @@ function! UltiSnips_JumpForwards()
endfunction endfunction
function! UltiSnips_FileTypeChanged() 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 "" return ""
endfunction endfunction
@ -173,6 +182,7 @@ endfunction
function! UltiSnips_MapKeys() function! UltiSnips_MapKeys()
" Map the keys correctly " Map the keys correctly
if g:UltiSnipsExpandTrigger == g:UltiSnipsJumpForwardTrigger if g:UltiSnipsExpandTrigger == g:UltiSnipsJumpForwardTrigger
exec "inoremap <silent> " . g:UltiSnipsExpandTrigger . " <C-R>=UltiSnips_ExpandSnippetOrJump()<cr>" exec "inoremap <silent> " . g:UltiSnipsExpandTrigger . " <C-R>=UltiSnips_ExpandSnippetOrJump()<cr>"
exec "snoremap <silent> " . g:UltiSnipsExpandTrigger . " <Esc>:call UltiSnips_ExpandSnippetOrJump()<cr>" exec "snoremap <silent> " . g:UltiSnipsExpandTrigger . " <Esc>:call UltiSnips_ExpandSnippetOrJump()<cr>"
else else

View File

@ -2,7 +2,7 @@
# encoding: utf-8 # encoding: utf-8
from functools import wraps from functools import wraps
from collections import deque from collections import deque, defaultdict
import glob import glob
import hashlib import hashlib
import os import os
@ -55,9 +55,9 @@ class _SnippetDictionary(object):
else: else:
return [ s for s in self.snippets if s.could_match(trigger) ] return [ s for s in self.snippets if s.could_match(trigger) ]
@property
def snippets(self): def snippets(self):
return self._added + self._snippets return self._added + self._snippets
snippets = property(snippets)
def clear_snippets(self, triggers=[]): def clear_snippets(self, triggers=[]):
"""Remove all snippets that match each trigger in triggers. """Remove all snippets that match each trigger in triggers.
@ -74,9 +74,9 @@ class _SnippetDictionary(object):
self._snippets = [] self._snippets = []
self._added = [] self._added = []
@property
def files(self): def files(self):
return self._files return self._files
files = property(files)
def reset(self): def reset(self):
self._snippets = [] self._snippets = []
@ -374,22 +374,22 @@ class Snippet(object):
return match return match
@property
def overwrites_previous(self): def overwrites_previous(self):
return "!" in self._opts return "!" in self._opts
overwrites_previous = property(overwrites_previous)
@property
def description(self): def description(self):
return ("(%s) %s" % (self._t, self._d)).strip() return ("(%s) %s" % (self._t, self._d)).strip()
description = property(description)
@property
def trigger(self): def trigger(self):
return self._t return self._t
trigger = property(trigger)
@property
def matched(self): def matched(self):
""" The last text that was matched. """ """ The last text that was matched. """
return self._matched return self._matched
matched = property(matched)
def launch(self, text_before, visual_content, parent, start, end): def launch(self, text_before, visual_content, parent, start, end):
indent = self._INDENT.match(text_before).group(0) indent = self._INDENT.match(text_before).group(0)
@ -516,6 +516,7 @@ class SnippetManager(object):
self._vstate = VimState() self._vstate = VimState()
self._test_error = test_error self._test_error = test_error
self._snippets = {} self._snippets = {}
self._filetypes = defaultdict(lambda: ['all'])
self._visual_content = VisualContentPreserver() self._visual_content = VisualContentPreserver()
while len(self._csnippets): while len(self._csnippets):
@ -780,7 +781,8 @@ class SnippetManager(object):
before the cursor. If possible is True, then get all before the cursor. If possible is True, then get all
possible matches. possible matches.
""" """
filetypes = self.ensure_snippets_loaded() self._ensure_all_loaded()
filetypes = self._filetypes[_vim.buf.nr][::-1]
found_snippets = [] found_snippets = []
for ft in filetypes: for ft in filetypes:
@ -869,11 +871,11 @@ class SnippetManager(object):
return True return True
@property
def _cs(self): def _cs(self):
if not len(self._csnippets): if not len(self._csnippets):
return None return None
return self._csnippets[-1] return self._csnippets[-1]
_cs = property(_cs)
def _parse_snippets(self, ft, fn, file_data=None): def _parse_snippets(self, ft, fn, file_data=None):
self.add_snippet_file(ft, fn) self.add_snippet_file(ft, fn)
@ -915,19 +917,15 @@ class SnippetManager(object):
return ret return ret
def _filetypes(self, dotft=None): @property
if dotft is None: def primary_filetype(self):
dotft = _vim.eval("&filetype") """ 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" ] def file_to_edit(self, ft):
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):
""" Gets a file to edit based on the given filetype. """ Gets a file to edit based on the given filetype.
If no filetype is given, uses the current filetype from Vim. 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. If a non-shipped file already exists, it uses it.
Otherwise uses a file in ~/.vim/ or ~/vimfiles Otherwise uses a file in ~/.vim/ or ~/vimfiles
""" """
if not ft:
ft = self.filetype
edit = None edit = None
existing = self.base_snippet_files_for(ft, False) existing = self.base_snippet_files_for(ft, False)
filename = ft + ".snippets" filename = ft + ".snippets"
@ -966,21 +961,6 @@ class SnippetManager(object):
return edit 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 # Loading
def _load_snippets_for(self, ft): def _load_snippets_for(self, ft):
self.snippet_dict(ft).reset() self.snippet_dict(ft).reset()
@ -1027,16 +1007,30 @@ class SnippetManager(object):
self._ensure_loaded(parent, checked) 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 """ Checks for changes in the list of snippet files or the contents
of the snippet files and reloads them if necessary. 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_all_loaded()
self._ensure_loaded(ft)
return filetypes
def _find_snippets(self, ft, trigger, potentially = False, seen=None): 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:]) before, after = as_unicode(line[:col]), as_unicode(line[col:])
return before, after return before, after
@property
def nr(self):
return int(eval("bufnr('%')"))
def cursor(): def cursor():
""" """
The current windows cursor. Note that this is 0 based in col and 0 The current windows cursor. Note that this is 0 based in col and 0