copy paste shortcuts, file explorer scrolling
malvim find in file with /
This commit is contained in:
@@ -9,6 +9,8 @@ use ming_wm::framebuffer::Dimensions;
|
|||||||
use ming_wm::themes::ThemeInfo;
|
use ming_wm::themes::ThemeInfo;
|
||||||
use ming_wm::ipc::listen;
|
use ming_wm::ipc::listen;
|
||||||
|
|
||||||
|
const HEIGHT: usize = 20;
|
||||||
|
|
||||||
struct DirectoryChild {
|
struct DirectoryChild {
|
||||||
//if some, use instead of file/dir name
|
//if some, use instead of file/dir name
|
||||||
override_name: Option<String>,
|
override_name: Option<String>,
|
||||||
@@ -26,6 +28,7 @@ pub struct FileExplorer {
|
|||||||
current_dir_contents: Vec<DirectoryChild>,
|
current_dir_contents: Vec<DirectoryChild>,
|
||||||
//for scrolling and selecting dirs
|
//for scrolling and selecting dirs
|
||||||
position: usize,
|
position: usize,
|
||||||
|
top_position: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WindowLike for FileExplorer {
|
impl WindowLike for FileExplorer {
|
||||||
@@ -49,25 +52,36 @@ impl WindowLike for FileExplorer {
|
|||||||
self.current_path = selected_entry.path.clone();
|
self.current_path = selected_entry.path.clone();
|
||||||
self.current_dir_contents = self.get_current_dir_contents();
|
self.current_dir_contents = self.get_current_dir_contents();
|
||||||
self.position = 0;
|
self.position = 0;
|
||||||
|
self.top_position = 0;
|
||||||
return WindowMessageResponse::JustRerender;
|
return WindowMessageResponse::JustRerender;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WindowMessageResponse::DoNothing
|
WindowMessageResponse::DoNothing
|
||||||
} else if key_press.key == 'j' {
|
} else if key_press.key == 'j' || key_press.key == 'k' {
|
||||||
|
if key_press.key == 'j' {
|
||||||
//down
|
//down
|
||||||
if self.position == self.current_dir_contents.len() - 1 {
|
if self.position == self.current_dir_contents.len() - 1 {
|
||||||
self.position = 0;
|
self.position = 0;
|
||||||
} else {
|
} else {
|
||||||
self.position += 1;
|
self.position += 1;
|
||||||
}
|
}
|
||||||
WindowMessageResponse::JustRerender
|
} else {
|
||||||
} else if key_press.key == 'k' {
|
|
||||||
//up
|
//up
|
||||||
if self.position == 0 {
|
if self.position == 0 {
|
||||||
self.position = self.current_dir_contents.len() - 1;
|
self.position = self.current_dir_contents.len() - 1;
|
||||||
} else {
|
} else {
|
||||||
self.position -= 1;
|
self.position -= 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.top_position = self.position;
|
||||||
|
};
|
||||||
WindowMessageResponse::JustRerender
|
WindowMessageResponse::JustRerender
|
||||||
} else {
|
} else {
|
||||||
WindowMessageResponse::DoNothing
|
WindowMessageResponse::DoNothing
|
||||||
@@ -83,14 +97,14 @@ impl WindowLike for FileExplorer {
|
|||||||
//
|
//
|
||||||
//the actual files and directories
|
//the actual files and directories
|
||||||
let mut start_y = 0;
|
let mut start_y = 0;
|
||||||
let mut i = 0;
|
let mut i = self.top_position;
|
||||||
for entry in &self.current_dir_contents {
|
for entry in self.current_dir_contents.iter().skip(self.top_position) {
|
||||||
if start_y > self.dimensions[1] {
|
if start_y > self.dimensions[1] {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let is_selected = i == self.position;
|
let is_selected = i == self.position;
|
||||||
if is_selected {
|
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
|
//unwrap_or not used because "Arguments passed to unwrap_or are eagerly evaluated", apparently
|
||||||
let name = entry.override_name.clone();
|
let name = entry.override_name.clone();
|
||||||
@@ -100,7 +114,7 @@ impl WindowLike for FileExplorer {
|
|||||||
name.unwrap()
|
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));
|
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;
|
i += 1;
|
||||||
}
|
}
|
||||||
instructions
|
instructions
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use std::fmt;
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::fs::{ read_to_string, write };
|
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::themes::ThemeInfo;
|
||||||
use ming_wm::framebuffer::Dimensions;
|
use ming_wm::framebuffer::Dimensions;
|
||||||
use ming_wm::window_manager::{ DrawInstructions, WindowLike, WindowLikeType };
|
use ming_wm::window_manager::{ DrawInstructions, WindowLike, WindowLikeType };
|
||||||
@@ -310,6 +310,33 @@ impl WindowLike for Malvim {
|
|||||||
self.dimensions = dimensions;
|
self.dimensions = dimensions;
|
||||||
WindowMessageResponse::JustRerender
|
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 = ¤t_file.content[current_file.line_pos];
|
||||||
|
current_file.content[current_file.line_pos] = line.substring(0, current_file.cursor_pos).to_string() + ©_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,
|
_ => WindowMessageResponse::DoNothing,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -429,7 +456,7 @@ impl Malvim {
|
|||||||
//if not, move top_line_pos down until it is
|
//if not, move top_line_pos down until it is
|
||||||
let current_file = &self.files[self.current_file_index];
|
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();
|
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);
|
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 {
|
} else if actual_line_pos < current_file.top_line_pos {
|
||||||
self.files[self.current_file_index].top_line_pos = actual_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 {
|
} else if self.files.len() == 0 {
|
||||||
self.bottom_message = Some("No files are open, so can only do :e(dit)".to_string());
|
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" {
|
} else if first == "w" || first == "write" {
|
||||||
let current_file = &self.files[self.current_file_index];
|
let current_file = &self.files[self.current_file_index];
|
||||||
let _ = write(¤t_file.path, ¤t_file.content.join("\n"));
|
let _ = write(¤t_file.path, ¤t_file.content.join("\n"));
|
||||||
@@ -524,6 +562,7 @@ impl Malvim {
|
|||||||
} else if first == "q" || first == "quit" {
|
} else if first == "q" || first == "quit" {
|
||||||
self.files.remove(self.current_file_index);
|
self.files.remove(self.current_file_index);
|
||||||
self.current_file_index = self.current_file_index.checked_sub(1).unwrap_or(0);
|
self.current_file_index = self.current_file_index.checked_sub(1).unwrap_or(0);
|
||||||
|
return true;
|
||||||
} else if first == "p" || first == "tabp" {
|
} else if first == "p" || first == "tabp" {
|
||||||
self.current_file_index = self.current_file_index.checked_sub(1).unwrap_or(self.files.len() - 1);
|
self.current_file_index = self.current_file_index.checked_sub(1).unwrap_or(self.files.len() - 1);
|
||||||
return true;
|
return true;
|
||||||
@@ -543,4 +582,3 @@ impl Malvim {
|
|||||||
pub fn main() {
|
pub fn main() {
|
||||||
listen(Malvim::new());
|
listen(Malvim::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ impl WindowLike for Terminal {
|
|||||||
self.calc_actual_lines();
|
self.calc_actual_lines();
|
||||||
self.actual_line_num = self.actual_lines.len().checked_sub(self.get_max_lines()).unwrap_or(0);
|
self.actual_line_num = self.actual_lines.len().checked_sub(self.get_max_lines()).unwrap_or(0);
|
||||||
WindowMessageResponse::JustRerender
|
WindowMessageResponse::JustRerender
|
||||||
} else {
|
} else if key_press.key.len_utf8() == 1 {
|
||||||
//update
|
//update
|
||||||
let running_process = self.running_process.as_mut().unwrap();
|
let running_process = self.running_process.as_mut().unwrap();
|
||||||
if let Some(status) = running_process.try_wait().unwrap() {
|
if let Some(status) = running_process.try_wait().unwrap() {
|
||||||
@@ -90,6 +90,10 @@ impl WindowLike for Terminal {
|
|||||||
//still running
|
//still running
|
||||||
WindowMessageResponse::DoNothing
|
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) => {
|
WindowMessage::CtrlKeyPress(key_press) => {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ impl PartialEq for WindowBox {
|
|||||||
#[derive(PartialEq, Serialize, Deserialize)]
|
#[derive(PartialEq, Serialize, Deserialize)]
|
||||||
pub enum WindowManagerRequest {
|
pub enum WindowManagerRequest {
|
||||||
OpenWindow(String),
|
OpenWindow(String),
|
||||||
|
ClipboardCopy(String),
|
||||||
CloseStartMenu,
|
CloseStartMenu,
|
||||||
Unlock,
|
Unlock,
|
||||||
Lock,
|
Lock,
|
||||||
@@ -73,6 +74,8 @@ pub enum ShortcutType {
|
|||||||
CenterWindow,
|
CenterWindow,
|
||||||
FullscreenWindow,
|
FullscreenWindow,
|
||||||
HalfWidthWindow, //half width, full height
|
HalfWidthWindow, //half width, full height
|
||||||
|
ClipboardCopy,
|
||||||
|
ClipboardPaste(String),
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ use crate::essential::taskbar::Taskbar;
|
|||||||
use crate::essential::lock_screen::LockScreen;
|
use crate::essential::lock_screen::LockScreen;
|
||||||
use crate::essential::workspace_indicator::WorkspaceIndicator;
|
use crate::essential::workspace_indicator::WorkspaceIndicator;
|
||||||
use crate::essential::start_menu::StartMenu;
|
use crate::essential::start_menu::StartMenu;
|
||||||
|
use crate::logging::log;
|
||||||
|
|
||||||
pub const TASKBAR_HEIGHT: usize = 38;
|
pub const TASKBAR_HEIGHT: usize = 38;
|
||||||
pub const INDICATOR_HEIGHT: usize = 20;
|
pub const INDICATOR_HEIGHT: usize = 20;
|
||||||
@@ -137,6 +138,7 @@ pub struct WindowManager {
|
|||||||
pub locked: bool,
|
pub locked: bool,
|
||||||
current_workspace: u8,
|
current_workspace: u8,
|
||||||
framebuffer: Framebuffer,
|
framebuffer: Framebuffer,
|
||||||
|
clipboard: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
//1 is up, 2 is down
|
//1 is up, 2 is down
|
||||||
@@ -152,6 +154,7 @@ impl WindowManager {
|
|||||||
locked: false,
|
locked: false,
|
||||||
current_workspace: 0,
|
current_workspace: 0,
|
||||||
framebuffer,
|
framebuffer,
|
||||||
|
clipboard: None,
|
||||||
};
|
};
|
||||||
wm.lock();
|
wm.lock();
|
||||||
wm
|
wm
|
||||||
@@ -259,6 +262,8 @@ impl WindowManager {
|
|||||||
('c', ShortcutType::CenterWindow),
|
('c', ShortcutType::CenterWindow),
|
||||||
('f', ShortcutType::FullscreenWindow),
|
('f', ShortcutType::FullscreenWindow),
|
||||||
('w', ShortcutType::HalfWidthWindow),
|
('w', ShortcutType::HalfWidthWindow),
|
||||||
|
('C', ShortcutType::ClipboardCopy),
|
||||||
|
('P', ShortcutType::ClipboardPaste(String::new())),
|
||||||
//move window a small amount
|
//move window a small amount
|
||||||
('h', ShortcutType::MoveWindow(Direction::Left)),
|
('h', ShortcutType::MoveWindow(Direction::Left)),
|
||||||
('j', ShortcutType::MoveWindow(Direction::Down)),
|
('j', ShortcutType::MoveWindow(Direction::Down)),
|
||||||
@@ -464,6 +469,22 @@ impl WindowManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
&ShortcutType::ClipboardCopy => {
|
||||||
|
if let Some(focused_index) = self.get_focused_index() {
|
||||||
|
let window_like = &self.window_infos[focused_index].window_like;
|
||||||
|
if window_like.subtype() == WindowLikeType::Window {
|
||||||
|
press_response = self.window_infos[focused_index].window_like.handle_message(WindowMessage::Shortcut(ShortcutType::ClipboardCopy));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
&ShortcutType::ClipboardPaste(_) => {
|
||||||
|
if let Some(focused_index) = self.get_focused_index() {
|
||||||
|
let window_like = &self.window_infos[focused_index].window_like;
|
||||||
|
if window_like.subtype() == WindowLikeType::Window && self.clipboard.is_some() {
|
||||||
|
press_response = self.window_infos[focused_index].window_like.handle_message(WindowMessage::Shortcut(ShortcutType::ClipboardPaste(self.clipboard.clone().unwrap())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -558,6 +579,10 @@ impl WindowManager {
|
|||||||
}
|
}
|
||||||
self.lock();
|
self.lock();
|
||||||
},
|
},
|
||||||
|
WindowManagerRequest::ClipboardCopy(content) => {
|
||||||
|
self.clipboard = Some(content);
|
||||||
|
log(&format!("{:?}", self.clipboard));
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -671,4 +696,3 @@ impl WindowManager {
|
|||||||
self.framebuffer.write_frame(WRITER.lock().unwrap().get_buffer());
|
self.framebuffer.write_frame(WRITER.lock().unwrap().get_buffer());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user