def read(self) -> str:
        """
        Read the input.

        This will run the Python input user interface in another thread, wait
        for input to be accepted and return that. By running the UI in another
        thread, we avoid issues regarding possibly nested event loops.

        This can raise EOFError, when Control-D is pressed.
        """

        # Capture the current input_mode in order to restore it after reset,
        # for ViState.reset() sets it to InputMode.INSERT unconditionally and
        # doesn't accept any arguments.
        def pre_run(
            last_input_mode: InputMode = self.app.vi_state.input_mode,
        ) -> None:
            if self.vi_keep_last_used_mode:
                self.app.vi_state.input_mode = last_input_mode

            if not self.vi_keep_last_used_mode and self.vi_start_in_navigation_mode:
                self.app.vi_state.input_mode = InputMode.NAVIGATION

        # Run the UI.
        while True:
            try:
                result = self.app.run(pre_run=pre_run, in_thread=True)

                if result.lstrip().startswith("\x1a"):
                    # When the input starts with Ctrl-Z, quit the REPL.
                    # (Important for Windows users.)
                    raise EOFError

                # Remove leading whitespace.
                # (Users can add extra indentation, which happens for
                # instance because of copy/pasting code.)
                result = unindent_code(result)

                if result and not result.isspace():
                    if self.insert_blank_line_after_input:
                        self.app.output.write("\n")

                    return result
            except KeyboardInterrupt:
                # Abort - try again.
                self.signatures = []
                self.default_buffer.document = Document()

        Read the input.

        This will run the Python input user interface in another thread, wait
        for input to be accepted and return that. By running the UI in another
        thread, we avoid issues regarding possibly nested event loops.

        This can raise EOFError, when Control-D is pressed.
        
src/ptpython/python_input.py