copy paste shortcuts, file explorer scrolling

malvim find in file with /
This commit is contained in:
stjet
2024-12-27 23:58:45 +00:00
parent 606d8bf67f
commit acdb59d668
5 changed files with 104 additions and 21 deletions

View File

@@ -9,6 +9,8 @@ use ming_wm::framebuffer::Dimensions;
use ming_wm::themes::ThemeInfo;
use ming_wm::ipc::listen;
const HEIGHT: usize = 20;
struct DirectoryChild {
//if some, use instead of file/dir name
override_name: Option<String>,
@@ -26,6 +28,7 @@ pub struct FileExplorer {
current_dir_contents: Vec<DirectoryChild>,
//for scrolling and selecting dirs
position: usize,
top_position: usize,
}
impl WindowLike for FileExplorer {
@@ -49,25 +52,36 @@ impl WindowLike for FileExplorer {
self.current_path = selected_entry.path.clone();
self.current_dir_contents = self.get_current_dir_contents();
self.position = 0;
self.top_position = 0;
return WindowMessageResponse::JustRerender;
}
}
WindowMessageResponse::DoNothing
} else if key_press.key == 'j' {
//down
if self.position == self.current_dir_contents.len() - 1 {
self.position = 0;
} else if key_press.key == 'j' || key_press.key == 'k' {
if key_press.key == 'j' {
//down
if self.position == self.current_dir_contents.len() - 1 {
self.position = 0;
} else {
self.position += 1;
}
} else {
self.position += 1;
//up
if self.position == 0 {
self.position = self.current_dir_contents.len() - 1;
} else {
self.position -= 1;
}
}
WindowMessageResponse::JustRerender
} else if key_press.key == 'k' {
//up
if self.position == 0 {
self.position = self.current_dir_contents.len() - 1;
//calculate position
if self.position > self.top_position {
let current_height = (self.position - self.top_position) * HEIGHT;
if current_height > self.dimensions[1] {
self.top_position += (current_height - self.dimensions[1]) / HEIGHT + 1;
}
} else {
self.position -= 1;
}
self.top_position = self.position;
};
WindowMessageResponse::JustRerender
} else {
WindowMessageResponse::DoNothing
@@ -83,14 +97,14 @@ impl WindowLike for FileExplorer {
//
//the actual files and directories
let mut start_y = 0;
let mut i = 0;
for entry in &self.current_dir_contents {
let mut i = self.top_position;
for entry in self.current_dir_contents.iter().skip(self.top_position) {
if start_y > self.dimensions[1] {
break;
}
let is_selected = i == self.position;
if is_selected {
instructions.push(DrawInstructions::Rect([0, start_y], [self.dimensions[0], 20], theme_info.top));
instructions.push(DrawInstructions::Rect([0, start_y], [self.dimensions[0], HEIGHT], theme_info.top));
}
//unwrap_or not used because "Arguments passed to unwrap_or are eagerly evaluated", apparently
let name = entry.override_name.clone();
@@ -100,7 +114,7 @@ impl WindowLike for FileExplorer {
name.unwrap()
};
instructions.push(DrawInstructions::Text([5, start_y], vec!["times-new-roman".to_string(), "shippori-mincho".to_string()], name, if is_selected { theme_info.top_text } else { theme_info.text }, if is_selected { theme_info.top } else { theme_info.background }, None, None));
start_y += 20;
start_y += HEIGHT;
i += 1;
}
instructions

View File

@@ -4,7 +4,7 @@ use std::fmt;
use std::path::PathBuf;
use std::fs::{ read_to_string, write };
use ming_wm::messages::{ WindowMessage, WindowMessageResponse };
use ming_wm::messages::{ WindowMessage, WindowMessageResponse, WindowManagerRequest, ShortcutType };
use ming_wm::themes::ThemeInfo;
use ming_wm::framebuffer::Dimensions;
use ming_wm::window_manager::{ DrawInstructions, WindowLike, WindowLikeType };
@@ -310,6 +310,33 @@ impl WindowLike for Malvim {
self.dimensions = dimensions;
WindowMessageResponse::JustRerender
},
WindowMessage::Shortcut(shortcut) => {
match shortcut {
ShortcutType::ClipboardCopy => {
if self.files.len() > 0 {
let current_file = &mut self.files[self.current_file_index];
WindowMessageResponse::Request(WindowManagerRequest::ClipboardCopy(current_file.content[current_file.line_pos].clone()))
} else {
WindowMessageResponse::DoNothing
}
},
ShortcutType::ClipboardPaste(copy_string) => {
if self.mode == Mode::Insert {
let current_file = &mut self.files[self.current_file_index];
let line = &current_file.content[current_file.line_pos];
current_file.content[current_file.line_pos] = line.substring(0, current_file.cursor_pos).to_string() + &copy_string + line.substring(current_file.cursor_pos, line.len());
current_file.cursor_pos += copy_string.len();
self.calc_top_line_pos();
self.calc_current(); //too over zealous but whatever
self.files[self.current_file_index].changed = true;
WindowMessageResponse::JustRerender
} else {
WindowMessageResponse::DoNothing
}
},
_ => WindowMessageResponse::DoNothing,
}
},
_ => WindowMessageResponse::DoNothing,
}
}
@@ -429,7 +456,7 @@ impl Malvim {
//if not, move top_line_pos down until it is
let current_file = &self.files[self.current_file_index];
let actual_line_pos = self.current.actual_lines.iter().position(|l| l.1 == current_file.line_pos).unwrap();
if current_file.top_line_pos + self.current.max_lines < actual_line_pos {
if current_file.top_line_pos + self.current.max_lines <= actual_line_pos {
self.files[self.current_file_index].top_line_pos = actual_line_pos.checked_sub(self.current.max_lines - 1).unwrap_or(0);
} else if actual_line_pos < current_file.top_line_pos {
self.files[self.current_file_index].top_line_pos = actual_line_pos;
@@ -516,6 +543,17 @@ impl Malvim {
}
} else if self.files.len() == 0 {
self.bottom_message = Some("No files are open, so can only do :e(dit)".to_string());
} else if first.starts_with("/") {
let current_file = &mut self.files[self.current_file_index];
if current_file.content.len() > 0 {
let found_line_no = current_file.content.iter().skip(current_file.line_pos + 1).position(|line| {
line.contains(&first[1..])
});
if let Some(found_line_no) = found_line_no {
current_file.line_pos = found_line_no + current_file.line_pos + 1;
current_file.cursor_pos = 0;
}
}
} else if first == "w" || first == "write" {
let current_file = &self.files[self.current_file_index];
let _ = write(&current_file.path, &current_file.content.join("\n"));
@@ -524,6 +562,7 @@ impl Malvim {
} else if first == "q" || first == "quit" {
self.files.remove(self.current_file_index);
self.current_file_index = self.current_file_index.checked_sub(1).unwrap_or(0);
return true;
} else if first == "p" || first == "tabp" {
self.current_file_index = self.current_file_index.checked_sub(1).unwrap_or(self.files.len() - 1);
return true;
@@ -543,4 +582,3 @@ impl Malvim {
pub fn main() {
listen(Malvim::new());
}

View File

@@ -69,7 +69,7 @@ impl WindowLike for Terminal {
self.calc_actual_lines();
self.actual_line_num = self.actual_lines.len().checked_sub(self.get_max_lines()).unwrap_or(0);
WindowMessageResponse::JustRerender
} else {
} else if key_press.key.len_utf8() == 1 {
//update
let running_process = self.running_process.as_mut().unwrap();
if let Some(status) = running_process.try_wait().unwrap() {
@@ -90,6 +90,10 @@ impl WindowLike for Terminal {
//still running
WindowMessageResponse::DoNothing
}
} else {
//esc key (crash happens if esc key is entered and deleted, so prevent it from being entered)
//but if we want to support eg Chinese we need to properly handle multi-byte chars (todo)
WindowMessageResponse::DoNothing
}
},
WindowMessage::CtrlKeyPress(key_press) => {