tenseleyflow/fackr / cae12ce

Browse files

feat: parse OSC 7 for terminal working directory

Add CWD tracking to TerminalScreen:
- Add cwd field to store current working directory
- Implement osc_dispatch to parse OSC 7 sequences
- Extract path from file://hostname/path format
- Fish shell emits OSC 7 automatically on directory change
Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
cae12ce4af3bab111cde09cd12eddfcb9ab73449
Parents
4d05e34
Tree
d2e3a5d

1 changed file

StatusFile+-
M src/terminal/screen.rs 24 1
src/terminal/screen.rsmodified
@@ -96,6 +96,8 @@ pub struct TerminalScreen {
9696
     scroll_bottom: u16,
9797
     /// Response queue for device status reports
9898
     response_queue: Vec<Vec<u8>>,
99
+    /// Current working directory (from OSC 7)
100
+    pub cwd: Option<String>,
99101
 }
100102
 
101103
 impl TerminalScreen {
@@ -134,6 +136,8 @@ impl TerminalScreen {
134136
             scroll_bottom: rows.saturating_sub(1),
135137
             // Response queue
136138
             response_queue: Vec::new(),
139
+            // Current working directory
140
+            cwd: None,
137141
         }
138142
     }
139143
 
@@ -518,7 +522,26 @@ impl Perform for TerminalScreen {
518522
 
519523
     fn unhook(&mut self) {}
520524
 
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
+    }
522545
 
523546
     fn csi_dispatch(&mut self, params: &Params, intermediates: &[u8], _ignore: bool, action: char) {
524547
         let params: Vec<u16> = params.iter().map(|p| p.first().copied().unwrap_or(0) as u16).collect();