@@ -96,6 +96,8 @@ pub struct TerminalScreen { |
| 96 | 96 | scroll_bottom: u16, |
| 97 | 97 | /// Response queue for device status reports |
| 98 | 98 | response_queue: Vec<Vec<u8>>, |
| 99 | + /// Current working directory (from OSC 7) |
| 100 | + pub cwd: Option<String>, |
| 99 | 101 | } |
| 100 | 102 | |
| 101 | 103 | impl TerminalScreen { |
@@ -134,6 +136,8 @@ impl TerminalScreen { |
| 134 | 136 | scroll_bottom: rows.saturating_sub(1), |
| 135 | 137 | // Response queue |
| 136 | 138 | response_queue: Vec::new(), |
| 139 | + // Current working directory |
| 140 | + cwd: None, |
| 137 | 141 | } |
| 138 | 142 | } |
| 139 | 143 | |
@@ -518,7 +522,26 @@ impl Perform for TerminalScreen { |
| 518 | 522 | |
| 519 | 523 | fn unhook(&mut self) {} |
| 520 | 524 | |
| 521 | | - fn osc_dispatch(&mut self, _params: &[&[u8]], _bell_terminated: bool) {} |
| 525 | + fn osc_dispatch(&mut self, params: &[&[u8]], _bell_terminated: bool) { |
| 526 | + // OSC 7: Set working directory |
| 527 | + // Format: OSC 7 ; file://hostname/path ST |
| 528 | + if !params.is_empty() { |
| 529 | + if let Ok(cmd) = std::str::from_utf8(params[0]) { |
| 530 | + if cmd == "7" && params.len() >= 2 { |
| 531 | + if let Ok(url) = std::str::from_utf8(params[1]) { |
| 532 | + // Parse file://hostname/path format |
| 533 | + if let Some(path) = url.strip_prefix("file://") { |
| 534 | + // Find the first slash after hostname |
| 535 | + if let Some(slash_idx) = path.find('/') { |
| 536 | + let dir = &path[slash_idx..]; |
| 537 | + self.cwd = Some(dir.to_string()); |
| 538 | + } |
| 539 | + } |
| 540 | + } |
| 541 | + } |
| 542 | + } |
| 543 | + } |
| 544 | + } |
| 522 | 545 | |
| 523 | 546 | fn csi_dispatch(&mut self, params: &Params, intermediates: &[u8], _ignore: bool, action: char) { |
| 524 | 547 | let params: Vec<u16> = params.iter().map(|p| p.first().copied().unwrap_or(0) as u16).collect(); |