vim: Add support for `:e[dit] {file}` command to open files (#31227)

AidanV created

Closes #17786

Release Notes:

- Adds `:e[dit] {file}` command to open files

Change summary

crates/vim/src/command.rs | 33 ++++++++++++++++++++++++++++++++-
1 file changed, 32 insertions(+), 1 deletion(-)

Detailed changes

crates/vim/src/command.rs 🔗

@@ -166,6 +166,11 @@ struct VimSave {
     pub filename: String,
 }
 
+#[derive(Clone, Deserialize, JsonSchema, PartialEq)]
+struct VimEdit {
+    pub filename: String,
+}
+
 actions!(vim, [VisualCommand, CountCommand, ShellCommand]);
 impl_internal_actions!(
     vim,
@@ -178,6 +183,7 @@ impl_internal_actions!(
         ShellExec,
         VimSet,
         VimSave,
+        VimEdit,
     ]
 );
 
@@ -280,6 +286,30 @@ pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
         });
     });
 
+    Vim::action(editor, cx, |vim, action: &VimEdit, window, cx| {
+        vim.update_editor(window, cx, |vim, editor, window, cx| {
+            let Some(workspace) = vim.workspace(window) else {
+                return;
+            };
+            let Some(project) = editor.project.clone() else {
+                return;
+            };
+            let Some(worktree) = project.read(cx).visible_worktrees(cx).next() else {
+                return;
+            };
+            let project_path = ProjectPath {
+                worktree_id: worktree.read(cx).id(),
+                path: Arc::from(Path::new(&action.filename)),
+            };
+
+            let _ = workspace.update(cx, |workspace, cx| {
+                workspace
+                    .open_path(project_path, None, true, window, cx)
+                    .detach_and_log_err(cx);
+            });
+        });
+    });
+
     Vim::action(editor, cx, |vim, _: &CountCommand, window, cx| {
         let Some(workspace) = vim.workspace(window) else {
             return;
@@ -971,7 +1001,8 @@ fn generate_commands(_: &App) -> Vec<VimCommand> {
         VimCommand::new(("%", ""), EndOfDocument),
         VimCommand::new(("0", ""), StartOfDocument),
         VimCommand::new(("e", "dit"), editor::actions::ReloadFile)
-            .bang(editor::actions::ReloadFile),
+            .bang(editor::actions::ReloadFile)
+            .args(|_, args| Some(VimEdit { filename: args }.boxed_clone())),
         VimCommand::new(("ex", ""), editor::actions::ReloadFile).bang(editor::actions::ReloadFile),
         VimCommand::new(("cpp", "link"), editor::actions::CopyPermalinkToLine).range(act_on_range),
         VimCommand::str(("opt", "ions"), "zed::OpenDefaultSettings"),