implemented idea from bug #720326.

uses an MD5 hash to determine if any .snippets files have been updated
This commit is contained in:
rygwdn@gmail.com 2011-04-27 22:22:34 -03:00
parent 424b817338
commit db9e0b20a7

View File

@ -7,6 +7,7 @@ import glob
import os import os
import re import re
import string import string
from zlib import crc32
import vim import vim
@ -58,10 +59,15 @@ def feedkeys(s, mode='n'):
"""Wrapper around vim's feedkeys function. Mainly for convenience.""" """Wrapper around vim's feedkeys function. Mainly for convenience."""
vim.command(r'call feedkeys("%s", "%s")' % (s, mode)) vim.command(r'call feedkeys("%s", "%s")' % (s, mode))
def echom(mes, *args):
mes = mes % args
vim.command('echom "%s"' % mes.replace('"', '\\"'))
class _SnippetDictionary(object): class _SnippetDictionary(object):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self._snippets = [] self._snippets = []
self._extends = [] self._extends = []
self._files = {}
def add_snippet(self, s): def add_snippet(self, s):
self._snippets.append(s) self._snippets.append(s)
@ -84,6 +90,37 @@ class _SnippetDictionary(object):
else: else:
self._snippets = [] self._snippets = []
def files(self):
return self._files
files = property(files)
def _hash(self, path):
if not os.path.isfile(path):
return False
#hash = os.stat(path).st_mtime
file = open(path, "rb")
hash = 0
while True:
data = file.read(2048)
if not data:
break
hash = crc32(data, hash)
return hash
def addfile(self, path):
self.files[path] = self._hash(path)
def needs_update(self):
for path, hash in self.files.items():
if not hash or hash != self._hash(path):
return True
return False
def extends(): def extends():
def fget(self): def fget(self):
return self._extends return self._extends
@ -651,14 +688,22 @@ class SnippetManager(object):
if not rv: if not rv:
self._handle_failure(self.expand_trigger) self._handle_failure(self.expand_trigger)
@err_to_scratch_buffer def snippet_dict(self, ft):
def add_snippet(self, trigger, value, descr, options, ft = "all", globals = None):
if ft not in self._snippets: if ft not in self._snippets:
self._snippets[ft] = _SnippetDictionary() self._snippets[ft] = _SnippetDictionary()
l = self._snippets[ft].add_snippet( return self._snippets[ft]
@err_to_scratch_buffer
def add_snippet(self, trigger, value, descr, options, ft = "all", globals = None):
l = self.snippet_dict(ft).add_snippet(
Snippet(trigger, value, descr, options, globals or {}) Snippet(trigger, value, descr, options, globals or {})
) )
@err_to_scratch_buffer
def add_snippet_file(self, ft, path):
sd = self.snippet_dict(ft)
sd.addfile(path)
@err_to_scratch_buffer @err_to_scratch_buffer
def expand_anon(self, value, trigger="", descr="", options="", globals=None): def expand_anon(self, value, trigger="", descr="", options="", globals=None):
if globals is None: if globals is None:
@ -680,9 +725,7 @@ class SnippetManager(object):
@err_to_scratch_buffer @err_to_scratch_buffer
def add_extending_info(self, ft, parents): def add_extending_info(self, ft, parents):
if ft not in self._snippets: sd = self.snippet_dict(ft)
self._snippets[ft] = _SnippetDictionary()
sd = self._snippets[ft]
for p in parents: for p in parents:
if p in sd.extends: if p in sd.extends:
continue continue
@ -869,15 +912,6 @@ class SnippetManager(object):
if feedkey: if feedkey:
feedkeys(feedkey, mode) feedkeys(feedkey, mode)
def _ensure_snippets_loaded(self):
filetypes = self._filetypes()
for ft in filetypes:
if ft not in self._snippets:
self._load_snippets_for(ft)
return filetypes
def _get_before_after(self): def _get_before_after(self):
""" Returns the text before and after the cursor as a """ Returns the text before and after the cursor as a
tuple. tuple.
@ -1065,6 +1099,7 @@ class SnippetManager(object):
_cs = property(_cs) _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)
_SnippetsFileParser(ft, fn, self, file_data).parse() _SnippetsFileParser(ft, fn, self, file_data).parse()
def base_snippet_files_for(self, ft, default=True): def base_snippet_files_for(self, ft, default=True):
@ -1175,6 +1210,48 @@ class SnippetManager(object):
if p not in self._snippets: if p not in self._snippets:
self._load_snippets_for(p) self._load_snippets_for(p)
def _needs_update(self, ft):
if ft not in self._snippets:
return True
elif self.snippet_dict(ft).needs_update():
return True
else:
cur_snips = set(self.base_snippet_files_for(ft))
old_snips = set(self.snippet_dict(ft).files)
if cur_snips - old_snips:
return True
return False
def _ensure_loaded(self, ft, checked=None):
if not checked:
checked = set([ft])
elif ft in checked:
return
else:
checked.add(ft)
if self._needs_update(ft):
self._load_snippets_for(ft)
for parent in self.snippet_dict(ft).extends:
self._ensure_loaded(parent, checked)
def _ensure_snippets_loaded(self):
""" Checks for changes in the list of snippet files or the contents
of the snippet files and reloads them if necessary.
"""
filetypes = self._filetypes()
for ft in filetypes:
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):
""" """
Find snippets matching trigger Find snippets matching trigger