Some minor refactorings.
This commit is contained in:
parent
69659023fb
commit
daf778f59c
@ -16,6 +16,93 @@ from UltiSnips.text_objects import SnippetInstance
|
|||||||
from UltiSnips.util import IndentUtil
|
from UltiSnips.util import IndentUtil
|
||||||
import UltiSnips._vim as _vim
|
import UltiSnips._vim as _vim
|
||||||
|
|
||||||
|
def _ask_snippets(snippets):
|
||||||
|
""" Given a list of snippets, ask the user which one they
|
||||||
|
want to use, and return it.
|
||||||
|
"""
|
||||||
|
display = [ as_unicode("%i: %s") % (i+1,s.description) for i,s in enumerate(snippets)]
|
||||||
|
try:
|
||||||
|
rv = _vim.eval("inputlist(%s)" % _vim.escape(display))
|
||||||
|
if rv is None or rv == '0':
|
||||||
|
return None
|
||||||
|
rv = int(rv)
|
||||||
|
if rv > len(snippets):
|
||||||
|
rv = len(snippets)
|
||||||
|
return snippets[rv-1]
|
||||||
|
except _vim.error as e:
|
||||||
|
# Likely "invalid expression", but might be translated. We have no way
|
||||||
|
# of knowing the exact error, therefore, we ignore all errors silently.
|
||||||
|
return None
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _base_snippet_files_for(ft, default=True):
|
||||||
|
""" Returns a list of snippet files matching the given filetype (ft).
|
||||||
|
If default is set to false, it doesn't include shipped files.
|
||||||
|
|
||||||
|
Searches through each path in 'runtimepath' in reverse order,
|
||||||
|
in each of these, it searches each directory name listed in
|
||||||
|
'g:UltiSnipsSnippetDirectories' in order, then looks for files in these
|
||||||
|
directories called 'ft.snippets' or '*_ft.snippets' replacing ft with
|
||||||
|
the filetype.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if _vim.eval("exists('b:UltiSnipsSnippetDirectories')") == "1":
|
||||||
|
snippet_dirs = _vim.eval("b:UltiSnipsSnippetDirectories")
|
||||||
|
else:
|
||||||
|
snippet_dirs = _vim.eval("g:UltiSnipsSnippetDirectories")
|
||||||
|
base_snippets = os.path.realpath(os.path.join(__file__, "../../../UltiSnips"))
|
||||||
|
ret = []
|
||||||
|
|
||||||
|
paths = _vim.eval("&runtimepath").split(',')
|
||||||
|
|
||||||
|
if _should_reverse_search_path():
|
||||||
|
paths = paths[::-1]
|
||||||
|
|
||||||
|
for rtp in paths:
|
||||||
|
for snippet_dir in snippet_dirs:
|
||||||
|
pth = os.path.realpath(os.path.expanduser(os.path.join(rtp, snippet_dir)))
|
||||||
|
|
||||||
|
patterns = ["%s.snippets", "%s_*.snippets", os.path.join("%s","*")]
|
||||||
|
if not default and pth == base_snippets:
|
||||||
|
patterns.remove("%s.snippets")
|
||||||
|
|
||||||
|
for pattern in patterns:
|
||||||
|
for fn in glob.glob(os.path.join(pth, pattern % ft)):
|
||||||
|
if fn not in ret:
|
||||||
|
ret.append(fn)
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
def _words_for_line(trigger, before, num_words=None):
|
||||||
|
""" Gets the final 'num_words' words from 'before'.
|
||||||
|
If num_words is None, then use the number of words in
|
||||||
|
'trigger'.
|
||||||
|
"""
|
||||||
|
words = ''
|
||||||
|
if not len(before):
|
||||||
|
return ''
|
||||||
|
|
||||||
|
if num_words is None:
|
||||||
|
num_words = len(trigger.split())
|
||||||
|
|
||||||
|
word_list = before.split()
|
||||||
|
if len(word_list) <= num_words:
|
||||||
|
return before.strip()
|
||||||
|
else:
|
||||||
|
before_words = before
|
||||||
|
for i in range(-1, -(num_words + 1), -1):
|
||||||
|
left = before_words.rfind(word_list[i])
|
||||||
|
before_words = before_words[:left]
|
||||||
|
return before[len(before_words):].strip()
|
||||||
|
|
||||||
|
def _hash_file(path):
|
||||||
|
"""Returns a hashdigest of 'path'"""
|
||||||
|
if not os.path.isfile(path):
|
||||||
|
return False
|
||||||
|
return hashlib.sha1(open(path, "rb").read()).hexdigest()
|
||||||
|
|
||||||
def _plugin_dir():
|
def _plugin_dir():
|
||||||
""" Calculates the plugin directory for UltiSnips. This depends on the
|
""" Calculates the plugin directory for UltiSnips. This depends on the
|
||||||
current file being 3 levels deep from the plugin directory, so it needs to
|
current file being 3 levels deep from the plugin directory, so it needs to
|
||||||
@ -125,20 +212,12 @@ class _SnippetDictionary(object):
|
|||||||
self._extends = []
|
self._extends = []
|
||||||
self._files = {}
|
self._files = {}
|
||||||
|
|
||||||
|
|
||||||
def _hash(self, path):
|
|
||||||
if not os.path.isfile(path):
|
|
||||||
return False
|
|
||||||
|
|
||||||
return hashlib.sha1(open(path, "rb").read()).hexdigest()
|
|
||||||
|
|
||||||
|
|
||||||
def addfile(self, path):
|
def addfile(self, path):
|
||||||
self.files[path] = self._hash(path)
|
self.files[path] = _hash_file(path)
|
||||||
|
|
||||||
def needs_update(self):
|
def needs_update(self):
|
||||||
for path, hash in self.files.items():
|
for path, hash in self.files.items():
|
||||||
if not hash or hash != self._hash(path):
|
if not hash or hash != _hash_file(path):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -292,29 +371,7 @@ class Snippet(object):
|
|||||||
self._globals = globals
|
self._globals = globals
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "Snippet(%s,%s,%s)" % (self._t,self._d,self._opts)
|
return "Snippet(%s,%s,%s)" % (self._t, self._d, self._opts)
|
||||||
|
|
||||||
def _words_for_line(self, before, num_words=None):
|
|
||||||
""" Gets the final num_words words from before.
|
|
||||||
If num_words is None, then use the number of words in
|
|
||||||
the trigger.
|
|
||||||
"""
|
|
||||||
words = ''
|
|
||||||
if not len(before):
|
|
||||||
return ''
|
|
||||||
|
|
||||||
if num_words is None:
|
|
||||||
num_words = len(self._t.split())
|
|
||||||
|
|
||||||
word_list = before.split()
|
|
||||||
if len(word_list) <= num_words:
|
|
||||||
return before.strip()
|
|
||||||
else:
|
|
||||||
before_words = before
|
|
||||||
for i in range(-1, -(num_words + 1), -1):
|
|
||||||
left = before_words.rfind(word_list[i])
|
|
||||||
before_words = before_words[:left]
|
|
||||||
return before[len(before_words):].strip()
|
|
||||||
|
|
||||||
def _re_match(self, trigger):
|
def _re_match(self, trigger):
|
||||||
""" Test if a the current regex trigger matches
|
""" Test if a the current regex trigger matches
|
||||||
@ -345,7 +402,7 @@ class Snippet(object):
|
|||||||
if trigger and trigger.rstrip() != trigger:
|
if trigger and trigger.rstrip() != trigger:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
words = self._words_for_line(trigger)
|
words = _words_for_line(self._t, trigger)
|
||||||
|
|
||||||
if "r" in self._opts:
|
if "r" in self._opts:
|
||||||
match = self._re_match(trigger)
|
match = self._re_match(trigger)
|
||||||
@ -386,7 +443,7 @@ class Snippet(object):
|
|||||||
if trigger and trigger.rstrip() is not trigger:
|
if trigger and trigger.rstrip() is not trigger:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
words = self._words_for_line(trigger)
|
words = _words_for_line(self._t, trigger)
|
||||||
|
|
||||||
if "r" in self._opts:
|
if "r" in self._opts:
|
||||||
# Test for full match only
|
# Test for full match only
|
||||||
@ -490,7 +547,6 @@ class VisualContentPreserver(object):
|
|||||||
for cl in range(sl,el-1):
|
for cl in range(sl,el-1):
|
||||||
text += _vim_line_with_eol(cl)
|
text += _vim_line_with_eol(cl)
|
||||||
text += _vim_line_with_eol(el-1)[:ec+1]
|
text += _vim_line_with_eol(el-1)[:ec+1]
|
||||||
|
|
||||||
self._text = text
|
self._text = text
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -511,6 +567,7 @@ class _VimPosition(Position):
|
|||||||
@property
|
@property
|
||||||
def mode(self):
|
def mode(self):
|
||||||
return self._mode
|
return self._mode
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def visualmode(self):
|
def visualmode(self):
|
||||||
return self._visualmode
|
return self._visualmode
|
||||||
@ -540,9 +597,11 @@ class VimState(object):
|
|||||||
@property
|
@property
|
||||||
def pos(self):
|
def pos(self):
|
||||||
return self._poss[-1]
|
return self._poss[-1]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ppos(self):
|
def ppos(self):
|
||||||
return self._poss[-2]
|
return self._poss[-2]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def remembered_buffer(self):
|
def remembered_buffer(self):
|
||||||
return self._lvb[:]
|
return self._lvb[:]
|
||||||
@ -559,7 +618,6 @@ class SnippetManager(object):
|
|||||||
|
|
||||||
self.reset()
|
self.reset()
|
||||||
|
|
||||||
|
|
||||||
@err_to_scratch_buffer
|
@err_to_scratch_buffer
|
||||||
def reset(self, test_error=False):
|
def reset(self, test_error=False):
|
||||||
self._vstate = VimState()
|
self._vstate = VimState()
|
||||||
@ -631,7 +689,7 @@ class SnippetManager(object):
|
|||||||
if not snippets:
|
if not snippets:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
snippet = self._ask_snippets(snippets)
|
snippet = _ask_snippets(snippets)
|
||||||
if not snippet:
|
if not snippet:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@ -639,7 +697,6 @@ class SnippetManager(object):
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
@err_to_scratch_buffer
|
@err_to_scratch_buffer
|
||||||
def expand_or_jump(self):
|
def expand_or_jump(self):
|
||||||
"""
|
"""
|
||||||
@ -768,7 +825,6 @@ class SnippetManager(object):
|
|||||||
self._csnippets[0].update_textobjects()
|
self._csnippets[0].update_textobjects()
|
||||||
self._vstate.remember_buffer(self._csnippets[0])
|
self._vstate.remember_buffer(self._csnippets[0])
|
||||||
|
|
||||||
|
|
||||||
def leaving_buffer(self):
|
def leaving_buffer(self):
|
||||||
"""
|
"""
|
||||||
Called when the user switches tabs/windows/buffers. It basically means
|
Called when the user switches tabs/windows/buffers. It basically means
|
||||||
@ -920,28 +976,6 @@ class SnippetManager(object):
|
|||||||
|
|
||||||
return snippets
|
return snippets
|
||||||
|
|
||||||
def _ask_snippets(self, snippets):
|
|
||||||
""" Given a list of snippets, ask the user which one they
|
|
||||||
want to use, and return it.
|
|
||||||
"""
|
|
||||||
# make a python list
|
|
||||||
display = [ as_unicode("%i: %s") % (i+1,s.description) for i,s in enumerate(snippets)]
|
|
||||||
|
|
||||||
try:
|
|
||||||
rv = _vim.eval("inputlist(%s)" % _vim.escape(display))
|
|
||||||
if rv is None or rv == '0':
|
|
||||||
return None
|
|
||||||
rv = int(rv)
|
|
||||||
if rv > len(snippets):
|
|
||||||
rv = len(snippets)
|
|
||||||
return snippets[rv-1]
|
|
||||||
except _vim.error as e:
|
|
||||||
# Likely "invalid expression", but might be translated. We have no way
|
|
||||||
# of knowing the exact error, therefore, we ignore all errors silently.
|
|
||||||
return None
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _do_snippet(self, snippet, before, after):
|
def _do_snippet(self, snippet, before, after):
|
||||||
""" Expands the given snippet, and handles everything
|
""" Expands the given snippet, and handles everything
|
||||||
that needs to be done with it.
|
that needs to be done with it.
|
||||||
@ -988,19 +1022,16 @@ class SnippetManager(object):
|
|||||||
if not before:
|
if not before:
|
||||||
return False
|
return False
|
||||||
snippets = self._snips(before, False)
|
snippets = self._snips(before, False)
|
||||||
|
|
||||||
if not snippets:
|
if not snippets:
|
||||||
# No snippet found
|
# No snippet found
|
||||||
return False
|
return False
|
||||||
elif len(snippets) == 1:
|
elif len(snippets) == 1:
|
||||||
snippet = snippets[0]
|
snippet = snippets[0]
|
||||||
else:
|
else:
|
||||||
snippet = self._ask_snippets(snippets)
|
snippet = _ask_snippets(snippets)
|
||||||
if not snippet:
|
if not snippet:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
self._do_snippet(snippet, before, after)
|
self._do_snippet(snippet, before, after)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -1013,44 +1044,6 @@ class SnippetManager(object):
|
|||||||
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()
|
||||||
|
|
||||||
def base_snippet_files_for(self, ft, default=True):
|
|
||||||
""" Returns a list of snippet files matching the given filetype (ft).
|
|
||||||
If default is set to false, it doesn't include shipped files.
|
|
||||||
|
|
||||||
Searches through each path in 'runtimepath' in reverse order,
|
|
||||||
in each of these, it searches each directory name listed in
|
|
||||||
'g:UltiSnipsSnippetDirectories' in order, then looks for files in these
|
|
||||||
directories called 'ft.snippets' or '*_ft.snippets' replacing ft with
|
|
||||||
the filetype.
|
|
||||||
"""
|
|
||||||
|
|
||||||
if _vim.eval("exists('b:UltiSnipsSnippetDirectories')") == "1":
|
|
||||||
snippet_dirs = _vim.eval("b:UltiSnipsSnippetDirectories")
|
|
||||||
else:
|
|
||||||
snippet_dirs = _vim.eval("g:UltiSnipsSnippetDirectories")
|
|
||||||
base_snippets = os.path.realpath(os.path.join(__file__, "../../../UltiSnips"))
|
|
||||||
ret = []
|
|
||||||
|
|
||||||
paths = _vim.eval("&runtimepath").split(',')
|
|
||||||
|
|
||||||
if _should_reverse_search_path():
|
|
||||||
paths = paths[::-1]
|
|
||||||
|
|
||||||
for rtp in paths:
|
|
||||||
for snippet_dir in snippet_dirs:
|
|
||||||
pth = os.path.realpath(os.path.expanduser(os.path.join(rtp, snippet_dir)))
|
|
||||||
|
|
||||||
patterns = ["%s.snippets", "%s_*.snippets", os.path.join("%s","*")]
|
|
||||||
if not default and pth == base_snippets:
|
|
||||||
patterns.remove("%s.snippets")
|
|
||||||
|
|
||||||
for pattern in patterns:
|
|
||||||
for fn in glob.glob(os.path.join(pth, pattern % ft)):
|
|
||||||
if fn not in ret:
|
|
||||||
ret.append(fn)
|
|
||||||
|
|
||||||
return ret
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def primary_filetype(self):
|
def primary_filetype(self):
|
||||||
""" Property for the primary filetype. This filetype
|
""" Property for the primary filetype. This filetype
|
||||||
@ -1067,8 +1060,10 @@ 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
|
||||||
"""
|
"""
|
||||||
|
# This method is not using self, but is called by UltiSnips.vim and is
|
||||||
|
# therefore in this class because it is the facade to Vim.
|
||||||
edit = None
|
edit = None
|
||||||
existing = self.base_snippet_files_for(ft, False)
|
existing = _base_snippet_files_for(ft, False)
|
||||||
filename = ft + ".snippets"
|
filename = ft + ".snippets"
|
||||||
|
|
||||||
if _vim.eval("exists('g:UltiSnipsSnippetsDir')") == "1":
|
if _vim.eval("exists('g:UltiSnipsSnippetsDir')") == "1":
|
||||||
@ -1099,7 +1094,7 @@ class SnippetManager(object):
|
|||||||
def _load_snippets_for(self, ft):
|
def _load_snippets_for(self, ft):
|
||||||
self.snippet_dict(ft).reset()
|
self.snippet_dict(ft).reset()
|
||||||
|
|
||||||
for fn in self.base_snippet_files_for(ft):
|
for fn in _base_snippet_files_for(ft):
|
||||||
self._parse_snippets(ft, fn)
|
self._parse_snippets(ft, fn)
|
||||||
|
|
||||||
# Now load for the parents
|
# Now load for the parents
|
||||||
@ -1107,7 +1102,6 @@ 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):
|
def _needs_update(self, ft):
|
||||||
do_hash = _vim.eval('exists("g:UltiSnipsDoHash")') == "0" \
|
do_hash = _vim.eval('exists("g:UltiSnipsDoHash")') == "0" \
|
||||||
or _vim.eval("g:UltiSnipsDoHash") != "0"
|
or _vim.eval("g:UltiSnipsDoHash") != "0"
|
||||||
@ -1117,7 +1111,7 @@ class SnippetManager(object):
|
|||||||
elif do_hash and self.snippet_dict(ft).needs_update():
|
elif do_hash and self.snippet_dict(ft).needs_update():
|
||||||
return True
|
return True
|
||||||
elif do_hash:
|
elif do_hash:
|
||||||
cur_snips = set(self.base_snippet_files_for(ft))
|
cur_snips = set(_base_snippet_files_for(ft))
|
||||||
old_snips = set(self.snippet_dict(ft).files)
|
old_snips = set(self.snippet_dict(ft).files)
|
||||||
|
|
||||||
if cur_snips - old_snips:
|
if cur_snips - old_snips:
|
||||||
@ -1125,7 +1119,6 @@ class SnippetManager(object):
|
|||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def _ensure_loaded(self, ft, checked=None):
|
def _ensure_loaded(self, ft, checked=None):
|
||||||
if not checked:
|
if not checked:
|
||||||
checked = set([ft])
|
checked = set([ft])
|
||||||
@ -1140,7 +1133,6 @@ class SnippetManager(object):
|
|||||||
for parent in self.snippet_dict(ft).extends:
|
for parent in self.snippet_dict(ft).extends:
|
||||||
self._ensure_loaded(parent, checked)
|
self._ensure_loaded(parent, checked)
|
||||||
|
|
||||||
|
|
||||||
def _ensure_all_loaded(self):
|
def _ensure_all_loaded(self):
|
||||||
for ft in self._filetypes[_vim.buf.nr]:
|
for ft in self._filetypes[_vim.buf.nr]:
|
||||||
self._ensure_loaded(ft)
|
self._ensure_loaded(ft)
|
||||||
@ -1163,7 +1155,6 @@ class SnippetManager(object):
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
self._filetypes[_vim.buf.nr].insert(idx + 1, ft)
|
self._filetypes[_vim.buf.nr].insert(idx + 1, ft)
|
||||||
idx += 1
|
idx += 1
|
||||||
|
|
||||||
self._ensure_all_loaded()
|
self._ensure_all_loaded()
|
||||||
|
|
||||||
def _find_snippets(self, ft, trigger, potentially = False, seen=None):
|
def _find_snippets(self, ft, trigger, potentially = False, seen=None):
|
||||||
@ -1178,19 +1169,15 @@ class SnippetManager(object):
|
|||||||
snips = self._snippets.get(ft,None)
|
snips = self._snippets.get(ft,None)
|
||||||
if not snips:
|
if not snips:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
if not seen:
|
if not seen:
|
||||||
seen = []
|
seen = []
|
||||||
seen.append(ft)
|
seen.append(ft)
|
||||||
|
|
||||||
parent_results = []
|
parent_results = []
|
||||||
|
|
||||||
for p in snips.extends:
|
for p in snips.extends:
|
||||||
if p not in seen:
|
if p not in seen:
|
||||||
seen.append(p)
|
seen.append(p)
|
||||||
parent_results += self._find_snippets(p, trigger,
|
parent_results += self._find_snippets(p, trigger,
|
||||||
potentially, seen)
|
potentially, seen)
|
||||||
|
|
||||||
return parent_results + snips.get_matching_snippets(
|
return parent_results + snips.get_matching_snippets(
|
||||||
trigger, potentially)
|
trigger, potentially)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user