1use crossterm::terminal;
2
3pub mod input;
4mod render;
5pub use render::Renderer;
6mod table;
7pub use table::Table;
8pub use input::{Dir, PromptAction, Action};
9
10use std::fmt;
11
12#[derive(Clone, Copy, Debug)]
13pub enum Mode {
14 Prompt(PromptType),
15 Table,
16 Insert,
17 Exit, }
19
20impl fmt::Display for Mode {
21 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
22 use Mode::*;
23 let s = match self {
24 Insert => "Insert Mode",
25 Table => "Movement Mode",
26 Prompt(_) => "Prompt",
27 _ => "",
28 };
29 write!(f, "{}", s)
30 }
31}
32
33#[derive(Clone, Copy, Debug)]
34pub enum PromptType {
35 EditReplace,
36 EditAppend,
37 Command,
38}
39
40impl PromptType {
41 fn ps2(self) -> String {
42 use PromptType::*;
43 match self {
44 EditReplace => "edit: ",
45 EditAppend => "edit: ",
46 Command => ":",
47 }.to_string()
48 }
49}
50
51#[derive(Clone, Copy, Debug)]
53pub struct Cursor {
54 pub x: usize,
55 pub y: usize,
56}
57
58impl Cursor {
59 pub fn new() -> Self {
60 Self { x: 0, y: 0 }
61 }
62
63 pub fn move_dir(&mut self, dir: Dir, table: &Table) {
64 use Dir::*;
65 match dir {
66 Up => if self.y > 0 {
67 self.y -= 1;
68 }
69 Down => if self.y < table.dims().1 - 1 {
70 self.y += 1;
71 }
72 Left => if self.x > 0 {
73 self.x -= 1;
74 }
75 Right => if self.x < table.dims().0 - 1 {
76 self.x += 1;
77 }
78 Top => {
79 self.y = 0;
80 }
81 Bottom => {
82 self.y = table.dims().1 - 1;
83 }
84 Start => {
85 self.x = 0;
86 }
87 End => {
88 self.x = table.dims().0 - 1;
89 }
90 }
91 }
92}
93
94pub fn align_anchor(anchor: &mut Cursor, c: Cursor) {
95 let (w, hs) = terminal::size().unwrap();
96 let h = hs as usize;
97
98 if anchor.y > c.y {
100 anchor.y = c.y;
101 }
102
103 if anchor.y + h - 3 < c.y {
106 anchor.y = c.y + 3 - h; }
108}