pub fn run(
        mut self,
        writer: impl Write,
        con: &AppContext,
        skin: Skin,
    ) -> Result<Option<Launchable>, ProgramError> {
        // Ensure the buffer is flushed before we return
        let writer = WriteCleanup::new(writer, |w| w.flush());

        // Push some terminal state changes, ensuring they're reverted when we
        // end the program.
        let writer = WriteCleanup::build(
            writer,
            |w| just_queue(w, EnterAlternateScreen),
            |w| just_queue(w, LeaveAlternateScreen),
        )?;
        let writer = WriteCleanup::build(
            writer,
            |w| just_queue(w, cursor::Hide),
            |w| just_queue(w, cursor::Show),
        )?;

        debug!("we're on screen");
        let mut screen = Screen::new(con, skin)?;

        // we listen for events in a separate thread so that we can go on listening
        // when a long search is running, and interrupt it if needed
        let mut writer = WriteCleanup::build(
            writer,
            |w| just_queue(w, EnableMouseCapture),
            |w| just_queue(w, DisableMouseCapture),
        )?;
        let event_source = EventSource::new()?;
        let rx_events = event_source.receiver();

        self.push(Box::new(
            BrowserState::new(
                con.launch_args.root.clone(),
                con.launch_args.tree_options.clone(),
                &screen,
                &TaskLifetime::unlimited(),
            )?
            .expect("Failed to create BrowserState"),
        ));

        let mut cmd = Command::new();

        // if some commands were passed to the application
        //  we execute them before even starting listening for events
        if let Some(unparsed_commands) = &con.launch_args.commands {
            let lifetime = TaskLifetime::unlimited();
            for arg_cmd in parse_command_sequence(unparsed_commands, con)? {
                cmd = self.apply_command(&mut writer, arg_cmd, &mut screen, con)?;
                self.do_pending_tasks(&mut writer, &cmd, &mut screen, con, lifetime.clone())?;
                if self.quitting {
                    return Ok(self.launch_at_end.take());
                }
            }
        }

        let state = self.mut_state();
        state.display(&mut writer, &screen, con)?;
        state.write_status(&mut writer, &cmd, &screen, con)?;
        state.write_flags(&mut writer, &mut screen, con)?;

        screen.input_field.display_on(&mut writer)?;
        loop {
            let tl = TaskLifetime::new(event_source.shared_event_count());
            if !self.quitting {
                self.do_pending_tasks(&mut writer, &cmd, &mut screen, con, tl)?;
            }
            let event = match rx_events.recv() {
                Ok(event) => event,
                Err(_) => {
                    // this is how we quit the application,
                    // when the input thread is properly closed
                    break;
                }
            };
            cmd.add_event(&event, &mut screen.input_field, con, self.state());
            debug!("command after add_event: {:?}", &cmd);
            cmd = self.apply_command(&mut writer, cmd, &mut screen, con)?;
            event_source.unblock(self.quitting);
        }

        Ok(self.launch_at_end.take())
    }
/// This is the main loop of the application
This is the main loop of the application
This is the main loop of the application
pub fn run(
        mut self,
        writer: impl Write,
        con: &AppContext,
        skin: Skin,
    ) -> Result<Option<Launchable>, ProgramError> {
        // Ensure the buffer is flushed before we return
        let writer = WriteCleanup::new(writer, |w| w.flush());
        // Push some terminal state changes, ensuring they're reverted when we
        // end the program.
        let writer = WriteCleanup::build(
            writer,
            |w| just_queue(w, EnterAlternateScreen),
            |w| just_queue(w, LeaveAlternateScreen),
        )?;
        let writer = WriteCleanup::build(
            writer,
            |w| just_queue(w, cursor::Hide),
            |w| just_queue(w, cursor::Show),
        )?;
        debug!("we're on screen");
        let mut screen = Screen::new(con, skin)?;
        // we listen for events in a separate thread so that we can go on listening
        // when a long search is running, and interrupt it if needed
        let mut writer = WriteCleanup::build(
            writer,
            |w| just_queue(w, EnableMouseCapture),
            |w| just_queue(w, DisableMouseCapture),
        )?;
        let event_source = EventSource::new()?;
        let rx_events = event_source.receiver();
        self.push(Box::new(
            BrowserState::new(
                con.launch_args.root.clone(),
                con.launch_args.tree_options.clone(),
                &screen,
                &TaskLifetime::unlimited(),
            )?
            .expect("Failed to create BrowserState"),
        ));
        let mut cmd = Command::new();
        // if some commands were passed to the application
        //  we execute them before even starting listening for events
        if let Some(unparsed_commands) = &con.launch_args.commands {
            let lifetime = TaskLifetime::unlimited();
            for arg_cmd in parse_command_sequence(unparsed_commands, con)? {
                cmd = self.apply_command(&mut writer, arg_cmd, &mut screen, con)?;
                self.do_pending_tasks(&mut writer, &cmd, &mut screen, con, lifetime.clone())?;
                if self.quitting {
                    return Ok(self.launch_at_end.take());
                }
            }
        }
        let state = self.mut_state();
        state.display(&mut writer, &screen, con)?;
        state.write_status(&mut writer, &cmd, &screen, con)?;
        state.write_flags(&mut writer, &mut screen, con)?;
        screen.input_field.display_on(&mut writer)?;
        loop {
            let tl = TaskLifetime::new(event_source.shared_event_count());
            if !self.quitting {
                self.do_pending_tasks(&mut writer, &cmd, &mut screen, con, tl)?;
            }
            let event = match rx_events.recv() {
                Ok(event) => event,
                Err(_) => {
                    // this is how we quit the application,
                    // when the input thread is properly closed
                    break;
                }
            };
            cmd.add_event(&event, &mut screen.input_field, con, self.state());
            debug!("command after add_event: {:?}", &cmd);
            cmd = self.apply_command(&mut writer, cmd, &mut screen, con)?;
            event_source.unblock(self.quitting);
        }
        Ok(self.launch_at_end.take())
    }
