diff --git a/crates/project/src/terminals.rs b/crates/project/src/terminals.rs index 6e24259ebd..b64988f8c8 100644 --- a/crates/project/src/terminals.rs +++ b/crates/project/src/terminals.rs @@ -393,6 +393,27 @@ impl Project { }) .detach(); + + terminal_handle.update(cx, |terminal, _| { + if terminal.pending_initialization { + let shell_name = terminal + .pty_info + .current + .as_ref() + .map(|process| process.name.to_lowercase()) + .unwrap_or_default(); + let restore_command = if shell_name.contains("fish") { + "if set -q ZED_ORIGINAL_PATH; set -gx PATH $ZED_ORIGINAL_PATH; set -e ZED_ORIGINAL_PATH; end" + } else { + "if [ ! -z \"$ZED_ORIGINAL_PATH\" ]; then export PATH=\"$ZED_ORIGINAL_PATH\"; unset ZED_ORIGINAL_PATH; fi" + }; + terminal.input(restore_command.to_string()); + terminal.clear(); + terminal.initialized(); + } + }); + + if let Some(activate_command) = python_venv_activate_command { this.activate_python_virtual_environment(activate_command, &terminal_handle, cx); } diff --git a/crates/terminal/src/terminal.rs b/crates/terminal/src/terminal.rs index 954dbf4cb8..9b3058e42f 100644 --- a/crates/terminal/src/terminal.rs +++ b/crates/terminal/src/terminal.rs @@ -131,8 +131,9 @@ pub enum MaybeNavigationTarget { PathLike(PathLikeTarget), } -#[derive(Clone)] +#[derive(Clone, Debug)] enum InternalEvent { + Initialized, Resize(TerminalBounds), Clear, // FocusNextMatch, @@ -372,6 +373,10 @@ impl TerminalBuilder { release_channel::AppVersion::global(cx).to_string(), ); + if let Some(path) = env.get("PATH").cloned() { + env.insert("ZED_ORIGINAL_PATH".to_string(), path); + } + let mut terminal_title_override = None; let pty_options = { @@ -505,6 +510,7 @@ impl TerminalBuilder { debug_terminal, is_ssh_terminal, python_venv_directory, + pending_initialization: cfg!(not(target_os = "windows")), }; Ok(TerminalBuilder { @@ -662,6 +668,7 @@ pub struct Terminal { vi_mode_enabled: bool, debug_terminal: bool, is_ssh_terminal: bool, + pub pending_initialization: bool, } pub struct TaskState { @@ -781,6 +788,9 @@ impl Terminal { cx: &mut Context, ) { match event { + &InternalEvent::Initialized => { + self.pending_initialization = false; + } &InternalEvent::Resize(mut new_bounds) => { new_bounds.bounds.size.height = cmp::max(new_bounds.line_height, new_bounds.height()); @@ -1243,6 +1253,10 @@ impl Terminal { self.write_bytes_to_pty(input); } + pub fn initialized(&mut self) { + self.events.push_back(InternalEvent::Initialized); + } + pub fn toggle_vi_mode(&mut self) { self.events.push_back(InternalEvent::ToggleViMode); } @@ -1389,7 +1403,10 @@ impl Terminal { let mut terminal = term.lock_unfair(); //Note that the ordering of events matters for event processing while let Some(e) = self.events.pop_front() { - self.process_terminal_event(&e, &mut terminal, window, cx) + println!("processing event"); + dbg!(&e); + self.process_terminal_event(&e, &mut terminal, window, cx); + dbg!(&self.pending_initialization); } self.last_content = Self::make_content(&terminal, &self.last_content); diff --git a/crates/terminal_view/src/terminal_element.rs b/crates/terminal_view/src/terminal_element.rs index 66a7b83771..ba8da70269 100644 --- a/crates/terminal_view/src/terminal_element.rs +++ b/crates/terminal_view/src/terminal_element.rs @@ -47,6 +47,7 @@ pub struct LayoutState { hyperlink_tooltip: Option, gutter: Pixels, block_below_cursor_element: Option, + pending_initialization: bool, } /// Helper struct for converting data between Alacritty's cursor points, and displayed cursor points. @@ -743,19 +744,22 @@ impl Element for TerminalElement { .push((selection.start..=selection.end, player_color.selection)); } - // then have that representation be converted to the appropriate highlight data structure - - let (cells, rects) = TerminalElement::layout_grid( - cells.iter().cloned(), - &text_style, - window.text_system(), - last_hovered_word - .as_ref() - .map(|last_hovered_word| (link_style, &last_hovered_word.word_match)), - window, - cx, - ); - + let pending_initialization = self.terminal.read(cx).pending_initialization; + let (cells, rects) = if pending_initialization { + (Vec::new(), Vec::new()) + } else { + // then have that representation be converted to the appropriate highlight data structure + TerminalElement::layout_grid( + cells.iter().cloned(), + &text_style, + window.text_system(), + last_hovered_word + .as_ref() + .map(|last_hovered_word| (link_style, &last_hovered_word.word_match)), + window, + cx, + ) + }; // Layout cursor. Rectangle is used for IME, so we should lay it out even // if we don't end up showing it. let cursor = if let AlacCursorShape::Hidden = cursor.shape { @@ -852,6 +856,7 @@ impl Element for TerminalElement { hyperlink_tooltip, gutter, block_below_cursor_element, + pending_initialization, } }, ) @@ -921,35 +926,41 @@ impl Element for TerminalElement { rect.paint(origin, &layout.dimensions, window); } - for (relative_highlighted_range, color) in - layout.relative_highlighted_ranges.iter() - { - if let Some((start_y, highlighted_range_lines)) = - to_highlighted_range_lines(relative_highlighted_range, layout, origin) + if !layout.pending_initialization { + for (relative_highlighted_range, color) in + layout.relative_highlighted_ranges.iter() { - let hr = HighlightedRange { - start_y, - line_height: layout.dimensions.line_height, - lines: highlighted_range_lines, - color: *color, - corner_radius: 0.15 * layout.dimensions.line_height, - }; - hr.paint(bounds, window); + if let Some((start_y, highlighted_range_lines)) = + to_highlighted_range_lines( + relative_highlighted_range, + layout, + origin, + ) + { + let hr = HighlightedRange { + start_y, + line_height: layout.dimensions.line_height, + lines: highlighted_range_lines, + color: *color, + corner_radius: 0.15 * layout.dimensions.line_height, + }; + hr.paint(bounds, window); + } } - } - for cell in &layout.cells { - cell.paint(origin, &layout.dimensions, bounds, window, cx); - } - - if self.cursor_visible { - if let Some(mut cursor) = cursor { - cursor.paint(origin, window, cx); + for cell in &layout.cells { + cell.paint(origin, &layout.dimensions, bounds, window, cx); } - } - if let Some(mut element) = block_below_cursor_element { - element.paint(window, cx); + if self.cursor_visible { + if let Some(mut cursor) = cursor { + cursor.paint(origin, window, cx); + } + } + + if let Some(mut element) = block_below_cursor_element { + element.paint(window, cx); + } } if let Some(mut element) = hyperlink_tooltip {