diff --git a/plugin/UltiSnips.vim b/plugin/UltiSnips.vim index 34a73e7..b64d03b 100644 --- a/plugin/UltiSnips.vim +++ b/plugin/UltiSnips.vim @@ -37,6 +37,16 @@ if !exists("g:UltiSnipsJumpBackwardTrigger") let g:UltiSnipsJumpBackwardTrigger = "" endif +" Should UltiSnips unmap select mode mappings automagically? +if !exists("g:UltiSnipsRemoveSelectModeMappings") + let g:UltiSnipsRemoveSelectModeMappings = 1 +end + +" If UltiSnips should remove Mappings, which should be ignored +if !exists("g:UltiSnipsMappingsToIgnore") + let g:UltiSnipsMappingsToIgnore = [] +endif + " }}} "" FUNCTIONS {{{ diff --git a/plugin/UltiSnips/__init__.py b/plugin/UltiSnips/__init__.py index d158860..3a247dd 100644 --- a/plugin/UltiSnips/__init__.py +++ b/plugin/UltiSnips/__init__.py @@ -405,7 +405,6 @@ class LangMapTranslator(object): return s.translate(self._maps[langmap]) - class VimState(object): def __init__(self): self._abs_pos = None @@ -454,6 +453,8 @@ class VimState(object): self._cline = vim.current.buffer[line] def select_span(self, r): + self._unmap_select_mode_mapping() + delta = r.end - r.start lineno, col = r.start.line, r.start.col @@ -534,6 +535,60 @@ class VimState(object): return self._lline last_line = property(last_line) + ########################### + # Private functions below # + ########################### + def _unmap_select_mode_mapping(self): + """This function unmaps select mode mappings if so wished by the user. + Removes select mode mappings that can actually be typed by the user + (ie, ignores things like ). + """ + if int(vim.eval("g:UltiSnipsRemoveSelectModeMappings")): + ignores = vim.eval("g:UltiSnipsMappingsToIgnore") + ['UltiSnips'] + + for option in ("", ""): + # Put all smaps into a var, and then read the var + vim.command(r"redir => _tmp_smaps | silent smap %s " % option + + "| redir END") + + # Check if any mappings where found + all_maps = filter(len, vim.eval(r"_tmp_smaps").splitlines()) + if (len(all_maps) == 1 and + all_maps[0][0] not in " sv"): + # "No maps found". String could be localized. Hopefully + # it doesn't start with any of these letters in any + # language + continue + + # Only keep mappings that should not be ignored + maps = [m for m in all_maps if + not any(i in m for i in ignores) and len(m.strip())] + + for m in maps: + # Some mappings have their modes listed + trig = m.split() + if m[0] == " ": + trig = trig[0] + else: + trig = trig[1] + + # The bar separates commands + if trig[-1] == "|": + trig = trig[:-1] + "" + + # Special ones + if trig[0] == "<": + add = False + # Only allow these + for valid in ["Tab", "NL", "CR", "C-Tab", "BS"]: + if trig == "<%s>" % valid: + add = True + if not add: + continue + + # Actually unmap it + vim.command("sunmap %s %s" % (option,trig)) + class SnippetManager(object): def __init__(self): self._vstate = VimState() diff --git a/test.py b/test.py index 0d19a41..4af4902 100755 --- a/test.py +++ b/test.py @@ -1933,6 +1933,73 @@ xj k """ +####################### +# Test for bug 427298 # +####################### +class _SelectModeMappings(_VimTest): + snippets = ("test", "${1:World}") + keys = "test" + EX + "Hello" + wanted = "Hello" + maps = ("", "") + buffer_maps = ("", "") + do_unmapping = True + ignores = [] + + def _options_on(self): + self.send(":let g:UltiSnipsRemoveSelectModeMappings=%i\n" % + int(self.do_unmapping)) + self.send(":let g:UltiSnipsMappingsToIgnore=%s\n" % + repr(self.ignores)) + + if not isinstance(self.maps[0], tuple): + self.maps = (self.maps,) + if not isinstance(self.buffer_maps[0], tuple): + self.buffer_maps = (self.buffer_maps,) + + for key, m in self.maps: + if not len(key): continue + self.send(":smap %s %s\n" % (key,m)) + for key, m in self.buffer_maps: + if not len(key): continue + self.send(":smap %s %s\n" % (key,m)) + + def _options_off(self): + for key, m in self.maps: + if not len(key): continue + self.send(":sunmap %s\n" % key) + for key, m in self.buffer_maps: + if not len(key): continue + self.send(":sunmap %s\n" % key) + + self.send(":let g:UltiSnipsRemoveSelectModeMappings=1\n") + self.send(":let g:UltiSnipsMappingsToIgnore= []\n") + +class SelectModeMappings_RemoveBeforeSelecting_ECR(_SelectModeMappings): + maps = ("H", "x") + wanted = "Hello" +class SelectModeMappings_DisableRemoveBeforeSelecting_ECR(_SelectModeMappings): + do_unmapping = False + maps = ("H", "x") + wanted = "xello" +class SelectModeMappings_IgnoreMappings_ECR(_SelectModeMappings): + ignores = ["e"] + maps = ("H", "x"), ("e", "l") + wanted = "Hello" +class SelectModeMappings_IgnoreMappings1_ECR(_SelectModeMappings): + ignores = ["H"] + maps = ("H", "x"), ("e", "l") + wanted = "xello" +class SelectModeMappings_IgnoreMappings2_ECR(_SelectModeMappings): + ignores = ["e", "H"] + maps = ("e", "l"), ("H", "x") + wanted = "xello" +class SelectModeMappings_BufferLocalMappings_ECR(_SelectModeMappings): + buffer_maps = ("H", "blah") + wanted = "Hello" + + + + ########################################################################### # END OF TEST #