pub fn run ( mut self , writer : impl Write , con : & AppContext , skin : Skin , ) -> Result < Option < Launchable > , ProgramError > { // Ensure the buffer is flushed before we return let writer = WriteCleanup :: new ( writer , | w | w . flush ( ) ) ; // Push some terminal state changes, ensuring they're reverted when we // end the program. let writer = WriteCleanup :: build ( writer , | w | just_queue ( w , EnterAlternateScreen ) , | w | just_queue ( w , LeaveAlternateScreen ) , ) ? ; let writer = WriteCleanup :: build ( writer , | w | just_queue ( w , cursor :: Hide ) , | w | just_queue ( w , cursor :: Show ) , ) ? ; debug ! ( " " ) ; let mut screen = Screen :: new ( con , skin ) ? ; // we listen for events in a separate thread so that we can go on listening // when a long search is running, and interrupt it if needed let mut writer = WriteCleanup :: build ( writer , | w | just_queue ( w , EnableMouseCapture ) , | w | just_queue ( w , DisableMouseCapture ) , ) ? ; let event_source = EventSource :: new ( ) ? ; let rx_events = event_source . receiver ( ) ; self . push ( Box :: new ( BrowserState :: new ( con . launch_args . root . clone ( ) , con . launch_args . tree_options . clone ( ) , & screen , & TaskLifetime :: unlimited ( ) , ) ? . expect ( " " ) , ) ) ; let mut cmd = Command :: new ( ) ; // if some commands were passed to the application //  we execute them before even starting listening for events if let Some ( unparsed_commands ) = & con . launch_args . commands { let lifetime = TaskLifetime :: unlimited ( ) ; for arg_cmd in parse_command_sequence ( unparsed_commands , con ) ? { cmd = self . apply_command ( & mut writer , arg_cmd , & mut screen , con ) ? ; self . do_pending_tasks ( & mut writer , & cmd , & mut screen , con , lifetime . clone ( ) ) ? ; if self . quitting { return Ok ( self . launch_at_end . take ( ) ) ; } } } let state = self . mut_state ( ) ; state . display ( & mut writer , & screen , con ) ? ; state . write_status ( & mut writer , & cmd , & screen , con ) ? ; state . write_flags ( & mut writer , & mut screen , con ) ? ; screen . input_field . display_on ( & mut writer ) ? ; loop { let tl = TaskLifetime :: new ( event_source . shared_event_count ( ) ) ; if ! self . quitting { self . do_pending_tasks ( & mut writer , & cmd , & mut screen , con , tl ) ? ; } let event = match rx_events . recv ( ) { Ok ( event ) => event , Err ( _ ) => { // this is how we quit the application, // when the input thread is properly closed break ; } } ; cmd . add_event ( & event , & mut screen . input_field , con , self . state ( ) ) ; debug ! ( " " cmd ) ; cmd = self . apply_command ( & mut writer , cmd , & mut screen , con ) ? ; event_source . unblock ( self . quitting ) ; } Ok ( self . launch_at_end . take ( ) ) }
This is the main loop of the application
This is the main loop of the application
mut self
writer
impl Write
con
&AppContext
skin
Skin
mut self
writer
impl Write
con
&AppContext
skin
Skin