Example #1
0
 def _jump_to(self, tag, mode=""):
     """To jump to the tag on the current line."""
     hidden = v.opt("hidden")
     autowriteall = v.opt("autowriteall")
     modified = v.call(u"getbufvar({},'&mod')".format(self.user_buf.nr))
     bufname = self.user_buf.name
     self._close()
     count, tagfile = self._tag_count(tag)
     if (not hidden and not autowriteall) and modified and tagfile != bufname:
         v.echohl(u"write the buffer first. (:h hidden)", "WarningMsg")
     else:
         v.exe(u"sil! {}{}tag {}".format(count, mode, tag["name"]))
         v.exe("normal! zvzzg^")
Example #2
0
    def _tag_count(self, tag):
        """To pick the best tag candidate for a given tag name.

        The number retruned is meant to be used in conjunction with the :tag
        vim command (see :h :tag)
        """
        enc = v.encoding()
        candidates = v.call(u'taglist("{}")'.format(tag["name"]))
        if len(candidates) == 1:
            return 1, candidates[0]["filename"].decode(enc)

        #  group tags by file name
        groups = []
        for fname, g in groupby(candidates, key=itemgetter("filename")):
            groups.append((fname, list(g)))
        groups.sort(key=itemgetter(0))

        # sort tags by the `line` field (XXX: or `cmd`?); tags from of the
        # current buffer are put first. This is ensures that the `:[count]tag
        # [name]` command will work as expected (see :h tag-priority)
        ordered_candidates = []
        for fname, tags in groups:
            sorted_tags = sorted(tags, key=itemgetter("line"))
            if fname.decode(enc) == v.bufname():
                ordered_candidates = sorted_tags + ordered_candidates
            else:
                ordered_candidates.extend(sorted_tags)

        files = [c["filename"].decode(enc) for c in ordered_candidates]
        scores = [0]*len(ordered_candidates)
        for i, candidate in enumerate(ordered_candidates):
            if candidate["cmd"].decode(enc) == tag["cmd"]:
                scores[i] += 1
            if candidate["name"].decode(enc) == tag["name"]:
                scores[i] += 1
            if candidate["filename"].decode(enc) == tag["file"]:
                scores[i] += 1
            if candidate["line"].decode(enc) == tag["exts"].get("line"):
                scores[i] += 1
            if candidate["kind"].decode(enc) == tag["exts"].get("kind"):
                scores[i] += 1
            if candidate["language"].decode(enc) == tag["exts"].get("language"):
                scores[i] += 1

        idx = scores.index(max(scores))
        return idx + 1, files[idx]
Example #3
0
    def get_files(self):
        """To get all files in the current project.

        The current working directory is derived from the path of
        the current open buffer.
        """
        root = self.get_root()
        if not root:
            return []

        if not self.files_cache:
            # Get all files of the current project.
            # XXX On OS X, if there is a directory whose name contains unicode
            # characters, glob("{root}/**") skips all files in that directory
            # except the first. (using os.walk in not a solution since it does
            # not filter files according to the `wildignore` vim option)
            files = v.call(u"glob('{}/**')".format(root)).split(u"\n")
            files = imap(lambda f: normalize("NFC", f), files)
            self.files_cache = filter(isfile, files)

        return self.files_cache
Example #4
0
    def get(self):
        """To read a key pressed by the user."""
        self._reset()

        try:
            raw_char = v.call('strtrans(getchar())')
        except KeyboardInterrupt:
            # This exception is triggered only on Windows when the user
            # press CTRL+C
            self.CHAR = 'c'
            self.CTRL = True
            self.INTERRUPT = True
            return

        nr = v.call(u"str2nr('{}')".format(raw_char))
        # `nr` == 0 when the user press backspace, an arrow key, F*, etc

        if nr != 0:

            if nr == 13:  # same as Ctrl+m
                self.RETURN = True
            elif nr == 27:
                self.ESC = True
            elif nr == 9:  # same as Ctrl+i
                self.TAB = True
            elif 1 <= nr <= 26:
                self.CTRL = True
                self.CHAR = self._nr2char(nr+96)
                if self.CHAR == 'c':
                    self.INTERRUPT = True
            else:
                self.CHAR = self._nr2char(nr)

        else:

            if 'kl' in raw_char:
                self.LEFT = True
            elif 'kr' in raw_char:
                self.RIGHT = True
            elif 'ku' in raw_char:
                self.UP = True
            elif 'kd' in raw_char:
                self.DOWN = True
            elif 'kb' in raw_char:
                self.BS = True
            elif 'k1' in raw_char:
                self.F1 = True
            elif 'k2' in raw_char:
                self.F2 = True
            elif 'k3' in raw_char:
                self.F3 = True
            elif 'k4' in raw_char:
                self.F4 = True
            elif 'k5' in raw_char:
                self.F5 = True
            elif 'k6' in raw_char:
                self.F6 = True
            elif 'k7' in raw_char:
                self.F7 = True
            elif 'k8' in raw_char:
                self.F8 = True
            elif 'k9' in raw_char:
                self.F9 = True
            elif 'k10' in raw_char:
                self.F10 = True
            elif 'k11' in raw_char:
                self.F11 = True
            elif 'k12' in raw_char:
                self.F12 = True
            else:
                # mouse clicks or scrolls
                self.MOUSE = True
Example #5
0
 def _nr2char(self, nr):
     return v.call("nr2char({})".format(nr))