Esempio n. 1
0
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 (%s)") % (i+1, escape(s.description, '\\'),
        escape(s.location, '\\')) for i, s in enumerate(snippets)]
    return _ask_user(snippets, display)
Esempio n. 2
0
    def _file_to_edit(self, requested_ft, bang):  # pylint: disable=no-self-use
        """Returns a file to be edited for the given requested_ft.

        If 'bang' is
        empty only private files in g:UltiSnipsSnippetsDir are considered,
        otherwise all files are considered and the user gets to choose.

        """
        # 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.
        potentials = set()

        if _vim.eval("exists('g:UltiSnipsSnippetsDir')") == '1':
            snippet_dir = _vim.eval('g:UltiSnipsSnippetsDir')
        else:
            if platform.system() == 'Windows':
                snippet_dir = os.path.join(_vim.eval('$HOME'),
                                           'vimfiles', 'UltiSnips')
            elif _vim.eval("has('nvim')") == '1':
                snippet_dir = os.path.join(_vim.eval('$HOME'),
                                           '.nvim', 'UltiSnips')
            else:
                snippet_dir = os.path.join(_vim.eval('$HOME'),
                                           '.vim', 'UltiSnips')

        filetypes = []
        if requested_ft:
            filetypes.append(requested_ft)
        else:
            if bang:
                filetypes.extend(self._buffer_filetypes[_vim.buf.number])
            else:
                filetypes.append(self._buffer_filetypes[_vim.buf.number][0])

        for ft in filetypes:
            potentials.update(find_snippet_files(ft, snippet_dir))
            potentials.add(os.path.join(snippet_dir,
                                        ft + '.snippets'))
            if bang:
                potentials.update(find_all_snippet_files(ft))

        potentials = set(os.path.realpath(os.path.expanduser(p))
                         for p in potentials)

        if len(potentials) > 1:
            files = sorted(potentials)
            formatted = [as_unicode('%i: %s') % (i, escape(fn, '\\')) for
                         i, fn in enumerate(files, 1)]
            file_to_edit = _ask_user(files, formatted)
            if file_to_edit is None:
                return ''
        else:
            file_to_edit = potentials.pop()

        dirname = os.path.dirname(file_to_edit)
        if not os.path.exists(dirname):
            os.makedirs(dirname)
        return file_to_edit
Esempio n. 3
0
    def matches(self, before, visual_content=None):
        """Returns True if this snippet matches 'before'."""
        # If user supplies both "w" and "i", it should perhaps be an
        # error, but if permitted it seems that "w" should take precedence
        # (since matching at word boundary and within a word == matching at word
        # boundary).
        self._matched = ''

        words = _words_for_line(self._trigger, before)

        if 'r' in self._opts:
            try:
                match = self._re_match(before)
            except Exception as e:
                self._make_debug_exception(e)
                raise

        elif 'w' in self._opts:
            words_len = len(self._trigger)
            words_prefix = words[:-words_len]
            words_suffix = words[-words_len:]
            match = (words_suffix == self._trigger)
            if match and words_prefix:
                # Require a word boundary between prefix and suffix.
                boundary_chars = escape(words_prefix[-1:] +
                                        words_suffix[:1], r'\"')
                match = _vim.eval(
                    '"%s" =~# "\\\\v.<."' %
                    boundary_chars) != '0'
        elif 'i' in self._opts:
            match = words.endswith(self._trigger)
        else:
            match = (words == self._trigger)

        # By default, we match the whole trigger
        if match and not self._matched:
            self._matched = self._trigger

        # Ensure the match was on a word boundry if needed
        if 'b' in self._opts and match:
            text_before = before.rstrip()[:-len(self._matched)]
            if text_before.strip(' \t') != '':
                self._matched = ''
                return False

        self._context = None
        if match and self._context_code:
            self._context = self._context_match(visual_content)
            if not self.context:
                match = False

        return match
Esempio n. 4
0
    def could_match(self, before):
        """Return True if this snippet could match the (partial) 'before'."""
        self._matched = ''

        # List all on whitespace.
        if before and before[-1] in (' ', '\t'):
            before = ''
        if before and before.rstrip() is not before:
            return False

        words = _words_for_line(self._trigger, before)

        if 'r' in self._opts:
            # Test for full match only
            match = self._re_match(before)
        elif 'w' in self._opts:
            # Trim non-empty prefix up to word boundary, if present.
            qwords = escape(words, r'\"')
            words_suffix = _vim.eval(
                'substitute("%s", "\\\\v^.+<(.+)", "\\\\1", "")' % qwords)
            match = self._trigger.startswith(words_suffix)
            self._matched = words_suffix

            # TODO: list_snippets() function cannot handle partial-trigger
            # matches yet, so for now fail if we trimmed the prefix.
            if words_suffix != words:
                match = False
        elif 'i' in self._opts:
            # TODO: It is hard to define when a inword snippet could match,
            # therefore we check only for full-word trigger.
            match = self._trigger.startswith(words)
        else:
            match = self._trigger.startswith(words)

        # By default, we match the words from the trigger
        if match and not self._matched:
            self._matched = words

        # Ensure the match was on a word boundry if needed
        if 'b' in self._opts and match:
            text_before = before.rstrip()[:-len(self._matched)]
            if text_before.strip(' \t') != '':
                self._matched = ''
                return False

        return match
