Disable auto detecting changes to snippet files on expansion (#967)
Instead, trigger an auto command whenever a .snippets file is saved that will reload the snippets. This is a performance improvement with a loss of functionality: externally (i.e. outside of the current Vim instance) generated snippet files will not be picked up until UltiSnips#RefreshSnippets is called. I decided to not expose a command for this, since I assume it is rarely useful. I think the command would add confusion of when it was supposed to be ran. Fixes #932.
This commit is contained in:
parent
9014274598
commit
4eac979888
@ -131,7 +131,6 @@ function! UltiSnips#Anon(value, ...)
|
|||||||
return ""
|
return ""
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
|
||||||
function! UltiSnips#CursorMoved()
|
function! UltiSnips#CursorMoved()
|
||||||
exec g:_uspy "UltiSnips_Manager._cursor_moved()"
|
exec g:_uspy "UltiSnips_Manager._cursor_moved()"
|
||||||
endf
|
endf
|
||||||
@ -147,4 +146,8 @@ endfunction
|
|||||||
function! UltiSnips#TrackChange()
|
function! UltiSnips#TrackChange()
|
||||||
exec g:_uspy "UltiSnips_Manager._track_change()"
|
exec g:_uspy "UltiSnips_Manager._track_change()"
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! UltiSnips#RefreshSnippets()
|
||||||
|
exec g:_uspy "UltiSnips_Manager._refresh_snippets()"
|
||||||
|
endfunction
|
||||||
" }}}
|
" }}}
|
||||||
|
@ -751,8 +751,9 @@ with a backslash, '\'.
|
|||||||
To illustrate plaintext snippets, let's begin with a simple example. You can
|
To illustrate plaintext snippets, let's begin with a simple example. You can
|
||||||
try the examples yourself. Simply edit a new file with Vim. Example snippets
|
try the examples yourself. Simply edit a new file with Vim. Example snippets
|
||||||
will be added to the 'all.snippets' file, so you'll want to open it in Vim for
|
will be added to the 'all.snippets' file, so you'll want to open it in Vim for
|
||||||
editing as well. >
|
editing as well in the same Vim instance. You can use |UltiSnipsEdit| for this,
|
||||||
~/.vim/UltiSnips/all.snippets
|
but you can also just run >
|
||||||
|
:tabedit ~/.vim/UltiSnips/all.snippets
|
||||||
|
|
||||||
Add this snippet to 'all.snippets' and save the file.
|
Add this snippet to 'all.snippets' and save the file.
|
||||||
|
|
||||||
|
@ -17,6 +17,15 @@ setlocal commentstring=#%s
|
|||||||
setlocal noexpandtab
|
setlocal noexpandtab
|
||||||
setlocal autoindent nosmartindent nocindent
|
setlocal autoindent nosmartindent nocindent
|
||||||
|
|
||||||
|
" Whenever a snippets file is written, we ask UltiSnips to reload all snippet
|
||||||
|
" files. This feels like auto-updating, but is of course just an
|
||||||
|
" approximation: If files change outside of the current Vim instance, we will
|
||||||
|
" not notice.
|
||||||
|
augroup ultisnips_snippets.vim
|
||||||
|
autocmd!
|
||||||
|
autocmd BufWritePost <buffer> call UltiSnips#RefreshSnippets()
|
||||||
|
augroup END
|
||||||
|
|
||||||
" Define match words for use with matchit plugin
|
" Define match words for use with matchit plugin
|
||||||
" http://www.vim.org/scripts/script.php?script_id=39
|
" http://www.vim.org/scripts/script.php?script_id=39
|
||||||
if exists("loaded_matchit") && !exists("b:match_words")
|
if exists("loaded_matchit") && !exists("b:match_words")
|
||||||
|
@ -16,16 +16,14 @@ class SnippetSource(object):
|
|||||||
self._snippets = defaultdict(SnippetDictionary)
|
self._snippets = defaultdict(SnippetDictionary)
|
||||||
self._extends = defaultdict(set)
|
self._extends = defaultdict(set)
|
||||||
|
|
||||||
def ensure(self, filetypes, cached):
|
def ensure(self, filetypes):
|
||||||
"""Update/reload the snippets in the source when needed.
|
"""Ensures that snippets are loaded."""
|
||||||
|
|
||||||
It makes sure that the snippets are not outdated.
|
|
||||||
|
|
||||||
|
def refresh(self):
|
||||||
|
"""Resets all snippets, so that they are reloaded on the next call to
|
||||||
|
ensure.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def loaded(self, filetypes):
|
|
||||||
return len(self._snippets) > 0
|
|
||||||
|
|
||||||
def _get_existing_deep_extends(self, base_filetypes):
|
def _get_existing_deep_extends(self, base_filetypes):
|
||||||
"""Helper for get all existing filetypes extended by base filetypes."""
|
"""Helper for get all existing filetypes extended by base filetypes."""
|
||||||
deep_extends = self.get_deep_extends(base_filetypes)
|
deep_extends = self.get_deep_extends(base_filetypes)
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
"""Code to provide access to UltiSnips files from disk."""
|
"""Code to provide access to UltiSnips files from disk."""
|
||||||
|
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
import hashlib
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from UltiSnips import _vim
|
from UltiSnips import _vim
|
||||||
@ -12,13 +11,6 @@ from UltiSnips import compatibility
|
|||||||
from UltiSnips.snippet.source._base import SnippetSource
|
from UltiSnips.snippet.source._base import SnippetSource
|
||||||
|
|
||||||
|
|
||||||
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()
|
|
||||||
|
|
||||||
|
|
||||||
class SnippetSyntaxError(RuntimeError):
|
class SnippetSyntaxError(RuntimeError):
|
||||||
|
|
||||||
"""Thrown when a syntax error is found in a file."""
|
"""Thrown when a syntax error is found in a file."""
|
||||||
@ -29,24 +21,18 @@ class SnippetSyntaxError(RuntimeError):
|
|||||||
|
|
||||||
|
|
||||||
class SnippetFileSource(SnippetSource):
|
class SnippetFileSource(SnippetSource):
|
||||||
|
|
||||||
"""Base class that abstracts away 'extends' info and file hashes."""
|
"""Base class that abstracts away 'extends' info and file hashes."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
SnippetSource.__init__(self)
|
SnippetSource.__init__(self)
|
||||||
self._files_for_ft = defaultdict(set)
|
|
||||||
self._file_hashes = defaultdict(lambda: None)
|
|
||||||
self._ensure_cached = False
|
|
||||||
|
|
||||||
def ensure(self, filetypes, cached):
|
|
||||||
if cached and self._ensure_cached:
|
|
||||||
return
|
|
||||||
|
|
||||||
|
def ensure(self, filetypes):
|
||||||
for ft in self.get_deep_extends(filetypes):
|
for ft in self.get_deep_extends(filetypes):
|
||||||
if self._needs_update(ft):
|
if self._needs_update(ft):
|
||||||
self._load_snippets_for(ft)
|
self._load_snippets_for(ft)
|
||||||
|
|
||||||
self._ensure_cached = True
|
def refresh(self):
|
||||||
|
self.__init__()
|
||||||
|
|
||||||
def _get_all_snippet_files_for(self, ft):
|
def _get_all_snippet_files_for(self, ft):
|
||||||
"""Returns a set of all files that define snippets for 'ft'."""
|
"""Returns a set of all files that define snippets for 'ft'."""
|
||||||
@ -59,38 +45,22 @@ class SnippetFileSource(SnippetSource):
|
|||||||
def _needs_update(self, ft):
|
def _needs_update(self, ft):
|
||||||
"""Returns true if any files for 'ft' have changed and must be
|
"""Returns true if any files for 'ft' have changed and must be
|
||||||
reloaded."""
|
reloaded."""
|
||||||
existing_files = self._get_all_snippet_files_for(ft)
|
return not (ft in self._snippets)
|
||||||
if existing_files != self._files_for_ft[ft]:
|
|
||||||
self._files_for_ft[ft] = existing_files
|
|
||||||
return True
|
|
||||||
|
|
||||||
for filename in self._files_for_ft[ft]:
|
|
||||||
if _hash_file(filename) != self._file_hashes[filename]:
|
|
||||||
return True
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
def _load_snippets_for(self, ft):
|
def _load_snippets_for(self, ft):
|
||||||
"""Load all snippets for the given 'ft'."""
|
"""Load all snippets for the given 'ft'."""
|
||||||
if ft in self._snippets:
|
assert(ft not in self._snippets)
|
||||||
del self._snippets[ft]
|
for fn in self._get_all_snippet_files_for(ft):
|
||||||
del self._extends[ft]
|
|
||||||
try:
|
|
||||||
for fn in self._files_for_ft[ft]:
|
|
||||||
self._parse_snippets(ft, fn)
|
self._parse_snippets(ft, fn)
|
||||||
except:
|
|
||||||
del self._files_for_ft[ft]
|
|
||||||
raise
|
|
||||||
# Now load for the parents
|
# Now load for the parents
|
||||||
for parent_ft in self.get_deep_extends([ft]):
|
for parent_ft in self.get_deep_extends([ft]):
|
||||||
if parent_ft != ft and self._needs_update(parent_ft):
|
if parent_ft != ft and self._needs_update(parent_ft):
|
||||||
self._load_snippets_for(parent_ft)
|
self._load_snippets_for(parent_ft)
|
||||||
|
|
||||||
def _parse_snippets(self, ft, filename):
|
def _parse_snippets(self, ft, filename):
|
||||||
"""Parse the 'filename' for the given 'ft' and watch it for changes in
|
"""Parse the 'filename' for the given 'ft'."""
|
||||||
the future."""
|
|
||||||
self._file_hashes[filename] = _hash_file(filename)
|
|
||||||
file_data = compatibility.open_ascii_file(filename, 'r').read()
|
file_data = compatibility.open_ascii_file(filename, 'r').read()
|
||||||
|
self._snippets[ft] # Make sure the dictionary exists
|
||||||
for event, data in self._parse_snippet_file(file_data, filename):
|
for event, data in self._parse_snippet_file(file_data, filename):
|
||||||
if event == 'error':
|
if event == 'error':
|
||||||
msg, line_index = data
|
msg, line_index = data
|
||||||
|
@ -569,7 +569,7 @@ class SnippetManager(object):
|
|||||||
clear_priority = None
|
clear_priority = None
|
||||||
cleared = {}
|
cleared = {}
|
||||||
for _, source in self._snippet_sources:
|
for _, source in self._snippet_sources:
|
||||||
source.ensure(filetypes, cached=autotrigger_only)
|
source.ensure(filetypes)
|
||||||
|
|
||||||
# Collect cleared information from sources.
|
# Collect cleared information from sources.
|
||||||
for _, source in self._snippet_sources:
|
for _, source in self._snippet_sources:
|
||||||
@ -859,6 +859,10 @@ class SnippetManager(object):
|
|||||||
|
|
||||||
self._should_reset_visual = True
|
self._should_reset_visual = True
|
||||||
|
|
||||||
|
@err_to_scratch_buffer.wrap
|
||||||
|
def _refresh_snippets(self):
|
||||||
|
for _, source in self._snippet_sources:
|
||||||
|
source.refresh()
|
||||||
|
|
||||||
UltiSnips_Manager = SnippetManager( # pylint:disable=invalid-name
|
UltiSnips_Manager = SnippetManager( # pylint:disable=invalid-name
|
||||||
vim.eval('g:UltiSnipsExpandTrigger'),
|
vim.eval('g:UltiSnipsExpandTrigger'),
|
||||||
|
Loading…
Reference in New Issue
Block a user