Skip to content

Commit

Permalink
🐛 Fixed editor shortcuts not getting registered
Browse files Browse the repository at this point in the history
  • Loading branch information
nwrenger committed Mar 29, 2024
1 parent f3ac8b4 commit aee349b
Show file tree
Hide file tree
Showing 5 changed files with 240 additions and 266 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "omega"
version = "0.2.3"
version = "0.2.4"
repository = "https://github.com/nwrenger/omega"
documentation = "https://github.com/nwrenger/omega"
readme = "README.md"
Expand Down
59 changes: 6 additions & 53 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use cursive::{
event::{Event, Key},
theme::{BaseColor, BorderStyle, Color, PaletteColor, Theme},
view::{Nameable, Resizable, Scrollable},
views::{LinearLayout, NamedView, OnEventView, Panel, ResizedView, ScrollView},
views::{LinearLayout, NamedView, Panel, ResizedView, ScrollView},
};
use cursive_buffered_backend::BufferedBackend;
use cursive_tree_view::TreeView;
Expand Down Expand Up @@ -87,7 +87,7 @@ impl State {
}

// Helper types of the main/tree panel
pub type EditorPanel = Panel<OnEventView<ResizedView<ScrollView<NamedView<EditArea>>>>>;
pub type EditorPanel = Panel<ResizedView<ScrollView<NamedView<EditArea>>>>;
pub type TreePanel = ResizedView<Panel<ScrollView<NamedView<TreeView<TreeEntry>>>>>;

