Added support for extends keyword. With this it is simple to make inheritance trees of snippets for file types

This commit is contained in:
Holger Rapp 2009-08-02 11:57:43 +02:00
parent 1236d0ab86
commit 43e60ebd57
4 changed files with 49 additions and 31 deletions

View File

@ -1,3 +1,6 @@
- extends keyword is now supported on the first line of snippet files. This makes it easy to
define special cases, for example cpp extends c: a cpp trigger is useless
in c, but a c trigger is valuable for cpp.
- UltiSnips now adheres to expandtab and tabstop options of vim
version 1.1:

View File

@ -1,3 +1,4 @@
extends c
###########################################################################
# TextMate Snippets #

View File

@ -145,6 +145,13 @@ CUDA files, i keep the file type set to ":set ft=cpp.c" or ":set
ft=cuda.cpp.c". This activates all snippets for each file type in the order
specified.
As an alternative, the first line of each snippet file can look like this: >
extends ft1, ft2, ft3
For example, the first line in cpp.snippets looks like this: >
extends c
This means, first check all triggers for c, then add the triggers from this
file. This is a convenient way to add more special cases to more general ones.
The snippets file format is simple. A line starting with # is a comment, each
snippet starts with a line in the form of: >
snippet tab_trigger [ "description" [ options ] ]

View File

@ -11,6 +11,20 @@ from UltiSnips.Geometry import Position
from UltiSnips.TextObjects import *
from UltiSnips.Buffer import VimBuffer
class _SnippetDictionary(dict):
def __init__(self, *args, **kwargs):
dict.__init__(self, *args, **kwargs)
self._extends = []
def extends():
def fget(self):
return self._extends
def fset(self, value):
self._extends = value
return locals()
extends = property(**extends())
class _SnippetsFileParser(object):
def __init__(self, ft, fn, snip_manager):
self._sm = snip_manager
@ -45,6 +59,10 @@ class _SnippetsFileParser(object):
self._idx += 1
def parse(self):
if self._lines[0].startswith("extends"):
self._sm.add_extending_info(self._ft,
[ p.strip() for p in self._lines[0][7:].split(',') ])
while self._idx < len(self._lines):
line = self._lines[self._idx]
@ -253,11 +271,21 @@ class SnippetManager(object):
def add_snippet(self, trigger, value, descr, options, ft = "all"):
if ft not in self._snippets:
self._snippets[ft] = {}
self._snippets[ft] = _SnippetDictionary()
l = self._snippets[ft].get(trigger,[])
l.append(Snippet(trigger, value, descr, options))
self._snippets[ft][trigger] = l
def add_extending_info(self, ft, parents):
if ft not in self._snippets:
self._snippets[ft] = _SnippetDictionary()
sd = self._snippets[ft]
for p in parents:
if p in sd.extends:
continue
sd.extends.append(p)
def backspace_while_selected(self):
"""
@ -535,36 +563,8 @@ class SnippetManager(object):
_cs = property(_cs)
# Loading
def _load_snippets_from(self, ft, fn):
cs = None
cv = ""
cdescr = ""
coptions = ""
for line in open(fn):
if cs is None and line.startswith("#"):
continue
if line.startswith("snippet"):
cs = line.split()[1]
left = line.find('"')
if left != -1:
right = line.rfind('"')
cdescr = line[left+1:right]
coptions = line[right:].strip()
continue
if cs != None:
if line.startswith("endsnippet"):
cv = cv[:-1] # Chop the last newline
l = self._snippets[ft].get(cs,[])
l.append(Snippet(cs,cv,cdescr,coptions))
self._snippets[ft][cs] = l
cv = cdescr = coptions = ""
cs = None
continue
else:
cv += line
def _load_snippets_for(self, ft):
self._snippets[ft] = {}
self._snippets[ft] = _SnippetDictionary()
for p in vim.eval("&runtimepath").split(',')[::-1]:
pattern = p + os.path.sep + "UltiSnips" + os.path.sep + \
"*%s.snippets" % ft
@ -572,13 +572,20 @@ class SnippetManager(object):
for fn in glob.glob(pattern):
_SnippetsFileParser(ft, fn, self).parse()
# Now load for the parents
for p in self._snippets[ft].extends:
if p not in self._snippets:
self._load_snippets_for(p)
def _find_snippets(self, ft, trigger):
snips = self._snippets.get(ft,None)
if not snips:
return []
return snips.get(trigger, [])
parent_results = reduce( lambda a,b: a+b,
[ self._find_snippets(p, trigger) for p in snips.extends ], [])
return parent_results + snips.get(trigger, [])
UltiSnips_Manager = SnippetManager()