use std::path::{Path, PathBuf}; use ai::diff_validation::DiffDelta; use warp_util::path::LineAndColumnArg; use warpui::elements::{DraggableState, Empty, MouseStateHandle}; use warpui::{ AppContext, Element, Entity, ModelHandle, TypedActionView, View, ViewContext, ViewHandle, }; use super::buffer_location::LocalOrRemotePath; use super::editor_management::CodeSource; use super::local_code_editor::LocalCodeEditorView; use crate::pane_group::focus_state::PaneFocusHandle; use crate::pane_group::pane::view::{HeaderContent, HeaderRenderContext}; use crate::pane_group::{BackingView, CodePane, PaneConfiguration, PaneEvent}; // Keybinding constants - exported so AI document view can reuse pub const SAVE_FILE_BINDING_NAME: &str = "code_view:save"; pub const SAVE_FILE_BINDING_DESCRIPTION: &str = "Save file"; #[cfg_attr(not(feature = "local_fs"), allow(dead_code))] pub fn is_supported_code_file(_path: impl AsRef) -> bool { false } #[cfg_attr(not(feature = "local_fs"), allow(dead_code))] pub fn is_binary_file(_path: impl AsRef) -> bool { false } pub fn init(_app: &mut AppContext) {} #[derive(Debug, Clone)] pub enum CodeViewAction { RemoveTabAtIndex { index: usize }, } #[derive(Debug, Clone)] #[allow(unused)] pub enum CodeViewEvent { Pane(PaneEvent), TabChanged { location: Option, tab_index: usize, }, FileOpened { location: LocalOrRemotePath, tab_index: usize, }, RunTabConfigSkill { path: PathBuf, }, OpenLspLogs { log_path: PathBuf, }, } #[derive(Debug, Clone)] pub enum PendingSaveIntent { Save, Discard, Cancel, } #[allow(unused)] #[derive(Debug, Clone)] enum TabBarDragPosition { BeforeTab, AfterTab, } #[allow(unused)] #[derive(Default, Clone)] struct TabDataMouseStateHandles { tab_handle: MouseStateHandle, close_handle: MouseStateHandle, accept_mouse_state: MouseStateHandle, reject_mouse_state: MouseStateHandle, tab_draggable_state: DraggableState, } #[allow(unused)] #[derive(Clone)] pub struct TabData { location: Option, editor_view: ViewHandle, mouse_state_handles: TabDataMouseStateHandles, drag_position: Option, } impl TabData { /// Returns the file location (local or remote), if any. pub fn location(&self) -> Option<&LocalOrRemotePath> { self.location.as_ref() } /// Returns the local filesystem path, if this tab is backed by a local file. /// Returns `None` for remote files and untitled tabs. pub fn local_path(&self) -> Option { self.location .as_ref() .and_then(|loc| PathBuf::try_from(loc.clone()).ok()) } } pub struct CodeView { pane_configuration: ModelHandle, source: CodeSource, } impl CodeView { pub fn new( source: CodeSource, _line_col: Option, ctx: &mut ViewContext, ) -> Self { let pane_configuration = ctx.add_model(|_ctx| PaneConfiguration::new("")); Self { pane_configuration, source, } } pub fn tab_at(&self, _index: usize) -> Option<&TabData> { None } pub fn tab_count(&self) -> usize { 0 } pub fn active_tab_index(&self) -> usize { 0 } pub fn source(&self) -> &CodeSource { &self.source } pub fn open_or_focus_existing( &mut self, location: Option, line_col: Option, ctx: &mut ViewContext, ) { if let Some(path) = location.and_then(|loc| PathBuf::try_from(loc).ok()) { self.open_local(None, path, line_col, ctx); } } pub fn open_local( &mut self, _diffs: Option>, _path: impl Into, _line_col: Option, _ctx: &mut ViewContext, ) { } pub fn local_path(&self, _ctx: &AppContext) -> Option { None } pub fn focus(&self, _ctx: &mut ViewContext) {} pub fn pane_configuration(&self) -> ModelHandle { self.pane_configuration.clone() } pub fn contains_unsaved_changes(&self, _ctx: &AppContext) -> bool { false } /// Stub: the WASM code view has no tabs, so there is nothing to auto-save /// and no unsaveable changes remain. pub fn auto_save_all_unsaved_tabs(&mut self, _ctx: &mut ViewContext) -> bool { false } pub fn active_tab_shows_unsaved_indicator(&self, _ctx: &AppContext) -> bool { false } pub fn close_overlays(&mut self, _ctx: &mut ViewContext) { // Not yet implemented } pub fn remove_tab_for_move( &mut self, _index: usize, _ctx: &mut ViewContext, ) -> Option { None } } impl Entity for CodeView { type Event = CodeViewEvent; } impl View for CodeView { fn ui_name() -> &'static str { "CodeView" } fn render(&self, _app: &AppContext) -> Box { Empty::new().finish() } } impl TypedActionView for CodeView { type Action = CodeViewAction; fn handle_action(&mut self, _action: &Self::Action, _ctx: &mut ViewContext) {} } impl BackingView for CodeView { type PaneHeaderOverflowMenuAction = CodeViewAction; type CustomAction = (); type AssociatedData = (); fn handle_pane_header_overflow_menu_action( &mut self, _action: &Self::PaneHeaderOverflowMenuAction, _ctx: &mut ViewContext, ) { } fn close(&mut self, ctx: &mut ViewContext) { ctx.emit(CodeViewEvent::Pane(PaneEvent::Close)); } fn focus_contents(&mut self, ctx: &mut ViewContext) { ctx.focus_self(); } fn handle_custom_action( &mut self, _custom_action: &Self::CustomAction, _ctx: &mut ViewContext, ) { } fn render_header_content( &self, _ctx: &HeaderRenderContext<'_>, app: &AppContext, ) -> HeaderContent { HeaderContent::simple(self.pane_configuration.as_ref(app).title()) } fn set_focus_handle(&mut self, _handle: PaneFocusHandle, _ctx: &mut ViewContext) {} }