diff --git a/helix-term/src/compositor.rs b/helix-term/src/compositor.rs index 28c8651a2..af510ed59 100644 --- a/helix-term/src/compositor.rs +++ b/helix-term/src/compositor.rs @@ -15,6 +15,7 @@ pub enum EventResult { Consumed(Option), } +use crate::commands; use crate::job::Jobs; use crate::ui::picker; use helix_view::Editor; diff --git a/helix-term/src/ui/mod.rs b/helix-term/src/ui/mod.rs index b79125f82..b91cfe1cb 100644 --- a/helix-term/src/ui/mod.rs +++ b/helix-term/src/ui/mod.rs @@ -285,6 +285,40 @@ pub fn file_picker(root: PathBuf, config: &helix_view::editor::Config) -> FilePi type FileExplorer = Picker<(PathBuf, bool), (PathBuf, Style)>; +fn create_file_operation_prompt( + prompt: &'static str, + cx: &mut Context, + path: &Path, + callback: fn(&Path, &str), +) { + cx.editor.path_editing = Some(path.to_path_buf()); + let callback = Box::pin(async move { + let call: Callback = Callback::EditorCompositor(Box::new(move |editor, compositor| { + // let path = path.clone(); + let mut prompt = Prompt::new( + prompt.into(), + None, + crate::ui::completers::none, + move |_cx, input: &str, event: PromptEvent| { + if event != PromptEvent::Validate { + return; + }; + + callback(path, input); + }, + ); + + if let Some(path_editing) = &editor.path_editing { + prompt.set_line_no_recalculate(path_editing.display().to_string()); + } + + compositor.push(Box::new(prompt)); + })); + Ok(call) + }); + cx.jobs.callback(callback); +} + pub fn file_explorer(root: PathBuf, editor: &Editor) -> Result { let directory_style = editor.theme.get("ui.text.directory"); let directory_content = directory_content(&root)?; @@ -336,26 +370,19 @@ pub fn file_explorer(root: PathBuf, editor: &Editor) -> Result { - // TODO: ask user for name of file to be created - // Fill in with the picker's current directory - log::error!("create file"); + create_file_operation_prompt("create:", cx, path, |path, input| ()) }, // move alt!('m') => { - // TODO: ask the user for new name of file - // on enter move the file to the new location - log::error!("rename file"); + create_file_operation_prompt("move:", cx, path, |path, input| ()) }, // delete alt!('d') => { - // TODO: ask user for confirmation, while showing which file - // will be deleted - log::error!("delete file"); + create_file_operation_prompt("delete? (y/n):", cx, path, |path, input| ()) }, // copy alt!('y') => { - // TODO: ask the user for new name of file - log::error!("copy file"); + create_file_operation_prompt("copy-to:", cx, path, |path, input| ()) }, }); diff --git a/helix-term/src/ui/prompt.rs b/helix-term/src/ui/prompt.rs index 03adeb05b..5444a78fd 100644 --- a/helix-term/src/ui/prompt.rs +++ b/helix-term/src/ui/prompt.rs @@ -122,6 +122,12 @@ impl Prompt { self.recalculate_completion(editor); } + pub fn set_line_no_recalculate(&mut self, line: String) { + let cursor = line.len(); + self.line = line; + self.cursor = cursor; + } + pub fn with_language( mut self, language: &'static str, diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index 739dcfb49..8e1ccd618 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -1035,6 +1035,7 @@ pub struct Editor { pub tree: Tree, pub next_document_id: DocumentId, pub documents: BTreeMap, + pub path_editing: Option, // We Flatten<> to resolve the inner DocumentSavedEventFuture. For that we need a stream of streams, hence the Once<>. // https://stackoverflow.com/a/66875668 @@ -1223,6 +1224,7 @@ impl Editor { handlers, mouse_down_range: None, cursor_cache: CursorCache::default(), + path_editing: None, } }