@@ -567,6 +567,33 @@ fn terminal_tab_duplicate_supported(source: &TerminalDuplicateSource) -> bool {
567567 )
568568}
569569
570+ fn terminal_duplicate_source_with_cwd (
571+ source : TerminalDuplicateSource ,
572+ current_working_dir : Option < & str > ,
573+ ) -> TerminalDuplicateSource {
574+ let Some ( cwd) = current_working_dir. filter ( |cwd| !cwd. trim ( ) . is_empty ( ) ) else {
575+ return source;
576+ } ;
577+ let cwd = cwd. to_string ( ) ;
578+
579+ match source {
580+ TerminalDuplicateSource :: Local ( mut config) => {
581+ config. working_dir = Some ( cwd) ;
582+ TerminalDuplicateSource :: Local ( config)
583+ }
584+ TerminalDuplicateSource :: Ssh {
585+ connection,
586+ sync_path_with_terminal,
587+ ..
588+ } => TerminalDuplicateSource :: Ssh {
589+ connection,
590+ working_dir : Some ( cwd) ,
591+ sync_path_with_terminal,
592+ } ,
593+ TerminalDuplicateSource :: Serial ( connection) => TerminalDuplicateSource :: Serial ( connection) ,
594+ }
595+ }
596+
570597/// Terminal view component - supports both Local and SSH backends
571598pub struct TerminalView {
572599 /// Terminal model entity
@@ -4554,7 +4581,15 @@ impl TabContent for TerminalView {
45544581 window : & mut Window ,
45554582 cx : & mut Context < Self > ,
45564583 ) -> Option < Arc < dyn TabContentView > > {
4557- let source = self . duplicate_source . clone ( ) ;
4584+ let current_working_dir = self
4585+ . terminal
4586+ . read ( cx)
4587+ . current_working_dir ( )
4588+ . map ( str:: to_string) ;
4589+ let source = terminal_duplicate_source_with_cwd (
4590+ self . duplicate_source . clone ( ) ,
4591+ current_working_dir. as_deref ( ) ,
4592+ ) ;
45584593 let duplicate = cx. new ( |cx| match source {
45594594 TerminalDuplicateSource :: Local ( config) => {
45604595 TerminalView :: new_with_index ( config, None , window, cx)
@@ -5164,7 +5199,8 @@ mod tests {
51645199 should_reset_history_prompt_for_terminal_event, should_scroll_to_bottom_on_user_input,
51655200 should_start_block_selection, should_start_selection_from_pending_sgr_press,
51665201 should_upload_clipboard_image_to_remote_cli, take_whole_scroll_lines,
5167- terminal_history_scope, terminal_tab_duplicate_supported, wrapped_addon_line_text,
5202+ terminal_duplicate_source_with_cwd, terminal_history_scope,
5203+ terminal_tab_duplicate_supported, wrapped_addon_line_text,
51685204 } ;
51695205 use crate :: history_prompt:: { HistoryPromptAccept , HistoryPromptState } ;
51705206 use alacritty_terminal:: index:: { Column , Line , Point as AlacPoint } ;
@@ -5275,6 +5311,78 @@ mod tests {
52755311 ) ) ;
52765312 }
52775313
5314+ #[ test]
5315+ fn duplicate_source_for_local_terminal_prefers_current_working_dir ( ) {
5316+ let mut config = LocalConfig :: default ( ) ;
5317+ config. working_dir = Some ( "/tmp/original" . to_string ( ) ) ;
5318+
5319+ let source = terminal_duplicate_source_with_cwd (
5320+ TerminalDuplicateSource :: Local ( config) ,
5321+ Some ( "/tmp/current" ) ,
5322+ ) ;
5323+
5324+ let TerminalDuplicateSource :: Local ( config) = source else {
5325+ panic ! ( "expected local duplicate source" ) ;
5326+ } ;
5327+ assert_eq ! ( Some ( "/tmp/current" ) , config. working_dir. as_deref( ) ) ;
5328+ }
5329+
5330+ #[ test]
5331+ fn duplicate_source_keeps_original_local_dir_when_current_dir_is_blank ( ) {
5332+ let mut config = LocalConfig :: default ( ) ;
5333+ config. working_dir = Some ( "/tmp/original" . to_string ( ) ) ;
5334+
5335+ let source =
5336+ terminal_duplicate_source_with_cwd ( TerminalDuplicateSource :: Local ( config) , Some ( " " ) ) ;
5337+
5338+ let TerminalDuplicateSource :: Local ( config) = source else {
5339+ panic ! ( "expected local duplicate source" ) ;
5340+ } ;
5341+ assert_eq ! ( Some ( "/tmp/original" ) , config. working_dir. as_deref( ) ) ;
5342+ }
5343+
5344+ #[ test]
5345+ fn duplicate_source_for_ssh_terminal_prefers_current_working_dir ( ) {
5346+ let ssh = StoredConnection :: new_ssh (
5347+ "ssh" . to_string ( ) ,
5348+ SshParams {
5349+ host : "localhost" . to_string ( ) ,
5350+ port : 22 ,
5351+ username : "user" . to_string ( ) ,
5352+ auth_method : SshAuthMethod :: Agent ,
5353+ connect_timeout : None ,
5354+ keepalive_interval : None ,
5355+ keepalive_max : None ,
5356+ default_directory : None ,
5357+ init_script : None ,
5358+ disable_shell_integration : None ,
5359+ jump_server : None ,
5360+ proxy : None ,
5361+ } ,
5362+ None ,
5363+ ) ;
5364+
5365+ let source = terminal_duplicate_source_with_cwd (
5366+ TerminalDuplicateSource :: Ssh {
5367+ connection : ssh,
5368+ working_dir : Some ( "/srv/original" . to_string ( ) ) ,
5369+ sync_path_with_terminal : true ,
5370+ } ,
5371+ Some ( "/srv/current" ) ,
5372+ ) ;
5373+
5374+ let TerminalDuplicateSource :: Ssh {
5375+ working_dir,
5376+ sync_path_with_terminal,
5377+ ..
5378+ } = source
5379+ else {
5380+ panic ! ( "expected ssh duplicate source" ) ;
5381+ } ;
5382+ assert_eq ! ( Some ( "/srv/current" ) , working_dir. as_deref( ) ) ;
5383+ assert ! ( sync_path_with_terminal) ;
5384+ }
5385+
52785386 #[ test]
52795387 fn terminal_history_scope_matches_supported_connection_kinds ( ) {
52805388 let local = terminal_history_scope ( TerminalConnectionKind :: Local , None )
0 commit comments