pub mod code_review_view; pub mod comment_list_view; pub mod context; pub mod diff_size_limits; #[cfg_attr(not(feature = "local_fs"), allow(dead_code))] pub mod diff_state; pub mod editor_state; pub(crate) mod find_model; pub(crate) mod git_dialog; pub mod git_status_update; mod hidden_lines; pub mod telemetry_event; #[cfg_attr(not(feature = "local_fs"), allow(unused_imports))] pub use telemetry_event::CodeReviewTelemetryEvent; pub(crate) mod code_review_header; pub(crate) mod comment_rendering; pub mod comments; pub(crate) mod diff_menu; pub(crate) mod diff_selector; pub(crate) mod file_invalidation_queue; use code_review_view::CodeReviewAction; use std::path::{Path, PathBuf}; use warpui::{ id, keymap::{EditableBinding, FixedBinding}, AppContext, Entity, EntityId, ModelContext, SingletonEntity, WeakViewHandle, WindowId, }; use crate::code_review::telemetry_event::CodeReviewPaneEntrypoint; use crate::terminal::{view::TerminalView, CLIAgent}; use crate::util::bindings::CustomAction; /// Arguments needed to open or toggle the code review panel. /// Bundled into a struct so that events can atomically open the /// review and perform follow-up work without relying on event ordering. #[derive(Clone)] pub struct CodeReviewPanelArg { pub repo_path: Option, pub terminal_view: WeakViewHandle, pub entrypoint: CodeReviewPaneEntrypoint, pub focus_new_pane: bool, pub cli_agent: Option, } /// Scope for diff set context attachment #[derive(Clone, Debug, PartialEq)] pub enum DiffSetScope { All, File(PathBuf), } /// Register keybindings for code review functionality. pub fn init(app: &mut AppContext) { app.register_editable_bindings([ EditableBinding::new( "code_review:save_all_unsaved_files", "Save all unsaved files in code review", CodeReviewAction::SaveAllUnsavedFiles, ) .with_context_predicate(id!("CodeReviewView")) .with_key_binding("cmdorctrl-s"), EditableBinding::new( "code_review:show_find_bar", "Show find bar in code review", CodeReviewAction::ShowFindBar, ) .with_context_predicate(id!("CodeReviewView")) .with_key_binding("cmdorctrl-f") .with_enabled(|| crate::features::FeatureFlag::CodeReviewFind.is_enabled()), ]); app.register_fixed_bindings([FixedBinding::custom( CustomAction::Undo, CodeReviewAction::UndoRevert, "Undo", id!("CodeReviewView") & !id!("IMEOpen"), )]); diff_menu::init(app); diff_selector::init(app); git_dialog::init(app); } /// Uses heuristics to determine if a file is auto-generated. fn is_file_autogenerated(file_path: &Path, content: Option<&str>) -> bool { const AUTOGEN_HEADERS: [&str; 3] = [ "Code generated by", "This file is automatically generated", "AUTO-GENERATED FILE", ]; let file_name = file_path .file_name() .and_then(|name| name.to_str()) .unwrap_or(""); // Check for specific lock files and autogenerated files by exact name match file_name { // Package manager lock files "Cargo.lock" | "package-lock.json" | "yarn.lock" | "pnpm-lock.yaml" | "Gemfile.lock" | "composer.lock" | "Pipfile.lock" | "poetry.lock" | "go.sum" | "mix.lock" => return true, // Log files name if name.ends_with(".log") => return true, _ => {} } // Check for file path hints. if file_name.contains(".generated.") || file_name.contains(".gen.") || file_name.ends_with(".min.js") || file_name.ends_with(".min.css") || file_name.contains(".bundle.") { return true; } // Check for directory structure hints. let file_path_str = file_path.to_string_lossy(); if file_path_str.contains("__generated__/") || file_path_str.contains(".auto/") || file_path_str.contains("codegen/") { return true; } // Check the first line of the modified file for autogeneration headers. // We don't check any actual diffs because the user should probably inspect // auto-generated files if they are created for the first time. if let Some(content) = content { if let Some(first_line) = content.lines().next() { if AUTOGEN_HEADERS .iter() .any(|header| first_line.contains(header)) { return true; } } } false } /// A [`SingletonEntity`] that the tracks events for the code review model throughought the app. /// We need this because toasts are emitted in the Workspace, and want a click handler that triggers /// behavior in a _specific_ review pane. We use this model get around restrictions that make it hard /// to emit a CodeReviewView typed action from the toast because it's not in the view reponder chain of the /// Workspace. pub struct GlobalCodeReviewModel; impl GlobalCodeReviewModel { pub fn undo_revert_in_code_review_pane( &mut self, window_id: WindowId, view_id: EntityId, ctx: &mut ModelContext, ) { ctx.emit(GlobalCodeReviewEvent::DiffReverted { window_id, view_id }); } } pub enum GlobalCodeReviewEvent { DiffReverted { window_id: WindowId, view_id: EntityId, }, } impl SingletonEntity for GlobalCodeReviewModel {} impl Entity for GlobalCodeReviewModel { type Event = GlobalCodeReviewEvent; }