fn run_interactive()

in src/main.rs [523:604]


    fn run_interactive(
        &mut self,
        regex: &Regex,
        matcher: &RegexMatcher,
        subst: &str,
        dirs: Vec<&str>,
        file_set: Option<FileSet>,
    ) -> Result<()> {
        let walk = walk_builder_with_file_set(dirs.clone(), file_set.clone())?
            .hidden(!self.hidden)
            .threads(min(12, num_cpus::get()))
            .build_parallel();
        let (tx, rx) = channel();
        let thread_matcher = matcher.clone();
        thread::spawn(|| {
            walk.run(move || {
                let mut searcher = make_searcher();
                let tx = tx.clone();
                let matcher = thread_matcher.clone();
                Box::new(move |result| {
                    let dirent = match result {
                        Ok(d) => d,
                        Err(e) => {
                            eprintln!("Warning: {}", &e);
                            return WalkState::Continue;
                        }
                    };
                    if let Some(file_type) = dirent.file_type() {
                        if !file_type.is_file() {
                            return WalkState::Continue;
                        }
                        let path = dirent.path();
                        if !looks_like_code(path) {
                            return WalkState::Continue;
                        }
                        if let Some(contents) =
                            file_contents_if_matches(&mut searcher, &matcher, path)
                        {
                            if tx.send((path.to_path_buf(), contents)).is_err() {
                                return WalkState::Quit;
                            }
                        }
                    }
                    WalkState::Continue
                })
            })
        });

        // We have to keep track of which paths we've visited so that
        // if the user presses A to accept all changes and we kick
        // over into run_fast(), we don't apply the regex to files the
        // user has already addressed interactively. (The user may
        // have made manual edits or declined to replace some files.)
        // Since the user is doing this interactively and we don't
        // support bookmarks, this set presumably isn't going to grow so large
        // that the memory usage becomes a concern.
        let mut visited = HashSet::default();
        while let Ok((path, contents)) = rx.recv() {
            visited.insert(path.clone());
            self.present_and_apply_patches(&regex, subst, &path, contents)?;
            if self.yes_to_all {
                // Kick over into fast mode. We restart the
                // search, but we have our visited set so that
                // we won't apply changes to files the user
                // has already addressed.
                terminal::clear();
                notify_fast_mode();
                return Fastmod::run_fast_impl(
                    &regex,
                    &matcher,
                    subst,
                    dirs,
                    file_set,
                    self.hidden,
                    self.changed_files.clone(),
                    Some(visited),
                );
            }
        }
        self.print_changed_files_if_needed();
        Ok(())
    }