/// Starts the app && event loop
Expand Down Expand Up @@ -139,9 +139,9 @@ pub fn start() {
siv.add_global_callback(Event::CtrlChar('d'), |s| events::delete(s).handle(s));
siv.add_global_callback(Event::CtrlChar('s'), |s| events::save(s, None).handle(s));

let mut raw_text_area = EditArea::new().disabled();
let mut raw_edit_area = EditArea::new().disabled();
// detecting edits on `EditArea`, and updating global state
raw_text_area.set_on_edit(|siv, content, _| {
raw_edit_area.set_on_edit(|siv, content, _| {
let mut state = siv
.with_user_data(|state: &mut State| state.clone())
.unwrap_or_default();
Expand All @@ -168,56 +168,9 @@ pub fn start() {
siv.set_user_data(state);
});

let text_area = raw_text_area.with_name("editor").scrollable().full_screen();
let edit_are = raw_edit_area.with_name("editor").scrollable().full_screen();

let events = OnEventView::new(text_area)
.on_pre_event(Event::CtrlChar('c'), move |s| {
if let Some(mut text_area) = s.find_name::<EditArea>("editor") {
events::copy(&mut text_area).handle(s);
}
})
.on_pre_event(Event::CtrlChar('v'), move |s| {
if let Some(mut text_area) = s.find_name::<EditArea>("editor") {
events::paste(&mut text_area).handle(s);
}
})
.on_pre_event(Event::CtrlChar('x'), move |s| {
if let Some(mut text_area) = s.find_name::<EditArea>("editor") {
events::cut(&mut text_area).handle(s);
}
})
.on_pre_event(Event::Shift(Key::Up), |s| {
if let Some(mut text_area) = s.find_name::<EditArea>("editor") {
events::move_line(&mut text_area, events::Direction::Up).handle(s);
}
})
.on_pre_event(Event::Shift(Key::Down), |s| {
if let Some(mut text_area) = s.find_name::<EditArea>("editor") {
events::move_line(&mut text_area, events::Direction::Down).handle(s);
}
})
.on_pre_event(Event::Shift(Key::Left), |s| {
if let Some(mut text_area) = s.find_name::<EditArea>("editor") {
events::move_cursor_end(&mut text_area, events::Direction::Left).handle(s);
}
})
.on_pre_event(Event::Shift(Key::Right), |s| {
if let Some(mut text_area) = s.find_name::<EditArea>("editor") {
events::move_cursor_end(&mut text_area, events::Direction::Right).handle(s);
}
})
.on_pre_event(Key::Tab, |s| {
if let Some(mut text_area) = s.find_name::<EditArea>("editor") {
events::tabulator(&mut text_area, true).handle(s);
}
})
.on_pre_event(Event::Shift(Key::Tab), |s| {
if let Some(mut text_area) = s.find_name::<EditArea>("editor") {
events::tabulator(&mut text_area, false).handle(s);
}
});

let editor_panel = Panel::new(events).title("").with_name("editor_title");
let editor_panel = Panel::new(edit_are).title("").with_name("editor_title");
let file_tree_panel = Panel::new(file_tree::new(&project_path))
.title("")
.fixed_width(40)
Expand Down
211 changes: 7 additions & 204 deletions src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,9 @@ pub fn open_paths(
if let Some(current_file) = current_file {
match fs::read_to_string(current_file) {
Ok(content) => {
siv.call_on_name("editor", |text_area: &mut EditArea| {
text_area.set_content(content.clone());
text_area.enable();
siv.call_on_name("editor", |edit_area: &mut EditArea| {
edit_area.set_content(content.clone());
edit_area.enable();
})
.unwrap();
siv.call_on_name("editor_title", |view: &mut EditorPanel| {
Expand All @@ -214,10 +214,10 @@ pub fn open_paths(
}
};
} else if project_path.exists() {
siv.call_on_name("editor", |text_area: &mut EditArea| {
text_area.set_content(' ');
text_area.set_cursor(0);
text_area.disable();
siv.call_on_name("editor", |edit_area: &mut EditArea| {
edit_area.set_content(' ');
edit_area.set_cursor(0);
edit_area.disable();
})
.unwrap();
siv.call_on_name("editor_title", |view: &mut EditorPanel| view.set_title(""))
Expand Down Expand Up @@ -535,200 +535,3 @@ pub fn save(siv: &mut Cursive, other: Option<(&PathBuf, &String)>) -> Result<()>
}
Ok(())
}

/// Copies the line where the cursor currently is
pub fn copy(text_area: &mut EditArea) -> Result<()> {
let content = text_area.get_content().to_string();
let cursor_pos = text_area.cursor();

let (current_line, _) = get_cursor_line_info(&content, cursor_pos);

let lines: Vec<&str> = content.split('\n').collect();

crate::clipboard::set_content(lines[current_line].to_string() + "\n")?;

Ok(())
}

/// Pasts the current clipboard
pub fn paste(text_area: &mut EditArea) -> Result<()> {
let content = text_area.get_content().to_string();
let cursor_pos = text_area.cursor();

let (current_line, cursor_in_line) = get_cursor_line_info(&content, cursor_pos);

let mut lines: Vec<&str> = content.split('\n').collect();
let text = crate::clipboard::get_content()?;
let split = lines[current_line].split_at(cursor_in_line);
let inserted_line = split.0.to_string() + text.as_str() + split.1;
lines[current_line] = inserted_line.as_str();

let new_content: String = lines.join("\n");
text_area.set_content(new_content);

text_area.set_cursor(cursor_pos + text.to_string().len());

Ok(())
}

/// Cuts the line where the cursor currently is
pub fn cut(text_area: &mut EditArea) -> Result<()> {
let content = text_area.get_content().to_string();
let cursor_pos = text_area.cursor();

let (current_line, _) = get_cursor_line_info(&content, cursor_pos);

let mut lines: Vec<&str> = content.split('\n').collect();
crate::clipboard::set_content(lines[current_line].to_string() + "\n")?;
lines.remove(current_line);

let new_content: String = lines.join("\n");
text_area.set_content(new_content);

Ok(())
}

/// Implements the tabulator
pub fn tabulator(text_area: &mut EditArea, ident: bool) -> Result<()> {
let content = text_area.get_content().to_string();
let cursor_pos = text_area.cursor();

let (current_line, _) = get_cursor_line_info(&content, cursor_pos);
let mut lines: Vec<&str> = content.split('\n').collect();
let tab_size = 4;

if ident {
let str_to_add = " ".repeat(tab_size);
let new_line = str_to_add + lines[current_line];

text_area.set_cursor(cursor_pos + tab_size);

lines[current_line] = &new_line;
let new_content: String = lines.join("\n");
text_area.set_content(new_content);
} else {
let str_to_add = " ".repeat(tab_size);
let new_line = lines[current_line].replacen(&str_to_add, "", 1);

if lines[current_line] != new_line {
text_area.set_cursor(cursor_pos - tab_size);
}

lines[current_line] = &new_line;
let new_content: String = lines.join("\n");
text_area.set_content(new_content);
};

Ok(())
}

/// Directions for further functions
#[derive(PartialEq)]
pub enum Direction {
Up,
Down,
Left,
Right,
}

/// Moves the line withing the cursor in the specified direction
pub fn move_line(text_area: &mut EditArea, direction: Direction) -> Result<()> {
let content = text_area.get_content().to_string();
let cursor_pos = text_area.cursor();

let (current_line, cursor_in_line) = get_cursor_line_info(&content, cursor_pos);

let mut lines: Vec<&str> = content.split('\n').collect();

if (current_line == 0 && direction == Direction::Up)
|| (current_line == lines.len() - 1 && direction == Direction::Down)
{
return Ok(());
}

let line_to_move = lines.remove(current_line);
match direction {
Direction::Up => lines.insert(current_line - 1, line_to_move),
Direction::Down => lines.insert(current_line + 1, line_to_move),
_ => {}
}

let new_content: String = lines.join("\n");
text_area.set_content(new_content);

let new_cursor_pos = if direction == Direction::Up && current_line > 0 {
lines
.iter()
.take(current_line - 1)
.map(|line| line.len() + 1)
.sum::<usize>()
+ cursor_in_line
} else {
lines
.iter()
.take(current_line + (if direction == Direction::Down { 1 } else { 0 }))
.map(|line| line.len() + 1)
.sum::<usize>()
+ cursor_in_line
};

text_area.set_cursor(new_cursor_pos);

Ok(())
}

/// Move cursor to the start or end of the current line
pub fn move_cursor_end(text_area: &mut EditArea, direction: Direction) -> Result<()> {
let content = text_area.get_content().to_string();
let cursor_pos = text_area.cursor();

let (current_line, _) = get_cursor_line_info(&content, cursor_pos);

let lines: Vec<&str> = content.split('\n').collect();
match direction {
Direction::Left => {
let new_cursor_pos = lines
.iter()
.take(current_line)
.map(|line| line.len() + 1)
.sum::<usize>();
text_area.set_cursor(new_cursor_pos);
}
Direction::Right => {
let new_cursor_pos = if current_line < lines.len() {
lines
.iter()
.take(current_line + 1)
.map(|line| line.len() + 1)
.sum::<usize>()
- 1
} else {
content.len()
};
text_area.set_cursor(new_cursor_pos);
}
_ => {}
}

Ok(())
}

/// Returns the current line number and the cursor's position within that line
fn get_cursor_line_info(content: &str, cursor_pos: usize) -> (usize, usize) {
let lines: Vec<&str> = content.split('\n').collect();
let mut current_line = 0;
let mut cursor_in_line = 0;
let mut count = 0;

for (i, line) in lines.iter().enumerate() {
let line_len = line.len() + 1;
if count + line_len > cursor_pos {
current_line = i;
cursor_in_line = cursor_pos - count;
break;
}
count += line_len;
}

(current_line, cursor_in_line)
}
Loading

0 comments on commit aee349b

Please sign in to comment.