def replace_in_window(
        self,
        search: str,
        replace: str,
        *,
        reset_first_line: str = "top",
    ) -> "ReplacementInfo":
        """Search and replace in the window.

        Args:
            search: The string to search for (can be multi-line).
            replace: The string to replace it with (can be multi-line).
            reset_first_line: If "keep", we keep the current line. Otherwise, we
                `goto` the line where the replacement started with this mode.
        """
        window_text = self.get_window_text()
        # Update line number
        index = window_text.find(search)
        if index == -1:
            if self._exit_on_exception:
                print(f"Error: Text not found: {search}")
                exit(1)
            raise TextNotFound
        window_start_line, _ = self.line_range
        replace_start_line = window_start_line + len(window_text[:index].split("\n")) - 1
        new_window_text = window_text.replace(search, replace)
        self.set_window_text(new_window_text)
        if reset_first_line == "keep":
            pass
        else:
            self.goto(replace_start_line, mode=reset_first_line)
        return ReplacementInfo(
            first_replaced_line=replace_start_line,
            n_search_lines=len(search.split("\n")),
            n_replace_lines=len(replace.split("\n")),
            n_replacements=1,
        )
Search and replace in the window.

        Args:
            search: The string to search for (can be multi-line).
            replace: The string to replace it with (can be multi-line).
            reset_first_line: If "keep", we keep the current line. Otherwise, we
                `goto` the line where the replacement started with this mode.
        
tools/windowed/lib/windowed_file.py