diff --git a/README.md b/README.md index 2738b70..ba7a165 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,8 @@ Though just `cargo run --release` can be done. ## Config +Config files should be protected so they can only be written to with root privileges. + ### Desktop Backgrounds In `$XDG_CONFIG_DIR/ming-wm/desktop-background`, you can configure what the desktop background should be for each workspace. The first line decides the background for the first workspace, and so on. If lines are missing, or empty, or the config file is missing, the default green background is used. diff --git a/src/bin/file_explorer.rs b/src/bin/file_explorer.rs new file mode 100644 index 0000000..abcb8b9 --- /dev/null +++ b/src/bin/file_explorer.rs @@ -0,0 +1,74 @@ +use std::vec::Vec; +use std::vec; +use std::fs::read_dir; + +use ming_wm::window_manager::{ DrawInstructions, WindowLike, WindowLikeType }; +use ming_wm::messages::{ WindowMessage, WindowMessageResponse }; +use ming_wm::framebuffer::Dimensions; +use ming_wm::themes::ThemeInfo; +use ming_wm::ipc::listen; + +#[derive(Default)] +pub struct FileExplorer { + dimensions: Dimensions, + current_path: String, + //current_dir_contents: +} + +impl WindowLike for FileExplorer { + fn handle_message(&mut self, message: WindowMessage) -> WindowMessageResponse { + match message { + WindowMessage::Init(dimensions) => { + self.current_path = "/".to_string(); + self.dimensions = dimensions; + WindowMessageResponse::JustRerender + }, + WindowMessage::ChangeDimensions(dimensions) => { + self.dimensions = dimensions; + WindowMessageResponse::JustRerender + }, + WindowMessage::KeyPress(key_press) => { + // + WindowMessageResponse::DoNothing + }, + _ => WindowMessageResponse::DoNothing, + } + } + + fn draw(&self, theme_info: &ThemeInfo) -> Vec { + //top bar with path name and editing + vec![] + } + + fn title(&self) -> String { + "File Explorer".to_string() + } + + fn subtype(&self) -> WindowLikeType { + WindowLikeType::Window + } + + fn ideal_dimensions(&self, _dimensions: Dimensions) -> Dimensions { + [410, 410] + } + + fn resizable(&self) -> bool { + true + } +} + +impl FileExplorer { + pub fn new() -> Self { + Default::default() + } + + //should include .. if not / + fn read_current_dir_contents(&self) { + // + } +} + +pub fn main() { + listen(FileExplorer::new()); +} + diff --git a/src/bin/malvim.rs b/src/bin/malvim.rs index e36e0de..f316515 100644 --- a/src/bin/malvim.rs +++ b/src/bin/malvim.rs @@ -79,6 +79,7 @@ struct Malvim { files: Vec, current_file_index: usize, current: Current, + autoindent: bool, } impl WindowLike for Malvim { @@ -110,9 +111,23 @@ impl WindowLike for Malvim { let mut line = line.clone(); let (left, right) = line.split_at_mut(current_file.cursor_pos); current_file.content[current_file.line_pos] = left.to_string(); - current_file.content.insert(current_file.line_pos + 1, right.to_string()); + let spaces = if self.autoindent { + //find out how many spaces the line starts with, copy that to the new line + let mut spaces = 0; + for c in left.chars() { + if c == ' ' { + spaces += 1; + } else { + break; + } + } + spaces + } else { + 0 + }; + current_file.content.insert(current_file.line_pos + 1, " ".repeat(spaces) + right); current_file.line_pos += 1; - current_file.cursor_pos = 0; + current_file.cursor_pos = spaces; } else if key_press.key == '𐘁' { //backspace if current_length > 0 && current_file.cursor_pos > 0 { current_file.content[current_file.line_pos] = line.remove(current_file.cursor_pos, 1); @@ -134,6 +149,7 @@ impl WindowLike for Malvim { } else if self.mode == Mode::Normal && self.files.len() > 0 { let current_file = &mut self.files[self.current_file_index]; let current_length = current_file.content[current_file.line_pos].len(); + let mut numbered = false; // if self.state == State::Replace { if current_length > 0 && current_file.cursor_pos < current_length { @@ -164,10 +180,14 @@ impl WindowLike for Malvim { self.state = State::None; } else if self.state == State::Maybeg { if key_press.key == 'g' { - current_file.line_pos = 0; + current_file.line_pos = self.maybe_num.unwrap_or(0); + if current_file.line_pos >= current_file.content.len() { + current_file.line_pos = current_file.content.len() - 1; + } let new_length = current_file.content[current_file.line_pos].len(); current_file.cursor_pos = calc_new_cursor_pos(current_file.cursor_pos, new_length); } + changed = false; self.state = State::None; } else if self.state == State::Find || self.state == State::BackFind { let old_pos = current_file.cursor_pos; @@ -209,7 +229,7 @@ impl WindowLike for Malvim { } } changed = false; - } else if key_press.key == '0' { + } else if key_press.key == '0' && self.maybe_num.is_none() { current_file.cursor_pos = 0; changed = false; } else if key_press.key == '$' { @@ -239,6 +259,13 @@ impl WindowLike for Malvim { } else if key_press.key == 'F' { self.state = State::BackFind; changed = false; + } else if key_press.key.is_digit(10) { + self.maybe_num = Some(self.maybe_num.unwrap_or(0) * 10 + key_press.key.to_digit(10).unwrap() as usize); + numbered = true; + changed = false; + } + if !numbered && self.state != State::Maybeg { + self.maybe_num = None; } // } else if self.mode == Mode::Command { @@ -419,7 +446,10 @@ impl Malvim { let mut parts = self.command.as_ref().unwrap().split(" "); let first = parts.next().unwrap(); let arg = parts.next().unwrap_or(""); - if first == "e" || first == "edit" || ((first == "t" || first == "tabe") && self.files.len() > 0) { + if first == "autoindent" { + self.autoindent = !self.autoindent; + self.bottom_message = Some("Autoindent: ".to_string() + &self.autoindent.to_string()); + } else if first == "e" || first == "edit" || ((first == "t" || first == "tabe") && self.files.len() > 0) { //find the file and open it let mut failed = false; let mut new_path = if self.files.len() > 0 { @@ -477,7 +507,7 @@ impl Malvim { self.bottom_message = Some("No files are open, so can only do :e(dit)".to_string()); } else if first == "w" || first == "write" { let current_file = &self.files[self.current_file_index]; - write(¤t_file.path, ¤t_file.content.join("\n")); + let _ = write(¤t_file.path, ¤t_file.content.join("\n")); self.files[self.current_file_index].changed = false; } else if first == "q" || first == "quit" { self.files.remove(self.current_file_index); diff --git a/src/essential/start_menu.rs b/src/essential/start_menu.rs index 58f74e5..cbae2b8 100644 --- a/src/essential/start_menu.rs +++ b/src/essential/start_menu.rs @@ -151,7 +151,7 @@ impl StartMenu { } else if name == "Utils" { to_add.push("Terminal"); } else if name == "Files" { - to_add.push("Audio Player"); + to_add.extend(["File Explorer", "Audio Player"]); } // for a in 0..to_add.len() { diff --git a/src/window_manager.rs b/src/window_manager.rs index ec515ee..47480f2 100644 --- a/src/window_manager.rs +++ b/src/window_manager.rs @@ -517,6 +517,7 @@ impl WindowManager { "Malvim" => Some(Box::new(ProxyWindowLike::new_rust("malvim"))), "Terminal" => Some(Box::new(ProxyWindowLike::new_rust("terminal"))), "Audio Player" => Some(Box::new(ProxyWindowLike::new_rust("audio_player"))), + "File Explorer" => Some(Box::new(ProxyWindowLike::new_rust("file_explorer"))), "StartMenu" => Some(Box::new(StartMenu::new())), _ => None, };