diff --git a/app/src/ai/blocklist/action_model/execute/edit_documents.rs b/app/src/ai/blocklist/action_model/execute/edit_documents.rs index b3fd14a2c3..25f8e8d185 100644 --- a/app/src/ai/blocklist/action_model/execute/edit_documents.rs +++ b/app/src/ai/blocklist/action_model/execute/edit_documents.rs @@ -10,7 +10,6 @@ use crate::ai::{ }, document::ai_document_model::{AIDocumentId, AIDocumentModel, AIDocumentUpdateSource}, }; -use crate::notebooks::post_process_notebook; use super::{ActionExecution, AnyActionExecution, ExecuteActionInput, PreprocessActionInput}; @@ -66,8 +65,8 @@ impl EditDocumentsExecutor { // Apply the diff using fuzzy matching logic let search_replace = ai::diff_validation::SearchAndReplace { - search: post_process_notebook(&diff.search), - replace: post_process_notebook(&diff.replace), + search: diff.search.clone(), + replace: diff.replace.clone(), }; let content_name = format!("document_{}", diff.document_id); diff --git a/app/src/ai/document/ai_document_model.rs b/app/src/ai/document/ai_document_model.rs index dc88173835..1a1e6c8daf 100644 --- a/app/src/ai/document/ai_document_model.rs +++ b/app/src/ai/document/ai_document_model.rs @@ -32,7 +32,7 @@ use crate::{ model::{FileLinkResolutionContext, NotebooksEditorModel, RichTextEditorModelEvent}, rich_text_styles, }, - post_process_notebook, CloudNotebookModel, NotebookId, + CloudNotebookModel, NotebookId, }, server::{ cloud_objects::update_manager::{ @@ -522,7 +522,7 @@ impl AIDocumentModel { doc.title = new_title.to_owned(); let editor_handle = doc.editor.clone(); editor_handle.update(ctx, |editor, editor_ctx| { - editor.update_to_new_markdown(&post_process_notebook(new_content), editor_ctx); + editor.update_to_new_markdown(new_content, editor_ctx); }); ctx.emit(AIDocumentModelEvent::DocumentUpdated { @@ -776,8 +776,7 @@ impl AIDocumentModel { log::info!("Applying persisted SQLite content for document {id} (content differs from conversation restoration)"); doc.editor.update(ctx, |editor, editor_ctx| { - let processed = post_process_notebook(persisted_content); - editor.reset_with_markdown(&processed, editor_ctx); + editor.reset_with_markdown(persisted_content, editor_ctx); }); // Mark as dirty so the updated plan is attached to the next agent query @@ -830,9 +829,7 @@ impl AIDocumentModel { let content = content.into(); if !content.is_empty() { - // Post-process the content to remove extra newlines - let processed_content = post_process_notebook(&content); - model.reset_with_markdown(&processed_content, ctx); + model.reset_with_markdown(&content, ctx); } model }) @@ -961,8 +958,7 @@ impl AIDocumentModel { if let Some(doc) = self.create_new_document_version(id, ctx) { let content = new_content.into(); doc.editor.update(ctx, |editor, editor_ctx| { - let processed_content = post_process_notebook(&content); - editor.reset_with_markdown(&processed_content, editor_ctx); + editor.reset_with_markdown(&content, editor_ctx); }); doc.created_at = created_at; ctx.emit(AIDocumentModelEvent::DocumentUpdated { diff --git a/app/src/code/editor/comment_editor.rs b/app/src/code/editor/comment_editor.rs index 856013aac3..54bc808fb5 100644 --- a/app/src/code/editor/comment_editor.rs +++ b/app/src/code/editor/comment_editor.rs @@ -423,8 +423,8 @@ impl View for CommentEditor { ) .with_child( Container::new(footer_row) - .with_vertical_padding(8.) - .with_horizontal_padding(8.) + .with_vertical_padding(4.) + .with_horizontal_padding(4.) .with_border(Border::top(1.).with_border_fill(border_color)) .finish(), ) diff --git a/app/src/drive/import/nodes.rs b/app/src/drive/import/nodes.rs index 004a5b3342..d7690a51f7 100644 --- a/app/src/drive/import/nodes.rs +++ b/app/src/drive/import/nodes.rs @@ -1,6 +1,5 @@ use crate::{ drive::{cloud_object_styling::warp_drive_icon_color, DriveObjectType}, - notebooks::post_process_notebook, workflows::{ export_workflow::export_deserialize, workflow::Workflow, workflow_enum::WorkflowEnum, }, @@ -897,9 +896,7 @@ impl FileUploadState { pub(super) async fn parse_file(path: PathBuf, file_type: FileType) -> Result { match file_type { - FileType::Notebook => Ok(FileContent::Notebook(post_process_notebook( - &async_fs::read_to_string(path).await?, - ))), + FileType::Notebook => Ok(FileContent::Notebook(async_fs::read_to_string(path).await?)), FileType::Workflow => { let file = async_fs::read(path).await?; let mut workflow_enums: HashMap = HashMap::new(); diff --git a/app/src/notebooks/editor/mod.rs b/app/src/notebooks/editor/mod.rs index 3732c4449b..6b4cc43188 100644 --- a/app/src/notebooks/editor/mod.rs +++ b/app/src/notebooks/editor/mod.rs @@ -11,11 +11,15 @@ use warp_editor::{ }, render::model::{ BrokenLinkStyle, CheckBoxStyle, EmbeddedItem, HorizontalRuleStyle, InlineCodeStyle, - ParagraphStyles, RichTextStyles, TableStyle, PARAGRAPH_MIN_HEIGHT, + ParagraphStyles, RichTextStyles, TableStyle, }, }; use warp_util::user_input::UserInput; -use warpui::{elements::Border, fonts::FamilyId, ui_components::checkbox::HOVER_BACKGROUND_COLOR}; +use warpui::{ + elements::{Border, ListIndentLevel}, + fonts::FamilyId, + ui_components::checkbox::HOVER_BACKGROUND_COLOR, +}; use crate::{ appearance::Appearance, @@ -40,9 +44,7 @@ mod omnibar; pub mod view; pub use block_insertion_menu::BlockInsertionSource; -use warpui::elements::ListIndentLevel; - -const NOTEBOOK_LINE_HEIGHT_RATIO: f32 = 1.6; +const NOTEBOOK_LINE_HEIGHT_RATIO: f32 = 1.5; const NOTEBOOK_BASELINE_RATIO: f32 = 0.7; #[derive(Clone, Copy)] @@ -202,26 +204,31 @@ pub(crate) fn markdown_table_style( /// Build [`RichTextStyles`] based on the current [`Appearance`]. pub fn rich_text_styles(appearance: &Appearance, font_settings: &FontSettings) -> RichTextStyles { + let line_height_ratio = NOTEBOOK_LINE_HEIGHT_RATIO; + let baseline_ratio = NOTEBOOK_BASELINE_RATIO; let theme = appearance.theme(); let inline_font_color: ColorU = theme.terminal_colors().normal.red.into(); let font_size = derived_notebook_font_size(font_settings); + + let base_text = ParagraphStyles { + font_size, + font_weight: Default::default(), + line_height_ratio, + font_family: appearance.ui_font_family(), + text_color: theme.main_text_color(theme.background()).into_solid(), + baseline_ratio, + fixed_width_tab_size: None, + }; + RichTextStyles { - base_text: ParagraphStyles { - font_size, - font_weight: Default::default(), - line_height_ratio: NOTEBOOK_LINE_HEIGHT_RATIO, - font_family: appearance.ui_font_family(), - text_color: theme.main_text_color(theme.background()).into_solid(), - baseline_ratio: NOTEBOOK_BASELINE_RATIO, - fixed_width_tab_size: None, - }, + base_text, code_text: ParagraphStyles { font_family: appearance.monospace_font_family(), font_size, font_weight: Default::default(), - line_height_ratio: NOTEBOOK_LINE_HEIGHT_RATIO, + line_height_ratio, text_color: theme.main_text_color(theme.background()).into_solid(), - baseline_ratio: NOTEBOOK_BASELINE_RATIO, + baseline_ratio, fixed_width_tab_size: Some(4), }, code_background: theme.background().into(), @@ -229,10 +236,10 @@ pub fn rich_text_styles(appearance: &Appearance, font_settings: &FontSettings) - embedding_text: ParagraphStyles { font_size, font_weight: Default::default(), - line_height_ratio: NOTEBOOK_LINE_HEIGHT_RATIO, + line_height_ratio, font_family: appearance.monospace_font_family(), text_color: theme.main_text_color(theme.surface_2()).into_solid(), - baseline_ratio: NOTEBOOK_BASELINE_RATIO, + baseline_ratio, fixed_width_tab_size: Some(4), }, code_border: Border::all(1.).with_border_fill(theme.surface_3()), @@ -268,8 +275,8 @@ pub fn rich_text_styles(appearance: &Appearance, font_settings: &FontSettings) - }, block_spacings: Default::default(), show_placeholder_text_on_empty_block: true, - minimum_paragraph_height: Some(PARAGRAPH_MIN_HEIGHT), - cursor_width: 1., + minimum_paragraph_height: Some(base_text.line_height()), + cursor_width: 3., highlight_urls: true, table_style: markdown_table_style(appearance, appearance.ui_font_family(), font_size), } diff --git a/app/src/notebooks/file/mod.rs b/app/src/notebooks/file/mod.rs index 7526fd9a02..aa2edd5a0c 100644 --- a/app/src/notebooks/file/mod.rs +++ b/app/src/notebooks/file/mod.rs @@ -25,8 +25,6 @@ use warpui::{ ViewHandle, }; -#[cfg(feature = "local_fs")] -use crate::notebooks::post_process_notebook; use crate::{ appearance::Appearance, cmd_or_ctrl_shift, @@ -415,8 +413,7 @@ impl FileNotebookView { } match event { FileModelEvent::FileLoaded { content, .. } => { - let cleaned = post_process_notebook(content); - me.set_content(&cleaned, ctx); + me.set_content(content, ctx); send_telemetry_from_ctx!( TelemetryEvent::OpenNotebook(me.open_telemetry_metadata(ctx)), ctx @@ -457,8 +454,7 @@ impl FileNotebookView { ctx.notify(); } FileModelEvent::FileUpdated { content, .. } => { - let cleaned = post_process_notebook(content); - me.set_content(&cleaned, ctx); + me.set_content(content, ctx); } FileModelEvent::FileSaved { .. } | FileModelEvent::FailedToSave { .. } => {} } diff --git a/app/src/notebooks/mod.rs b/app/src/notebooks/mod.rs index d3dba78b9b..611a0d3952 100644 --- a/app/src/notebooks/mod.rs +++ b/app/src/notebooks/mod.rs @@ -13,7 +13,6 @@ use std::sync::Arc; use async_trait::async_trait; use anyhow::Result; -use itertools::Itertools; use serde::{Deserialize, Serialize}; use warpui::AppContext; @@ -253,15 +252,6 @@ pub fn init(app: &mut AppContext) { self::editor::view::init(app); } -/// Post process a notebook's content read from an external system. This cleans up extra -/// whitespace, and, in the future, may filter out unsupported syntax extensions. -/// -/// See CLD-944. -pub fn post_process_notebook(data: &str) -> String { - // TODO(kevin): We should not strip out newlines in the code block. - data.lines().filter(|line| !line.is_empty()).join("\n") -} - /// Translate a notebook's Markdown content into an external Markdown format. /// /// This: diff --git a/crates/editor/src/render/mod_tests.rs b/crates/editor/src/render/mod_tests.rs index 7edc3294dd..13e97bb943 100644 --- a/crates/editor/src/render/mod_tests.rs +++ b/crates/editor/src/render/mod_tests.rs @@ -323,7 +323,7 @@ Task List @ 1 [X] (2 characters, 1 lines, 18.00px tall) -------- 18.00px / 2 characters -------- Task List @ 1 [ ] (2 characters, 1 lines, 18.00px tall) -------- 36.00px / 4 characters -------- -Trailing Newline (1 characters, 1 lines, 32.00px tall) +Trailing Newline (1 characters, 1 lines, 24.00px tall) "#, ); @@ -344,7 +344,7 @@ Task List @ 1 [ ] (2 characters, 1 lines, 18.00px tall) -------- 54.00px / 6 characters -------- Task List @ 1 [ ] (2 characters, 1 lines, 18.00px tall) -------- 72.00px / 8 characters -------- -Trailing Newline (1 characters, 1 lines, 32.00px tall) +Trailing Newline (1 characters, 1 lines, 24.00px tall) "#, ) }); diff --git a/crates/editor/src/render/model/mod.rs b/crates/editor/src/render/model/mod.rs index eb9f60fa93..1feeb7a781 100644 --- a/crates/editor/src/render/model/mod.rs +++ b/crates/editor/src/render/model/mod.rs @@ -107,7 +107,7 @@ const TABLE_SCROLL_REVEAL_MARGIN: Pixels = Pixels::new(8.); pub const EMBEDDED_ITEM_FIRST_LINE_HEIGHT: f32 = 24.; pub const TEXT_SPACING: BlockSpacing = BlockSpacing { - margin: Margin::uniform(4.).with_right(16.), + margin: Margin::uniform(0.).with_right(16.), padding: Padding::uniform(0.), }; @@ -139,8 +139,8 @@ pub const BROKEN_LINK_SPACING: BlockSpacing = BlockSpacing { pub const HEADER_SPACING: BlockSpacing = BlockSpacing { margin: Margin::uniform(4.) - .with_top(12.) - .with_bottom(12.) + .with_top(4.) + .with_bottom(4.) .with_right(16.), padding: Padding::uniform(0.), };