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 open(self): """To open the Surfer user interface.""" # The Fugitive plugin seems to interfere with Surfer since it adds # some filenames to the vim option `tags`. Surfer does this too, # but if Fugitive is installed and the user is editing a file in a git # repository, it seems that Surfer cannot append anything to the # `tag` option. I haven't still figured out why this happens but this # seems to fix the issue. v.exe("exe 'set tags='.&tags") self.user_buf = self.BufInfo(v.bufname(), v.bufnr(), v.winnr()) pmod = settings.get("project_search_modifier") bmod = settings.get("buffer_search_modifier") prompt = u"echohl SurferPrompt | echon \"{}\" | echohl None".format( settings.get("prompt")) self._open_window() self.renderer.render(self.winnr, -1, "", [], "") v.redraw() # Start the input loop key = input.Input() while True: self.perform_new_search = True # Display the prompt and the current query v.exe(prompt) query = self.query.replace("\\", "\\\\").replace('"', '\\"') v.exe(u"echon \"{}\"".format(query)) # Wait for the next pressed key key.get() # Go to the tag on the current line if (key.RETURN or key.CTRL and key.CHAR in ('g', 'o', 'p', 's')): mode = key.CHAR if key.CHAR in ('s', 'p') else '' tag = self.mapper.get(self.cursor_pos) if tag: self._jump_to(tag, mode) break # Close the Surfer window elif key.ESC or key.INTERRUPT: self._close() break # Delete a character backward elif key.BS: query = self.query.strip() if query and query in (bmod, pmod): self.plug.generator.rebuild_tags = True self.query = u"{}".format(self.query)[:-1] self.cursor_pos = -1 # move the cursor to the bottom # Move the cursor up elif key.UP or key.TAB or key.CTRL and key.CHAR == 'k': self.perform_new_search = False if self.cursor_pos == 0: self.cursor_pos = len(v.buffer()) - 1 else: self.cursor_pos -= 1 # Move the cursor down elif key.DOWN or key.CTRL and key.CHAR == 'j': self.perform_new_search = False if self.cursor_pos == len(v.buffer()) - 1: self.cursor_pos = 0 else: self.cursor_pos += 1 # Clear the current search elif key.CTRL and key.CHAR == 'u': query = self.query.lstrip() if query and query[0] in (bmod, pmod): self.query = query[0] else: self.query = u"" self.cursor_pos = -1 # move the cursor to the bottom # A character has been pressed. elif key.CHAR: self.query += key.CHAR self.cursor_pos = -1 # move the cursor to the bottom if key.CHAR in (pmod, bmod) and len(self.query.strip()) == 1: self.plug.generator.rebuild_tags = True else: v.redraw() continue self._update() v.redraw()
def update_root(self): """To keep updated the project root whenever the user edits a buffer.""" bufname = v.bufname() if bufname is None or not bufname.startswith(self.root_cache): self.files_cache = [] self.root_cache = u""