Skip to content

Commit

Permalink
merging divergent branches
Browse files Browse the repository at this point in the history
  • Loading branch information
Deezzir committed Feb 7, 2023
2 parents 1d36d9d + 8335614 commit 686663f
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 100 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ edition = "2021"
regex = "1.3.9"
chrono = "0.4.23"
ncurses = { version = "5.101.0", features = ["wide"] }
ctrlc = "3.2.5"
2 changes: 1 addition & 1 deletion TODO.list
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
TODO(): Add subtodos
TODO(): Add proper Ctrl+c handling
TODO(): Fix autoresizing
TODO(): Finish a Rust TODO app
TODO(): Finish a Game of Life with Rust with GUI(SDL?)
Expand All @@ -11,3 +10,4 @@ DONE(2023-02-04 19:12:32.253412 -05:00): Add editing option to TODO app
DONE(2023-02-04 19:17:54.422294 -05:00): Add inserting option to TODO app
DONE(2023-02-06 13:47:25.683700140 -05:00): Add buffered stdout write
DONE(2023-02-06 16:00:00.876958453 -05:00): Add autoresizing of the TODO app UI(tree?)
DONE(2023-02-06 23:09:36.666041 -05:00): Add proper Ctrl+c handling
161 changes: 75 additions & 86 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ extern crate regex;
mod mods;

use chrono::Local;
use std::env::args;
use std::path::Path;
use std::process::exit;

use ncurses::*;
use std::sync::atomic::Ordering;

use mods::todo::*;
use mods::ui::*;
use mods::utils::*;

const SELECTED_PAIR: i16 = 1;
const UNSELECTED_PAIR: i16 = 2;
Expand Down Expand Up @@ -40,7 +40,14 @@ Author: Iurii Kondrakov <[email protected]>

const FILE_PATH: &str = "TODO.list";

#[derive(PartialEq)]
enum Mode {
Edit,
Normal,
}

