tenseleyflow/fackr / d666496

Browse files

fix: command palette char input, create new file from CLI

- Remove control char filter in command palette input (matches other
text inputs, fixes shift key issues)
- Create empty buffer with path when opening non-existent file from CLI
(fackr newfile.rs now creates the file on save)
Authored by espadonne
SHA
d666496492470d419d3e5ce240e20ddeccdce247
Parents
1f538c2
Tree
b33c297

2 changed files

StatusFile+-
M src/editor/state.rs 4 7
M src/workspace/state.rs 53 1
src/editor/state.rsmodified
@@ -4608,13 +4608,10 @@ impl Editor {
46084608
                         }
46094609
                     }
46104610
                     Key::Char(c) => {
4611
-                        // Only accept printable characters
4612
-                        if !c.is_control() {
4613
-                            query.push(c);
4614
-                            *filtered = filter_commands(query);
4615
-                            *selected_index = 0;
4616
-                            *scroll_offset = 0;
4617
-                        }
4611
+                        query.push(c);
4612
+                        *filtered = filter_commands(query);
4613
+                        *selected_index = 0;
4614
+                        *scroll_offset = 0;
46184615
                     }
46194616
                     _ => {}
46204617
                 }
src/workspace/state.rsmodified
@@ -95,6 +95,37 @@ impl BufferEntry {
9595
         }
9696
     }
9797
 
98
+    /// Create an empty buffer for a new file that doesn't exist yet
99
+    pub fn new_file(path: &Path, workspace_root: &Path) -> Self {
100
+        let buffer = Buffer::new();
101
+        let is_orphan = !path.starts_with(workspace_root);
102
+
103
+        // Store relative path for workspace files, absolute for orphans
104
+        let stored_path = if is_orphan {
105
+            path.to_path_buf()
106
+        } else {
107
+            path.strip_prefix(workspace_root)
108
+                .unwrap_or(path)
109
+                .to_path_buf()
110
+        };
111
+
112
+        // Detect language for syntax highlighting
113
+        let mut highlighter = Highlighter::new();
114
+        if let Some(filename) = path.file_name().and_then(|n| n.to_str()) {
115
+            highlighter.detect_language(filename);
116
+        }
117
+
118
+        Self {
119
+            path: Some(stored_path),
120
+            buffer,
121
+            history: History::new(),
122
+            highlighter,
123
+            is_orphan,
124
+            saved_hash: None, // Not saved yet - will prompt on close
125
+            saved_len: None,
126
+        }
127
+    }
128
+
98129
     pub fn from_file(path: &Path, workspace_root: &Path) -> Result<Self> {
99130
         let mut buffer = Buffer::load(path)?;
100131
         let saved_hash = Some(buffer.content_hash()); // Hash at load time
@@ -237,6 +268,16 @@ impl Tab {
237268
         })
238269
     }
239270
 
271
+    /// Create a tab for a new file that doesn't exist yet
272
+    pub fn new_file(path: &Path, workspace_root: &Path) -> Self {
273
+        let buffer_entry = BufferEntry::new_file(path, workspace_root);
274
+        Self {
275
+            buffers: vec![buffer_entry],
276
+            panes: vec![Pane::new()],
277
+            active_pane: 0,
278
+        }
279
+    }
280
+
240281
     /// Create a tab from string content (for diff views, etc.)
241282
     pub fn from_content(content: &str, display_name: &str) -> Self {
242283
         let buffer_entry = BufferEntry::from_content(content, Some(display_name));
@@ -627,9 +668,12 @@ impl Workspace {
627668
 
628669
         let mut workspace = Self::open(root)?;
629670
 
630
-        // Open the file in a tab
671
+        // Open the file in a tab (or create new file if it doesn't exist)
631672
         if abs_path.exists() {
632673
             workspace.open_file(&abs_path)?;
674
+        } else if abs_path.extension().is_some() || abs_path.file_name().is_some() {
675
+            // Path looks like a file (has extension or filename) - create new file buffer
676
+            workspace.open_new_file(&abs_path)?;
633677
         }
634678
 
635679
         Ok(workspace)
@@ -707,6 +751,14 @@ impl Workspace {
707751
         Ok(())
708752
     }
709753
 
754
+    /// Open a new file (doesn't exist yet) in a new tab
755
+    pub fn open_new_file(&mut self, path: &Path) -> Result<()> {
756
+        let tab = Tab::new_file(path, &self.root);
757
+        self.tabs.push(tab);
758
+        self.active_tab = self.tabs.len() - 1;
759
+        Ok(())
760
+    }
761
+
710762
     /// Open a file in a vertical split pane in the current tab
711763
     pub fn open_file_in_vsplit(&mut self, path: &Path) -> Result<()> {
712764
         self.tabs[self.active_tab].split_vertical_with_file(path, &self.root)