Esempio n. 5
0
    def matches(self, trigger):
        """Returns True if this snippet matches 'trigger'."""
        # If user supplies both "w" and "i", it should perhaps be an
        # error, but if permitted it seems that "w" should take precedence
        # (since matching at word boundary and within a word == matching at word
        # boundary).
        self._matched = ''

        # Don't expand on whitespace
        if trigger and trigger.rstrip() != trigger:
            return False

        words = _words_for_line(self._trigger, trigger)

        if 'r' in self._opts:
            match = self._re_match(trigger)
        elif 'w' in self._opts:
            words_len = len(self._trigger)
            words_prefix = words[:-words_len]
            words_suffix = words[-words_len:]
            match = (words_suffix == self._trigger)
            if match and words_prefix:
                # Require a word boundary between prefix and suffix.
                boundary_chars = escape(words_prefix[-1:] +
                                        words_suffix[:1], r'\"')
                match = _vim.eval(
                    '"%s" =~# "\\\\v.<."' %
                    boundary_chars) != '0'
        elif 'i' in self._opts:
            match = words.endswith(self._trigger)
        else:
            match = (words == self._trigger)

        # By default, we match the whole trigger
        if match and not self._matched:
            self._matched = self._trigger

        # Ensure the match was on a word boundry if needed
        if 'b' in self._opts and match:
            text_before = trigger.rstrip()[:-len(self._matched)]
            if text_before.strip(' \t') != '':
                self._matched = ''
                return False
        return match
Esempio n. 6
0
def _select_and_create_file_to_edit(potentials: Set[str]) -> str:
    file_to_edit = ""
    if len(potentials) > 1:
        files = sorted(potentials)
        exists = [os.path.exists(f) for f in files]
        formatted = [
            "%s %i: %s" % ("*" if exists else " ", i, escape(fn, "\\"))
            for i, (fn, exists) in enumerate(zip(files, exists), 1)
        ]
        file_to_edit = _ask_user(files, formatted)
        if file_to_edit is None:
            return ""
    else:
        file_to_edit = potentials.pop()

    dirname = os.path.dirname(file_to_edit)
    if not os.path.exists(dirname):
        os.makedirs(dirname)

    return file_to_edit
Esempio n. 7
0
    def _get_file_to_edit(
        self, snippet_dir, requested_ft, bang, allow_empty=False
    ):  # pylint: disable=no-self-use
        potentials = set()
        filetypes = []
        if requested_ft:
            filetypes.append(requested_ft)
        else:
            if bang:
                filetypes.extend(self.get_buffer_filetypes())
            else:
                filetypes.append(self.get_buffer_filetypes()[0])

        for ft in filetypes:
            potentials.update(find_snippet_files(ft, snippet_dir))
            potentials.add(os.path.join(snippet_dir, ft + ".snippets"))
            if bang:
                potentials.update(find_all_snippet_files(ft))

        potentials = set(os.path.realpath(os.path.expanduser(p)) for p in potentials)

        if len(potentials) > 1:
            files = sorted(potentials)
            formatted = [
                as_unicode("%i: %s") % (i, escape(fn, "\\"))
                for i, fn in enumerate(files, 1)
            ]
            file_to_edit = _ask_user(files, formatted)
            if file_to_edit is None:
                return ""
        else:
            file_to_edit = potentials.pop()

        if not allow_empty and not os.path.exists(file_to_edit):
            return ""

        dirname = os.path.dirname(file_to_edit)
        if not os.path.exists(dirname):
            os.makedirs(dirname)

        return file_to_edit
Esempio n. 8
0
    def _get_file_to_edit(self, snippet_dir, requested_ft, bang,
                          allow_empty=False): # pylint: disable=no-self-use
        potentials = set()
        filetypes = []
        if requested_ft:
            filetypes.append(requested_ft)
        else:
            if bang:
                filetypes.extend(self.get_buffer_filetypes())
            else:
                filetypes.append(self.get_buffer_filetypes()[0])

        for ft in filetypes:
            potentials.update(find_snippet_files(ft, snippet_dir))
            potentials.add(os.path.join(snippet_dir,
                                        ft + '.snippets'))
            if bang:
                potentials.update(find_all_snippet_files(ft))

        potentials = set(os.path.realpath(os.path.expanduser(p))
                         for p in potentials)

        if len(potentials) > 1:
            files = sorted(potentials)
            formatted = [as_unicode('%i: %s') % (i, escape(fn, '\\')) for
                         i, fn in enumerate(files, 1)]
            file_to_edit = _ask_user(files, formatted)
            if file_to_edit is None:
                return ''
        else:
            file_to_edit = potentials.pop()

        if not allow_empty and not os.path.exists(file_to_edit):
            return ''

        dirname = os.path.dirname(file_to_edit)
        if not os.path.exists(dirname):
            os.makedirs(dirname)

        return file_to_edit
Esempio n. 9
0
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 (%s)') % (i + 1, escape(s.description, '\\'),
                                            escape(s.location, '\\')) for i, s in enumerate(snippets)]
    return _ask_user(snippets, display)