Esempio n. 1
0
    def _setup_buffer(self):
        """To set sane options for the search results buffer."""
        last_search = ""
        if v.eval("@/"):
            last_search = v.eval("@/").decode(v.encoding()).replace(u'"', u'\\"')
        self.exit_cmds.extend([
            u"let @/=\"{}\"".format(last_search),
            u"set laststatus={}".format(v.opt("ls")),
            u"set guicursor={}".format(v.opt("gcr")),
        ])

        commands = [
            "let @/ = ''",
            "call clearmatches()"
        ]

        options = [
            "buftype=nofile", "bufhidden=wipe", "nobuflisted", "noundofile",
            "nobackup", "noswapfile", "nowrap", "nonumber", "nolist",
            "textwidth=0", "colorcolumn=0", "laststatus=0", "norelativenumber",
            "nocursorcolumn", "nospell", "foldcolumn=0", "foldcolumn=0",
            "guicursor=a:hor5-Cursor-blinkwait100",
        ]

        if settings.get("cursorline", bool):
            options.append("cursorline")
        else:
            options.append("nocursorline")

        for opt in options:
            v.exe("try|setl {}|catch|endtry".format(opt))

        for cmd in commands:
            v.exe(cmd)
Esempio n. 2
0
 def _generate_tagfile(self):
     """To generate a new temporary tagfile and update the vim
     `tags` option."""
     tagfile = tempfile.NamedTemporaryFile(delete=False)
     v.exe(u"set tags+={}".format(tagfile.name))
     self.old_tagfiles.append(tagfile.name)
     return tagfile
Esempio n. 3
0
 def _open_window(self):
     """To open the Surfer window if not already visible."""
     if not self.winnr:
         self.exit_cmds.append(u"set ei={}".format(v.opt("ei")))
         v.exe(u"set eventignore=all")
         v.exe(u'sil! keepa botright 1new {}'.format(self.name))
         self._setup_buffer()
         self.winnr = v.bufwinnr(self.name)
Esempio n. 4
0
 def _remove_tagfiles(self):
     """To delete all previously created tagfiles."""
     for tagfile in self.old_tagfiles:
         v.exe(u"set tags-={}".format(tagfile))
         try:
             os.remove(tagfile)
         except OSError:
             pass
Esempio n. 5
0
 def _close(self):
     """To close the Surfer user interface."""
     v.exe('q')
     for cmd in self.exit_cmds:
         v.exe(cmd)
     if self.user_buf.winnr:
         v.focus_win(self.user_buf.winnr)
     self._reset()
     v.redraw()
Esempio n. 6
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^")
Esempio n. 7
0
    def setup_colors(self):
        """To setup Surfer highlight groups."""
        postfix = "" if v.opt("bg") == "light" else "_darkbg"
        colors = {
            "SurferShade": settings.get("shade_color{}".format(postfix)),
            "SurferMatches": settings.get("matches_color{}".format(postfix)),
            "SurferPrompt": settings.get("prompt_color{}".format(postfix)),
            "SurferError": "WarningMsg"
        }
        for group, color in colors.items():
            if color:
                link = "" if "=" in color else "link"
                v.exe(u"hi {} {} {}".format(link, group, color))

        colors = settings.get("visual_kinds_colors{}".format(postfix))
        for kind, color in colors.items():
            if color:
                link = "" if "=" in color else "link"
                v.exe(u"hi {} SurferVisualKind_{} {}".format(link, kind, color))
Esempio n. 8
0
    def render(self, target_win, cursor_pos, query, tags, msg="", iserror=False):
        """To render all search results."""
        v.exe('syntax clear')
        v.focus_win(target_win)
        mapper = {}

        if not tags and not msg:
            msg = settings.get("no_results_msg")

        if msg:

            v.setbuffer(msg)
            v.setwinh(len(msg.split("\n")))
            (len(msg.split("\n")))
            cursor_pos = 0
            if iserror:
                self._highlight_err()

        else:

            # Find duplicates file names
            dups = {}
            for _, g in groupby(tags, key=lambda t: os.path.basename(t["file"])):
                # s is a set of unique paths but with the same basename
                s = set(t["file"] for t in g)
                if len(s) > 1:
                    dups.update((file, True) for file in s)

            tags = tags[::-1]
            mapper = dict(enumerate(t for t in tags))
            v.setbuffer([self._render_line(t, query, dups) for t in tags])
            cursor_pos = self._render_curr_line(cursor_pos)
            self._highlight_tags(tags, cursor_pos)
            v.setwinh(len(tags))

        v.cursor((cursor_pos + 1, 0))
        v.exe("normal! 0")

        return mapper, cursor_pos
Esempio n. 9
0
    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()