'Return a dict of Vi[m] modeline vars.
See ":help modeline" in Vim for a spec.
>>> TextInfo()._get_vi_vars("/* vim: set ai tw=75: */")
{\'ai\': None, \'tw\': 75}
>>> TextInfo()._get_vi_vars("vim: set ai tw=75: bar")
{\'ai\': None, \'tw\': 75}
>>> TextInfo()._get_vi_vars("vi: set foo:bar")
{\'foo\': None}
>>> TextInfo()._get_vi_vars(" vi: se foo:bar")
{\'foo\': None}
>>> TextInfo()._get_vi_vars(" ex: se foo:bar")
{\'foo\': None}
>>> TextInfo()._get_vi_vars(" vi:noai:sw=3 tw=75")
{\'tw\': 75, \'sw\': 3, \'noai\': None}
>>> TextInfo()._get_vi_vars(" vi:noai:sw=3 tw=75")
{\'tw\': 75, \'sw\': 3, \'noai\': None}
>>> TextInfo()._get_vi_vars("ex: se foo:bar")
Some edge cases:
>>> TextInfo()._get_vi_vars(r"/* vi:set dir=c\:\tmp: */")
{\'dir\': \'c:\\tmp\'}'

def _get_vi_vars(self, bytes):

    if (self._vi_vars_cache is not None):
        return self._vi_vars_cache
    vi_vars = {}
    if (('vi:' not in bytes) and ('ex:' not in bytes) and ('vim:' not in bytes)):
        self._vi_vars_cache = vi_vars
        return vi_vars
    for (pat, splitter) in self._vi_vars_pats_and_splitters:
        match = pat.search(bytes)
        if match:
            for var_str in splitter.split(match.group('rhs')):
                if ('=' in var_str):
                    (name, value) = var_str.split('=', 1)
                    try:
                        vi_vars[name] = int(value)
                    except ValueError:
                        vi_vars[name] = value.replace('\\:', ':')
                else:
                    vi_vars[var_str] = None
            break
    self._vi_vars_cache = vi_vars
    return vi_vars