fn main() {
set_sig_handler();
let file_path: String = get_args();
let file_name: String = Path::new(&file_path)
.file_name()
Expand All @@ -50,13 +57,13 @@ fn main() {
.to_string();

ncurses_init();
let mut editing: bool = false;
let mut mode: Mode = Mode::Normal;
let mut editing_cursor: usize = 0;
let mut app: TodoApp = TodoApp::new();
let mut ui = UI::new();

app.parse(&file_path);
loop {
while !QUIT.load(Ordering::SeqCst) {
erase();
let date = Local::now().format("%Y %a %b %d %H:%M:%S");
let mut w = 0;
Expand All @@ -76,15 +83,20 @@ fn main() {
app.get_dones_n()
),
UI_PAIR,
Some(A_BOLD()),
);
ui.label_styled(
&format!("[MESSAGE]: {}", app.get_message()),
UI_PAIR,
Some(A_BOLD()),
);
ui.label_styled(&format!("[MESSAGE]: {}", app.get_message()), UI_PAIR);
}
ui.end_layout();

ui.begin_layout(LayoutKind::Vert);
{
ui.label_styled(&format!("[DATE]: {date}"), UI_PAIR);
ui.label_styled(&format!("[FILE]: {file_name}"), UI_PAIR);
ui.label_styled(&format!("[DATE]: {date}"), UI_PAIR, Some(A_BOLD()));
ui.label_styled(&format!("[FILE]: {file_name}"), UI_PAIR, Some(A_BOLD()));
}
ui.end_layout();
}
Expand All @@ -98,15 +110,15 @@ fn main() {
ui.begin_layout(LayoutKind::Vert);
{
if app.is_in_todo_panel() {
ui.label_styled("[TODO]", HIGHLIGHT_PAIR);
ui.label_styled("[TODO]", HIGHLIGHT_PAIR, None);
} else {
ui.label_styled(" TODO ", UNSELECTED_PAIR);
ui.label_styled(" TODO ", UNSELECTED_PAIR, None);
}
ui.hl();
for todo in app.get_todos() {
if app.is_cur_todo(todo) {
if app.is_in_todo_panel() {
if editing {
if mode == Mode::Edit {
ui.edit_label(
todo.get_text(),
editing_cursor,
Expand All @@ -116,12 +128,14 @@ fn main() {
ui.label_styled(
&format!("- [ ] {}", todo.get_text()),
SELECTED_PAIR,
None,
);
}
} else {
ui.label_styled(
&format!("- [ ] {}", todo.get_text()),
UNSELECTED_PAIR,
None,
);
}
} else {
Expand All @@ -134,15 +148,15 @@ fn main() {
ui.begin_layout(LayoutKind::Vert);
{
if app.is_in_done_panel() {
ui.label_styled("[DONE]", HIGHLIGHT_PAIR);
ui.label_styled("[DONE]", HIGHLIGHT_PAIR, None);
} else {
ui.label_styled(" DONE ", UNSELECTED_PAIR);
ui.label_styled(" DONE ", UNSELECTED_PAIR, None);
}
ui.hl();
for done in app.get_dones() {
if app.is_cur_done(done) {
if app.is_in_done_panel() {
if editing {
if mode == Mode::Edit {
ui.edit_label(
done.get_text(),
editing_cursor,
Expand All @@ -152,12 +166,14 @@ fn main() {
ui.label_styled(
&format!("- [X] ({}) {}", done.get_date(), done.get_text()),
SELECTED_PAIR,
None,
);
}
} else {
ui.label_styled(
&format!("- [X]|{}| {}", done.get_date(), done.get_text()),
UNSELECTED_PAIR,
None,
);
}
} else {
Expand All @@ -174,37 +190,55 @@ fn main() {
refresh();
let key = getch();
if key != ERR {
if !editing {
app.clear_message();
match char::from_u32(key as u32).unwrap() {
'k' | '\u{103}' => app.go_up(),
'j' | '\u{102}' => app.go_down(),
'g' => app.go_top(),
'G' => app.go_bottom(),
'K' => app.drag_up(),
'J' => app.drag_down(),
'\n' => app.transfer_item(),
'd' => app.delete_item(),
'i' => {
editing_cursor = app.insert_item();
editing = editing_cursor == 0;
}
'r' => {
editing_cursor = app.edit_item();
editing = editing_cursor > 0;
match mode {
Mode::Normal => {
app.clear_message();
match char::from_u32(key as u32).unwrap() {
'k' | '\u{103}' => app.go_up(),
'j' | '\u{102}' => app.go_down(),
'g' => app.go_top(),
'G' => app.go_bottom(),
'K' => app.drag_up(),
'J' => app.drag_down(),
'\n' => app.transfer_item(),
'd' => app.delete_item(),
'i' => {
if let Some(cur) = app.insert_item() {
editing_cursor = cur;
mode = Mode::Edit;
}
}
'a' => {
if let Some(cur) = app.append_item() {
editing_cursor = cur;
mode = Mode::Edit;
}
}
'r' => {
if let Some(cur) = app.edit_item() {
editing_cursor = cur;
mode = Mode::Edit;
}
}
'u' => app.undo(),
'\t' => app.toggle_panel(),
'q' | '\u{3}' => break,
_ => {}
}
'u' => app.undo(),
'\t' => app.toggle_panel(),
'q' | '\u{3}' => break,
_ => {}
}
} else {
match key as u8 as char {
'\n' | '\u{1b}' => {
editing = app.finish_edit();
editing_cursor = if editing { editing_cursor } else { 0 };
Mode::Edit => {
match key as u8 as char {
'\n' => {
//'\u{1b}'
mode = if app.finish_edit() {
editing_cursor = 0;
Mode::Normal
} else {
Mode::Edit
};
}
_ => app.edit_item_with(&mut editing_cursor, key),
}
_ => app.edit_item_with(&mut editing_cursor, key),
}
}
}
Expand All @@ -213,48 +247,3 @@ fn main() {
endwin();
app.save(&file_path).unwrap();
}

fn ncurses_init() {
setlocale(LcCategory::all, "");
// Init ncurses
initscr();
raw();
// Allow for extended keyboard (like F1).
noecho();
keypad(stdscr(), true);
curs_set(CURSOR_VISIBILITY::CURSOR_INVISIBLE);
// Set timeout and esc delay
timeout(16);
set_escdelay(0);
// Set colors
use_default_colors();
start_color();
init_pair(HIGHLIGHT_PAIR, COLOR_BLACK, COLOR_GREEN);
init_pair(SELECTED_PAIR, COLOR_BLACK, COLOR_CYAN);
init_pair(UNSELECTED_PAIR, COLOR_BLACK, COLOR_WHITE);
init_pair(UI_PAIR, COLOR_WHITE, COLOR_BLACK);
}

fn get_args() -> String {
let mut args = args().skip(1);

match args.next() {
Some(arg) => match arg.as_str() {
"-f" | "--file" => args.next().unwrap_or_else(|| {
eprintln!("[ERROR]: No file given for '{arg}'.");
eprintln!("{USAGE}");
exit(1);
}),
"-h" | "--help" => {
println!("{HELP}\n{USAGE}");
exit(0);
}
_ => {
eprintln!("[ERROR]: Unknown argument: '{arg}'.");
eprintln!("{USAGE}");
exit(1);
}
},
None => FILE_PATH.to_string(),
}
}
1 change: 1 addition & 0 deletions src/mods.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod todo;
pub mod ui;
pub mod utils;
34 changes: 25 additions & 9 deletions src/mods/todo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,18 @@ impl Operation {
pub struct Item {
text: String,
date: DateTime<Local>,
sub_items: Vec<Item>,
dones_num: usize,
}

impl Item {
fn new(text: String, date: DateTime<Local>) -> Self {
Self { text, date }
Self {
text,
date,
sub_items: Vec::new(),
dones_num: 0,
}
}

pub fn get_text(&self) -> &String {
Expand Down Expand Up @@ -528,21 +535,21 @@ impl TodoApp {
}
}

pub fn insert_item(&mut self) -> usize {
pub fn insert_item(&mut self) -> Option<usize> {
assert!(
!self.is_in_edit(),
"insert_item() called in already running edit mode."
);

let mut editing_cursor = 1;
let mut editing_cursor = None;

match self.panel {
Panel::Todo => {
self.todos.record_state();
self.operation_stack
.push(Operation::new(Action::Insert, Panel::Todo));
self.todos.insert();
editing_cursor = 0;
editing_cursor = Some(0);

self.operation_stack
.push(Operation::new(Action::InEdit, self.panel));
Expand All @@ -556,7 +563,15 @@ impl TodoApp {
editing_cursor
}

pub fn edit_item(&mut self) -> usize {
pub fn append_item(&mut self) -> Option<usize> {
assert!(
!self.is_in_edit(),
"append_item() called in already running edit mode."
);
todo!("append_item() not implemented yet.");
}

pub fn edit_item(&mut self) -> Option<usize> {
assert!(
!self.is_in_edit(),
"edit_item() called in already running edit mode."
Expand Down Expand Up @@ -586,9 +601,10 @@ impl TodoApp {
self.operation_stack
.push(Operation::new(Action::InEdit, self.panel));
self.message.push_str("Editing current item.");
}

editing_cursor
return Some(editing_cursor);
}
None
}

pub fn edit_item_with(&mut self, cur: &mut usize, key: i32) {
Expand All @@ -615,7 +631,7 @@ impl TodoApp {
Panel::Todo => {
if self.todos.get_item().text.is_empty() {
self.message.push_str("TODO item can't be empty.");
return true;
return false;
}
}
Panel::Done => {
Expand All @@ -626,7 +642,7 @@ impl TodoApp {
}

self.operation_stack.pop();
false
true
}

fn is_in_edit(&self) -> bool {
Expand Down
Loading

0 comments on commit 686663f

Please sign in to comment.