Fixed **many** clippy lints, and one bug.
This commit is contained in:
parent
d289670def
commit
aecb80eaed
6 changed files with 155 additions and 201 deletions
296
src/main.rs
296
src/main.rs
|
|
@ -364,7 +364,7 @@ impl App {
|
||||||
|
|
||||||
let position = self.nav_model.position(id).unwrap_or(0);
|
let position = self.nav_model.position(id).unwrap_or(0);
|
||||||
|
|
||||||
self.open_folder(&path, position + 1, 1);
|
self.open_folder(path, position + 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn open_tab(&mut self, path_opt: Option<PathBuf>) -> Option<segmented_button::Entity> {
|
pub fn open_tab(&mut self, path_opt: Option<PathBuf>) -> Option<segmented_button::Entity> {
|
||||||
|
|
@ -381,14 +381,11 @@ impl App {
|
||||||
//TODO: allow files to be open multiple times
|
//TODO: allow files to be open multiple times
|
||||||
let mut activate_opt = None;
|
let mut activate_opt = None;
|
||||||
for entity in self.tab_model.iter() {
|
for entity in self.tab_model.iter() {
|
||||||
match self.tab_model.data::<Tab>(entity) {
|
if let Some(Tab::Editor(tab)) = self.tab_model.data::<Tab>(entity) {
|
||||||
Some(Tab::Editor(tab)) => {
|
if tab.path_opt.as_ref() == Some(&canonical) {
|
||||||
if tab.path_opt.as_ref() == Some(&canonical) {
|
activate_opt = Some(entity);
|
||||||
activate_opt = Some(entity);
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(entity) = activate_opt {
|
if let Some(entity) = activate_opt {
|
||||||
|
|
@ -428,15 +425,18 @@ impl App {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn save_config(&mut self) -> Command<Message> {
|
fn save_config(&mut self) -> Command<Message> {
|
||||||
match self.config_handler {
|
if let Some(ref config_handler) = self.config_handler {
|
||||||
Some(ref config_handler) => match self.config.write_entry(&config_handler) {
|
if let Err(err) = self.config.write_entry(config_handler) {
|
||||||
Ok(()) => {}
|
log::error!("failed to save config: {}", err);
|
||||||
Err(err) => {
|
}
|
||||||
log::error!("failed to save config: {}", err);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(ref config_handler) = self.config_handler {
|
||||||
|
if let Err(err) = self.config.write_entry(config_handler) {
|
||||||
|
log::error!("failed to save config: {}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
self.update_config()
|
self.update_config()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -449,43 +449,40 @@ impl App {
|
||||||
|
|
||||||
// Locate tree node to activate
|
// Locate tree node to activate
|
||||||
let mut active_id = segmented_button::Entity::default();
|
let mut active_id = segmented_button::Entity::default();
|
||||||
match tab_path_opt {
|
|
||||||
Some(tab_path) => {
|
if let Some(tab_path) = tab_path_opt {
|
||||||
// Automatically expand tree to find and select active file
|
// Automatically expand tree to find and select active file
|
||||||
loop {
|
loop {
|
||||||
let mut expand_opt = None;
|
let mut expand_opt = None;
|
||||||
for id in self.nav_model.iter() {
|
for id in self.nav_model.iter() {
|
||||||
match self.nav_model.data(id) {
|
if let Some(node) = self.nav_model.data(id) {
|
||||||
Some(node) => match node {
|
match node {
|
||||||
ProjectNode::Folder { path, open, .. } => {
|
ProjectNode::Folder { path, open, .. } => {
|
||||||
if tab_path.starts_with(path) && !*open {
|
if tab_path.starts_with(path) && !*open {
|
||||||
expand_opt = Some(id);
|
expand_opt = Some(id);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ProjectNode::File { path, .. } => {
|
}
|
||||||
if path == &tab_path {
|
ProjectNode::File { path, .. } => {
|
||||||
active_id = id;
|
if path == &tab_path {
|
||||||
break;
|
active_id = id;
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
None => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
match expand_opt {
|
|
||||||
Some(id) => {
|
|
||||||
//TODO: can this be optimized?
|
|
||||||
// Command not used becuase opening a folder just returns Command::none
|
|
||||||
let _ = self.on_nav_select(id);
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
match expand_opt {
|
||||||
|
Some(id) => {
|
||||||
|
//TODO: can this be optimized?
|
||||||
|
// Command not used becuase opening a folder just returns Command::none
|
||||||
|
let _ = self.on_nav_select(id);
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
self.nav_model.activate(active_id);
|
self.nav_model.activate(active_id);
|
||||||
}
|
}
|
||||||
|
|
@ -502,7 +499,7 @@ impl App {
|
||||||
}
|
}
|
||||||
tab.title()
|
tab.title()
|
||||||
}
|
}
|
||||||
None => format!("No Open File"),
|
None => "No Open File".to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let window_title = format!("{title} - COSMIC Text Editor");
|
let window_title = format!("{title} - COSMIC Text Editor");
|
||||||
|
|
@ -515,23 +512,21 @@ impl App {
|
||||||
let mut character_count = 0;
|
let mut character_count = 0;
|
||||||
let mut character_count_no_spaces = 0;
|
let mut character_count_no_spaces = 0;
|
||||||
let mut line_count = 0;
|
let mut line_count = 0;
|
||||||
match self.active_tab() {
|
|
||||||
Some(Tab::Editor(tab)) => {
|
if let Some(Tab::Editor(tab)) = self.active_tab() {
|
||||||
let editor = tab.editor.lock().unwrap();
|
let editor = tab.editor.lock().unwrap();
|
||||||
editor.with_buffer(|buffer| {
|
editor.with_buffer(|buffer| {
|
||||||
line_count = buffer.lines.len();
|
line_count = buffer.lines.len();
|
||||||
for line in buffer.lines.iter() {
|
for line in buffer.lines.iter() {
|
||||||
//TODO: do graphemes?
|
//TODO: do graphemes?
|
||||||
for c in line.text().chars() {
|
for c in line.text().chars() {
|
||||||
character_count += 1;
|
character_count += 1;
|
||||||
if !c.is_whitespace() {
|
if !c.is_whitespace() {
|
||||||
character_count_no_spaces += 1;
|
character_count_no_spaces += 1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
});
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
widget::settings::view_column(vec![widget::settings::view_section("")
|
widget::settings::view_column(vec![widget::settings::view_section("")
|
||||||
|
|
@ -598,7 +593,7 @@ impl App {
|
||||||
project_path,
|
project_path,
|
||||||
err
|
err
|
||||||
);
|
);
|
||||||
&old_path
|
old_path
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
format!(
|
format!(
|
||||||
|
|
@ -752,7 +747,7 @@ impl App {
|
||||||
))
|
))
|
||||||
.font(Font::MONOSPACE)
|
.font(Font::MONOSPACE)
|
||||||
.into(),
|
.into(),
|
||||||
widget::text(format!("{}", line_search_result.text))
|
widget::text(line_search_result.text.to_string())
|
||||||
.font(Font::MONOSPACE)
|
.font(Font::MONOSPACE)
|
||||||
.into(),
|
.into(),
|
||||||
])
|
])
|
||||||
|
|
@ -848,7 +843,7 @@ impl App {
|
||||||
widget::settings::item::builder(fl!("default-font")).control(widget::dropdown(
|
widget::settings::item::builder(fl!("default-font")).control(widget::dropdown(
|
||||||
&self.font_names,
|
&self.font_names,
|
||||||
font_selected,
|
font_selected,
|
||||||
|index| Message::DefaultFont(index),
|
Message::DefaultFont,
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
.add(
|
.add(
|
||||||
|
|
@ -914,7 +909,7 @@ impl Application for App {
|
||||||
//TODO: get localized name if possible
|
//TODO: get localized name if possible
|
||||||
let font_name = face
|
let font_name = face
|
||||||
.families
|
.families
|
||||||
.get(0)
|
.first()
|
||||||
.map_or_else(|| face.post_script_name.to_string(), |x| x.0.to_string());
|
.map_or_else(|| face.post_script_name.to_string(), |x| x.0.to_string());
|
||||||
font_names.push(font_name);
|
font_names.push(font_name);
|
||||||
}
|
}
|
||||||
|
|
@ -1030,11 +1025,8 @@ impl Application for App {
|
||||||
// Toggle open state and get clone of node data
|
// Toggle open state and get clone of node data
|
||||||
let node_opt = match self.nav_model.data_mut::<ProjectNode>(id) {
|
let node_opt = match self.nav_model.data_mut::<ProjectNode>(id) {
|
||||||
Some(node) => {
|
Some(node) => {
|
||||||
match node {
|
if let ProjectNode::Folder { open, .. } = node {
|
||||||
ProjectNode::Folder { open, .. } => {
|
*open = !*open;
|
||||||
*open = !*open;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
Some(node.clone())
|
Some(node.clone())
|
||||||
}
|
}
|
||||||
|
|
@ -1055,12 +1047,7 @@ impl Application for App {
|
||||||
self.open_folder(path, position + 1, indent + 1);
|
self.open_folder(path, position + 1, indent + 1);
|
||||||
} else {
|
} else {
|
||||||
// Close folder
|
// Close folder
|
||||||
loop {
|
while let Some(child_id) = self.nav_model.entity_at(position + 1) {
|
||||||
let child_id = match self.nav_model.entity_at(position + 1) {
|
|
||||||
Some(some) => some,
|
|
||||||
None => break,
|
|
||||||
};
|
|
||||||
|
|
||||||
if self.nav_model.indent(child_id).unwrap_or(0) > indent {
|
if self.nav_model.indent(child_id).unwrap_or(0) > indent {
|
||||||
self.nav_model.remove(child_id);
|
self.nav_model.remove(child_id);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1103,18 +1090,17 @@ impl Application for App {
|
||||||
Message::CloseProject => {
|
Message::CloseProject => {
|
||||||
log::info!("TODO");
|
log::info!("TODO");
|
||||||
}
|
}
|
||||||
Message::Copy => match self.active_tab() {
|
Message::Copy => {
|
||||||
Some(Tab::Editor(tab)) => {
|
if let Some(Tab::Editor(tab)) = self.active_tab() {
|
||||||
let editor = tab.editor.lock().unwrap();
|
let editor = tab.editor.lock().unwrap();
|
||||||
let selection_opt = editor.copy_selection();
|
let selection_opt = editor.copy_selection();
|
||||||
if let Some(selection) = selection_opt {
|
if let Some(selection) = selection_opt {
|
||||||
return clipboard::write(selection);
|
return clipboard::write(selection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
}
|
||||||
},
|
Message::Cut => {
|
||||||
Message::Cut => match self.active_tab() {
|
if let Some(Tab::Editor(tab)) = self.active_tab() {
|
||||||
Some(Tab::Editor(tab)) => {
|
|
||||||
let mut editor = tab.editor.lock().unwrap();
|
let mut editor = tab.editor.lock().unwrap();
|
||||||
let selection_opt = editor.copy_selection();
|
let selection_opt = editor.copy_selection();
|
||||||
editor.start_change();
|
editor.start_change();
|
||||||
|
|
@ -1124,8 +1110,7 @@ impl Application for App {
|
||||||
return clipboard::write(selection);
|
return clipboard::write(selection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
}
|
||||||
},
|
|
||||||
Message::DefaultFont(index) => {
|
Message::DefaultFont(index) => {
|
||||||
match self.font_names.get(index) {
|
match self.font_names.get(index) {
|
||||||
Some(font_name) => {
|
Some(font_name) => {
|
||||||
|
|
@ -1206,22 +1191,19 @@ impl Application for App {
|
||||||
Message::NotifyEvent(event) => {
|
Message::NotifyEvent(event) => {
|
||||||
let mut needs_reload = Vec::new();
|
let mut needs_reload = Vec::new();
|
||||||
for entity in self.tab_model.iter() {
|
for entity in self.tab_model.iter() {
|
||||||
match self.tab_model.data::<Tab>(entity) {
|
if let Some(Tab::Editor(tab)) = self.tab_model.data::<Tab>(entity) {
|
||||||
Some(Tab::Editor(tab)) => {
|
if let Some(path) = &tab.path_opt {
|
||||||
if let Some(path) = &tab.path_opt {
|
if event.paths.contains(path) {
|
||||||
if event.paths.contains(&path) {
|
if tab.changed() {
|
||||||
if tab.changed() {
|
log::warn!(
|
||||||
log::warn!(
|
"file changed externally before being saved: {:?}",
|
||||||
"file changed externally before being saved: {:?}",
|
path
|
||||||
path
|
);
|
||||||
);
|
} else {
|
||||||
} else {
|
needs_reload.push(entity);
|
||||||
needs_reload.push(entity);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1242,11 +1224,8 @@ impl Application for App {
|
||||||
self.watcher_opt = Some(watcher);
|
self.watcher_opt = Some(watcher);
|
||||||
|
|
||||||
for entity in self.tab_model.iter() {
|
for entity in self.tab_model.iter() {
|
||||||
match self.tab_model.data::<Tab>(entity) {
|
if let Some(Tab::Editor(tab)) = self.tab_model.data::<Tab>(entity) {
|
||||||
Some(Tab::Editor(tab)) => {
|
tab.watch(&mut self.watcher_opt);
|
||||||
tab.watch(&mut self.watcher_opt);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1363,15 +1342,14 @@ impl Application for App {
|
||||||
None => message::none(),
|
None => message::none(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Message::PasteValue(value) => match self.active_tab() {
|
Message::PasteValue(value) => {
|
||||||
Some(Tab::Editor(tab)) => {
|
if let Some(Tab::Editor(tab)) = self.active_tab() {
|
||||||
let mut editor = tab.editor.lock().unwrap();
|
let mut editor = tab.editor.lock().unwrap();
|
||||||
editor.start_change();
|
editor.start_change();
|
||||||
editor.insert_string(&value, None);
|
editor.insert_string(&value, None);
|
||||||
editor.finish_change();
|
editor.finish_change();
|
||||||
}
|
}
|
||||||
_ => {}
|
}
|
||||||
},
|
|
||||||
Message::PrepareGitDiff(project_path, path, staged) => {
|
Message::PrepareGitDiff(project_path, path, staged) => {
|
||||||
return Command::perform(
|
return Command::perform(
|
||||||
async move {
|
async move {
|
||||||
|
|
@ -1446,27 +1424,23 @@ impl Application for App {
|
||||||
//TODO: prompt for save?
|
//TODO: prompt for save?
|
||||||
return window::close(window::Id::MAIN);
|
return window::close(window::Id::MAIN);
|
||||||
}
|
}
|
||||||
Message::Redo => match self.active_tab() {
|
Message::Redo => {
|
||||||
Some(Tab::Editor(tab)) => {
|
if let Some(Tab::Editor(tab)) = self.active_tab() {
|
||||||
let mut editor = tab.editor.lock().unwrap();
|
let mut editor = tab.editor.lock().unwrap();
|
||||||
editor.redo();
|
editor.redo();
|
||||||
}
|
}
|
||||||
_ => {}
|
}
|
||||||
},
|
|
||||||
Message::Save => {
|
Message::Save => {
|
||||||
let mut title_opt = None;
|
let mut title_opt = None;
|
||||||
|
|
||||||
match self.active_tab_mut() {
|
if let Some(Tab::Editor(tab)) = self.active_tab_mut() {
|
||||||
Some(Tab::Editor(tab)) => {
|
#[cfg(feature = "rfd")]
|
||||||
#[cfg(feature = "rfd")]
|
if tab.path_opt.is_none() {
|
||||||
if tab.path_opt.is_none() {
|
//TODO: use async file dialog
|
||||||
//TODO: use async file dialog
|
tab.path_opt = rfd::FileDialog::new().save_file();
|
||||||
tab.path_opt = rfd::FileDialog::new().save_file();
|
|
||||||
}
|
|
||||||
title_opt = Some(tab.title());
|
|
||||||
tab.save();
|
|
||||||
}
|
}
|
||||||
_ => {}
|
title_opt = Some(tab.title());
|
||||||
|
tab.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(title) = title_opt {
|
if let Some(title) = title_opt {
|
||||||
|
|
@ -1474,22 +1448,19 @@ impl Application for App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Message::SelectAll => {
|
Message::SelectAll => {
|
||||||
match self.active_tab_mut() {
|
if let Some(Tab::Editor(tab)) = self.active_tab_mut() {
|
||||||
Some(Tab::Editor(tab)) => {
|
let mut editor = tab.editor.lock().unwrap();
|
||||||
let mut editor = tab.editor.lock().unwrap();
|
|
||||||
|
|
||||||
// Set cursor to lowest possible value
|
// Set cursor to lowest possible value
|
||||||
editor.set_cursor(Cursor::new(0, 0));
|
editor.set_cursor(Cursor::new(0, 0));
|
||||||
|
|
||||||
// Set selection end to highest possible value
|
// Set selection end to highest possible value
|
||||||
let selection = editor.with_buffer(|buffer| {
|
let selection = editor.with_buffer(|buffer| {
|
||||||
let last_line = buffer.lines.len().saturating_sub(1);
|
let last_line = buffer.lines.len().saturating_sub(1);
|
||||||
let last_index = buffer.lines[last_line].text().len();
|
let last_index = buffer.lines[last_line].text().len();
|
||||||
Selection::Normal(Cursor::new(last_line, last_index))
|
Selection::Normal(Cursor::new(last_line, last_index))
|
||||||
});
|
});
|
||||||
editor.set_selection(selection);
|
editor.set_selection(selection);
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Message::SystemThemeModeChange(_theme_mode) => {
|
Message::SystemThemeModeChange(_theme_mode) => {
|
||||||
|
|
@ -1512,15 +1483,14 @@ impl Application for App {
|
||||||
self.tab_model.activate(entity);
|
self.tab_model.activate(entity);
|
||||||
return self.update_tab();
|
return self.update_tab();
|
||||||
}
|
}
|
||||||
Message::TabChanged(entity) => match self.tab_model.data::<Tab>(entity) {
|
Message::TabChanged(entity) => {
|
||||||
Some(Tab::Editor(tab)) => {
|
if let Some(Tab::Editor(tab)) = self.tab_model.data::<Tab>(entity) {
|
||||||
let mut title = tab.title();
|
let mut title = tab.title();
|
||||||
//TODO: better way of adding change indicator
|
//TODO: better way of adding change indicator
|
||||||
title.push_str(" \u{2022}");
|
title.push_str(" \u{2022}");
|
||||||
self.tab_model.text_set(entity, title);
|
self.tab_model.text_set(entity, title);
|
||||||
}
|
}
|
||||||
_ => {}
|
}
|
||||||
},
|
|
||||||
Message::TabClose(entity) => {
|
Message::TabClose(entity) => {
|
||||||
// Activate closest item
|
// Activate closest item
|
||||||
if let Some(position) = self.tab_model.position(entity) {
|
if let Some(position) = self.tab_model.position(entity) {
|
||||||
|
|
@ -1542,32 +1512,25 @@ impl Application for App {
|
||||||
return self.update_tab();
|
return self.update_tab();
|
||||||
}
|
}
|
||||||
Message::TabContextAction(entity, action) => {
|
Message::TabContextAction(entity, action) => {
|
||||||
match self.tab_model.data_mut::<Tab>(entity) {
|
if let Some(Tab::Editor(tab)) = self.tab_model.data_mut::<Tab>(entity) {
|
||||||
Some(Tab::Editor(tab)) => {
|
// Close context menu
|
||||||
// Close context menu
|
tab.context_menu = None;
|
||||||
tab.context_menu = None;
|
// Run action's message
|
||||||
// Run action's message
|
return self.update(action.message());
|
||||||
return self.update(action.message());
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Message::TabContextMenu(entity, position_opt) => {
|
Message::TabContextMenu(entity, position_opt) => {
|
||||||
match self.tab_model.data_mut::<Tab>(entity) {
|
if let Some(Tab::Editor(tab)) = self.tab_model.data_mut::<Tab>(entity) {
|
||||||
Some(Tab::Editor(tab)) => {
|
// Update context menu
|
||||||
// Update context menu
|
tab.context_menu = position_opt;
|
||||||
tab.context_menu = position_opt;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Message::TabSetCursor(entity, cursor) => match self.tab_model.data::<Tab>(entity) {
|
Message::TabSetCursor(entity, cursor) => {
|
||||||
Some(Tab::Editor(tab)) => {
|
if let Some(Tab::Editor(tab)) = self.tab_model.data::<Tab>(entity) {
|
||||||
let mut editor = tab.editor.lock().unwrap();
|
let mut editor = tab.editor.lock().unwrap();
|
||||||
editor.set_cursor(cursor);
|
editor.set_cursor(cursor);
|
||||||
}
|
}
|
||||||
_ => {}
|
}
|
||||||
},
|
|
||||||
Message::TabWidth(tab_width) => {
|
Message::TabWidth(tab_width) => {
|
||||||
self.config.tab_width = tab_width;
|
self.config.tab_width = tab_width;
|
||||||
return self.save_config();
|
return self.save_config();
|
||||||
|
|
@ -1599,7 +1562,7 @@ impl Application for App {
|
||||||
let mut project_status = Vec::new();
|
let mut project_status = Vec::new();
|
||||||
for (project_name, project_path) in projects.iter() {
|
for (project_name, project_path) in projects.iter() {
|
||||||
//TODO: send errors to UI
|
//TODO: send errors to UI
|
||||||
match GitRepository::new(&project_path) {
|
match GitRepository::new(project_path) {
|
||||||
Ok(repo) => match repo.status().await {
|
Ok(repo) => match repo.status().await {
|
||||||
Ok(status) => {
|
Ok(status) => {
|
||||||
if !status.is_empty() {
|
if !status.is_empty() {
|
||||||
|
|
@ -1658,13 +1621,12 @@ impl Application for App {
|
||||||
self.config.word_wrap = !self.config.word_wrap;
|
self.config.word_wrap = !self.config.word_wrap;
|
||||||
return self.save_config();
|
return self.save_config();
|
||||||
}
|
}
|
||||||
Message::Undo => match self.active_tab() {
|
Message::Undo => {
|
||||||
Some(Tab::Editor(tab)) => {
|
if let Some(Tab::Editor(tab)) = self.active_tab() {
|
||||||
let mut editor = tab.editor.lock().unwrap();
|
let mut editor = tab.editor.lock().unwrap();
|
||||||
editor.undo();
|
editor.undo();
|
||||||
}
|
}
|
||||||
_ => {}
|
}
|
||||||
},
|
|
||||||
Message::VimBindings(vim_bindings) => {
|
Message::VimBindings(vim_bindings) => {
|
||||||
self.config.vim_bindings = vim_bindings;
|
self.config.vim_bindings = vim_bindings;
|
||||||
return self.save_config();
|
return self.save_config();
|
||||||
|
|
@ -1727,15 +1689,11 @@ impl Application for App {
|
||||||
ViMode::Normal => {
|
ViMode::Normal => {
|
||||||
format!("{}", parser.cmd)
|
format!("{}", parser.cmd)
|
||||||
}
|
}
|
||||||
ViMode::Insert => {
|
ViMode::Insert => "-- INSERT --".to_string(),
|
||||||
format!("-- INSERT --")
|
|
||||||
}
|
|
||||||
ViMode::Extra(extra) => {
|
ViMode::Extra(extra) => {
|
||||||
format!("{}{}", parser.cmd, extra)
|
format!("{}{}", parser.cmd, extra)
|
||||||
}
|
}
|
||||||
ViMode::Replace => {
|
ViMode::Replace => "-- REPLACE --".to_string(),
|
||||||
format!("-- REPLACE --")
|
|
||||||
}
|
|
||||||
ViMode::Visual => {
|
ViMode::Visual => {
|
||||||
format!("-- VISUAL -- {}", parser.cmd)
|
format!("-- VISUAL -- {}", parser.cmd)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
10
src/menu.rs
10
src/menu.rs
|
|
@ -33,20 +33,20 @@ macro_rules! menu_button {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn context_menu<'a>(config: &Config, entity: segmented_button::Entity) -> Element<'a, Message> {
|
pub fn context_menu<'a>(config: &Config, entity: segmented_button::Entity) -> Element<'a, Message> {
|
||||||
let menu_item = |label, action| {
|
let menu_item = |menu_label, menu_action| {
|
||||||
let mut key = String::new();
|
let mut key = String::new();
|
||||||
for (key_bind, action) in config.keybinds.iter() {
|
for (key_bind, key_action) in config.keybinds.iter() {
|
||||||
if action == action {
|
if key_action == &menu_action {
|
||||||
key = key_bind.to_string();
|
key = key_bind.to_string();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
menu_button!(
|
menu_button!(
|
||||||
widget::text(label),
|
widget::text(menu_label),
|
||||||
horizontal_space(Length::Fill),
|
horizontal_space(Length::Fill),
|
||||||
widget::text(key)
|
widget::text(key)
|
||||||
)
|
)
|
||||||
.on_press(Message::TabContextAction(entity, action))
|
.on_press(Message::TabContextAction(entity, menu_action))
|
||||||
};
|
};
|
||||||
|
|
||||||
widget::container(column!(
|
widget::container(column!(
|
||||||
|
|
|
||||||
|
|
@ -76,15 +76,17 @@ impl Ord for ProjectNode {
|
||||||
fn cmp(&self, other: &Self) -> Ordering {
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
match self {
|
match self {
|
||||||
// Folders are always before files
|
// Folders are always before files
|
||||||
Self::Folder { .. } => match other {
|
Self::Folder { .. } => {
|
||||||
Self::File { .. } => return Ordering::Less,
|
if let Self::File { .. } = other {
|
||||||
_ => {}
|
return Ordering::Less;
|
||||||
},
|
}
|
||||||
|
}
|
||||||
// Files are always after folders
|
// Files are always after folders
|
||||||
Self::File { .. } => match other {
|
Self::File { .. } => {
|
||||||
Self::Folder { .. } => return Ordering::Greater,
|
if let Self::Folder { .. } = other {
|
||||||
_ => {}
|
return Ordering::Greater;
|
||||||
},
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self.name().cmp(other.name())
|
self.name().cmp(other.name())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,13 +54,10 @@ impl ProjectSearchResult {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match entry.file_type() {
|
if let Some(file_type) = entry.file_type() {
|
||||||
Some(file_type) => {
|
if file_type.is_dir() {
|
||||||
if file_type.is_dir() {
|
continue;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let entry_path = entry.path();
|
let entry_path = entry.path();
|
||||||
|
|
@ -68,7 +65,7 @@ impl ProjectSearchResult {
|
||||||
let mut lines = Vec::new();
|
let mut lines = Vec::new();
|
||||||
match searcher.search_path(
|
match searcher.search_path(
|
||||||
&matcher,
|
&matcher,
|
||||||
&entry_path,
|
entry_path,
|
||||||
UTF8(|number_u64, text| {
|
UTF8(|number_u64, text| {
|
||||||
match usize::try_from(number_u64) {
|
match usize::try_from(number_u64) {
|
||||||
Ok(number) => match matcher.find(text.as_bytes()) {
|
Ok(number) => match matcher.find(text.as_bytes()) {
|
||||||
|
|
|
||||||
|
|
@ -161,7 +161,7 @@ impl EditorTab {
|
||||||
pub fn watch(&self, watcher_opt: &mut Option<notify::RecommendedWatcher>) {
|
pub fn watch(&self, watcher_opt: &mut Option<notify::RecommendedWatcher>) {
|
||||||
if let Some(path) = &self.path_opt {
|
if let Some(path) = &self.path_opt {
|
||||||
if let Some(watcher) = watcher_opt {
|
if let Some(watcher) = watcher_opt {
|
||||||
match watcher.watch(&path, notify::RecursiveMode::NonRecursive) {
|
match watcher.watch(path, notify::RecursiveMode::NonRecursive) {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
log::info!("watching {:?} for changes", path);
|
log::info!("watching {:?} for changes", path);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,6 @@ fn draw_rect(
|
||||||
let alpha = (color >> 24) & 0xFF;
|
let alpha = (color >> 24) & 0xFF;
|
||||||
if alpha == 0 {
|
if alpha == 0 {
|
||||||
// Do not draw if alpha is zero
|
// Do not draw if alpha is zero
|
||||||
return;
|
|
||||||
} else if alpha >= 255 {
|
} else if alpha >= 255 {
|
||||||
// Handle overwrite
|
// Handle overwrite
|
||||||
for y in start_y..start_y + h {
|
for y in start_y..start_y + h {
|
||||||
|
|
@ -172,7 +171,7 @@ fn draw_rect(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'editor, Message, Renderer> Widget<Message, Renderer> for TextBox<'a, Message>
|
impl<'a, Message, Renderer> Widget<Message, Renderer> for TextBox<'a, Message>
|
||||||
where
|
where
|
||||||
Message: Clone,
|
Message: Clone,
|
||||||
Renderer: renderer::Renderer + image::Renderer<Handle = image::Handle>,
|
Renderer: renderer::Renderer + image::Renderer<Handle = image::Handle>,
|
||||||
|
|
@ -233,9 +232,8 @@ where
|
||||||
) -> mouse::Interaction {
|
) -> mouse::Interaction {
|
||||||
let state = tree.state.downcast_ref::<State>();
|
let state = tree.state.downcast_ref::<State>();
|
||||||
|
|
||||||
match &state.dragging {
|
if let Some(Dragging::Scrollbar { .. }) = &state.dragging {
|
||||||
Some(Dragging::Scrollbar { .. }) => return mouse::Interaction::Idle,
|
return mouse::Interaction::Idle;
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(p) = cursor_position.position_in(layout.bounds()) {
|
if let Some(p) = cursor_position.position_in(layout.bounds()) {
|
||||||
|
|
@ -507,10 +505,9 @@ where
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let image_position =
|
let image_position = layout.position() + [self.padding.left, self.padding.top].into();
|
||||||
layout.position() + [self.padding.left as f32, self.padding.top as f32].into();
|
|
||||||
if let Some(ref handle) = *handle_opt {
|
if let Some(ref handle) = *handle_opt {
|
||||||
let image_size = image::Renderer::dimensions(renderer, &handle);
|
let image_size = image::Renderer::dimensions(renderer, handle);
|
||||||
image::Renderer::draw(
|
image::Renderer::draw(
|
||||||
renderer,
|
renderer,
|
||||||
handle.clone(),
|
handle.clone(),
|
||||||
|
|
@ -761,7 +758,7 @@ where
|
||||||
Event::Mouse(MouseEvent::WheelScrolled { delta }) => {
|
Event::Mouse(MouseEvent::WheelScrolled { delta }) => {
|
||||||
if let Some(_p) = cursor_position.position_in(layout.bounds()) {
|
if let Some(_p) = cursor_position.position_in(layout.bounds()) {
|
||||||
match delta {
|
match delta {
|
||||||
ScrollDelta::Lines { x, y } => {
|
ScrollDelta::Lines { x: _, y } => {
|
||||||
//TODO: this adjustment is just a guess!
|
//TODO: this adjustment is just a guess!
|
||||||
state.scroll_pixels = 0.0;
|
state.scroll_pixels = 0.0;
|
||||||
let lines = (-y * 6.0) as i32;
|
let lines = (-y * 6.0) as i32;
|
||||||
|
|
@ -770,7 +767,7 @@ where
|
||||||
}
|
}
|
||||||
status = Status::Captured;
|
status = Status::Captured;
|
||||||
}
|
}
|
||||||
ScrollDelta::Pixels { x, y } => {
|
ScrollDelta::Pixels { x: _, y } => {
|
||||||
//TODO: this adjustment is just a guess!
|
//TODO: this adjustment is just a guess!
|
||||||
state.scroll_pixels -= y * 6.0;
|
state.scroll_pixels -= y * 6.0;
|
||||||
let mut lines = 0;
|
let mut lines = 0;
|
||||||
|
|
@ -804,7 +801,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'editor, Message, Renderer> From<TextBox<'a, Message>> for Element<'a, Message, Renderer>
|
impl<'a, Message, Renderer> From<TextBox<'a, Message>> for Element<'a, Message, Renderer>
|
||||||
where
|
where
|
||||||
Message: Clone + 'a,
|
Message: Clone + 'a,
|
||||||
Renderer: renderer::Renderer + image::Renderer<Handle = image::Handle>,
|
Renderer: renderer::Renderer + image::Renderer<Handle = image::Handle>,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue