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^")
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]
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
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
def _nr2char(self, nr): return v.call("nr2char({})".format(nr))