Moved SnippetsFileParser into a file of its own.
This commit is contained in:
parent
975aca0c8e
commit
3d4e408b32
@ -12,6 +12,7 @@ from UltiSnips._diff import diff, guess_edit
|
|||||||
from UltiSnips.compatibility import as_unicode
|
from UltiSnips.compatibility import as_unicode
|
||||||
from UltiSnips.geometry import Position
|
from UltiSnips.geometry import Position
|
||||||
from UltiSnips.snippet_dictionary import SnippetDictionary
|
from UltiSnips.snippet_dictionary import SnippetDictionary
|
||||||
|
from UltiSnips.snippets_file_parser import SnippetsFileParser
|
||||||
from UltiSnips.text_objects import SnippetInstance
|
from UltiSnips.text_objects import SnippetInstance
|
||||||
from UltiSnips.util import IndentUtil
|
from UltiSnips.util import IndentUtil
|
||||||
from UltiSnips.vim_state import VimState
|
from UltiSnips.vim_state import VimState
|
||||||
@ -159,134 +160,6 @@ Following is the full stack trace:
|
|||||||
_vim.new_scratch_buffer(s)
|
_vim.new_scratch_buffer(s)
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
class _SnippetsFileParser(object):
|
|
||||||
def __init__(self, ft, fn, snip_manager, file_data=None):
|
|
||||||
self._sm = snip_manager
|
|
||||||
self._ft = ft
|
|
||||||
self._fn = fn
|
|
||||||
self._globals = {}
|
|
||||||
if file_data is None:
|
|
||||||
self._lines = open(fn).readlines()
|
|
||||||
else:
|
|
||||||
self._lines = file_data.splitlines(True)
|
|
||||||
|
|
||||||
self._idx = 0
|
|
||||||
|
|
||||||
def _error(self, msg):
|
|
||||||
fn = _vim.eval("""fnamemodify(%s, ":~:.")""" % _vim.escape(self._fn))
|
|
||||||
self._sm._error("%s in %s(%d)" % (msg, fn, self._idx + 1))
|
|
||||||
|
|
||||||
def _line(self):
|
|
||||||
if self._idx < len(self._lines):
|
|
||||||
line = self._lines[self._idx]
|
|
||||||
else:
|
|
||||||
line = ""
|
|
||||||
return line
|
|
||||||
|
|
||||||
def _line_head_tail(self):
|
|
||||||
parts = re.split(r"\s+", self._line().rstrip(), maxsplit=1)
|
|
||||||
parts.append('')
|
|
||||||
return parts[:2]
|
|
||||||
|
|
||||||
def _line_head(self):
|
|
||||||
return self._line_head_tail()[0]
|
|
||||||
|
|
||||||
def _line_tail(self):
|
|
||||||
return self._line_head_tail()[1]
|
|
||||||
|
|
||||||
def _goto_next_line(self):
|
|
||||||
self._idx += 1
|
|
||||||
return self._line()
|
|
||||||
|
|
||||||
def _parse_first(self, line):
|
|
||||||
""" Parses the first line of the snippet definition. Returns the
|
|
||||||
snippet type, trigger, description, and options in a tuple in that
|
|
||||||
order.
|
|
||||||
"""
|
|
||||||
cdescr = ""
|
|
||||||
coptions = ""
|
|
||||||
cs = ""
|
|
||||||
|
|
||||||
# Ensure this is a snippet
|
|
||||||
snip = line.split()[0]
|
|
||||||
|
|
||||||
# Get and strip options if they exist
|
|
||||||
remain = line[len(snip):].strip()
|
|
||||||
words = remain.split()
|
|
||||||
if len(words) > 2:
|
|
||||||
# second to last word ends with a quote
|
|
||||||
if '"' not in words[-1] and words[-2][-1] == '"':
|
|
||||||
coptions = words[-1]
|
|
||||||
remain = remain[:-len(coptions) - 1].rstrip()
|
|
||||||
|
|
||||||
# Get and strip description if it exists
|
|
||||||
remain = remain.strip()
|
|
||||||
if len(remain.split()) > 1 and remain[-1] == '"':
|
|
||||||
left = remain[:-1].rfind('"')
|
|
||||||
if left != -1 and left != 0:
|
|
||||||
cdescr, remain = remain[left:], remain[:left]
|
|
||||||
|
|
||||||
# The rest is the trigger
|
|
||||||
cs = remain.strip()
|
|
||||||
if len(cs.split()) > 1 or "r" in coptions:
|
|
||||||
if cs[0] != cs[-1]:
|
|
||||||
self._error("Invalid multiword trigger: '%s'" % cs)
|
|
||||||
cs = ""
|
|
||||||
else:
|
|
||||||
cs = cs[1:-1]
|
|
||||||
|
|
||||||
return (snip, cs, cdescr, coptions)
|
|
||||||
|
|
||||||
def _parse_snippet(self):
|
|
||||||
line = self._line()
|
|
||||||
|
|
||||||
(snip, trig, desc, opts) = self._parse_first(line)
|
|
||||||
end = "end" + snip
|
|
||||||
cv = ""
|
|
||||||
|
|
||||||
while self._goto_next_line():
|
|
||||||
line = self._line()
|
|
||||||
if line.rstrip() == end:
|
|
||||||
cv = cv[:-1] # Chop the last newline
|
|
||||||
break
|
|
||||||
cv += line
|
|
||||||
else:
|
|
||||||
self._error("Missing 'endsnippet' for %r" % trig)
|
|
||||||
return None
|
|
||||||
|
|
||||||
if not trig:
|
|
||||||
# there was an error
|
|
||||||
return None
|
|
||||||
elif snip == "global":
|
|
||||||
# add snippet contents to file globals
|
|
||||||
if trig not in self._globals:
|
|
||||||
self._globals[trig] = []
|
|
||||||
self._globals[trig].append(cv)
|
|
||||||
elif snip == "snippet":
|
|
||||||
self._sm.add_snippet(trig, cv, desc, opts, self._ft, self._globals, fn=self._fn)
|
|
||||||
else:
|
|
||||||
self._error("Invalid snippet type: '%s'" % snip)
|
|
||||||
|
|
||||||
def parse(self):
|
|
||||||
while self._line():
|
|
||||||
head, tail = self._line_head_tail()
|
|
||||||
if head == "extends":
|
|
||||||
if tail:
|
|
||||||
self._sm.add_extending_info(self._ft,
|
|
||||||
[ p.strip() for p in tail.split(',') ])
|
|
||||||
else:
|
|
||||||
self._error("'extends' without file types")
|
|
||||||
elif head in ("snippet", "global"):
|
|
||||||
self._parse_snippet()
|
|
||||||
elif head == "clearsnippets":
|
|
||||||
self._sm.clear_snippets(tail.split(), self._ft)
|
|
||||||
elif head and not head.startswith('#'):
|
|
||||||
self._error("Invalid line %r" % self._line().rstrip())
|
|
||||||
break
|
|
||||||
self._goto_next_line()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Snippet(object):
|
class Snippet(object):
|
||||||
_INDENT = re.compile(r"^[ \t]*")
|
_INDENT = re.compile(r"^[ \t]*")
|
||||||
_TABS = re.compile(r"^\t*")
|
_TABS = re.compile(r"^\t*")
|
||||||
@ -887,7 +760,7 @@ class SnippetManager(object):
|
|||||||
|
|
||||||
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)
|
||||||
_SnippetsFileParser(ft, fn, self, file_data).parse()
|
SnippetsFileParser(ft, fn, self, file_data).parse()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def primary_filetype(self):
|
def primary_filetype(self):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user