built more of the editor + tui parts

This commit is contained in:
Maddie H 2022-11-06 18:35:05 +00:00
parent 09d26ec97e
commit a8a978d86e
No known key found for this signature in database
GPG Key ID: 64FAA9959751687D
6 changed files with 240 additions and 52 deletions

61
Cargo.lock generated
View File

@ -2,6 +2,17 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "autocfg"
version = "1.1.0"
@ -20,6 +31,17 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "colored"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd"
dependencies = [
"atty",
"lazy_static",
"winapi",
]
[[package]]
name = "crossterm"
version = "0.25.0"
@ -45,13 +67,40 @@ dependencies = [
"winapi",
]
[[package]]
name = "ctrlc"
version = "3.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d91974fbbe88ec1df0c24a4f00f99583667a7e2e6272b2b92d294d81e462173"
dependencies = [
"nix",
"winapi",
]
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "lambda"
version = "0.1.0"
dependencies = [
"colored",
"crossterm",
"ctrlc",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.137"
@ -89,6 +138,18 @@ dependencies = [
"windows-sys",
]
[[package]]
name = "nix"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e322c04a9e3440c327fca7b6c8a63e6890a32fa2ad689db972425f07e0d22abb"
dependencies = [
"autocfg",
"bitflags",
"cfg-if",
"libc",
]
[[package]]
name = "parking_lot"
version = "0.12.1"

View File

@ -5,3 +5,5 @@ edition = "2021"
[dependencies]
crossterm = "0.25"
colored = "2"
ctrlc = "3.2.3"

View File

@ -1,7 +1,11 @@
enum Mode {
Normal,
Insert,
Select
pub struct Config<'a> {
pub logo: &'a str,
}
impl<'a> Config<'a> {
pub fn new() -> Self {
Self { logo: "λ" }
}
}
pub struct Buffer<'a> {
@ -10,21 +14,41 @@ pub struct Buffer<'a> {
pub path: &'a str,
}
pub enum Mode {
Normal,
Insert,
Select,
Command,
}
impl Mode {
pub fn as_str(&self) -> &str {
match self {
Mode::Normal => "NORMAL",
Mode::Insert => "INSERT",
Mode::Select => "SELECT",
Mode::Command => "COMMAND",
}
}
}
pub struct Editor<'a> {
pub config: Config<'a>,
pub buffer: Buffer<'a>,
pub cursor: [i32; 2],
mode: Mode,
pub cursors: Vec<i32>,
pub mode: Mode,
}
impl<'a> Editor<'a> {
pub fn new() -> Self {
Editor {
config: Config::new(),
buffer: Buffer {
data: Vec::from([String::from("Hello"), String::from("World")]),
name: "[No Name]",
path: "/home/spy",
},
cursor: [0, 0],
cursors: Vec::from([0]),
mode: Mode::Normal,
}
}

View File

@ -1,18 +1,9 @@
use std::time::Duration;
mod terminal;
mod editor;
mod terminal;
mod tui;
fn main() {
let lambda = editor::Editor::new();
let mut term = terminal::Terminal::new().unwrap();
loop {
for line in lambda.buffer.data {
terminal::Terminal::write(format!("{line}"));
mut term.cursor.move_to(0, 1);
};
std::thread::sleep(Duration::from_secs(3));
break;
};
terminal::Terminal::exit();
let mut screen = terminal::Screen::new().unwrap();
tui::start(&mut screen, lambda);
}

View File

@ -1,76 +1,124 @@
use crossterm::cursor::{Hide, MoveTo, Show};
use crossterm::style::Print;
use crossterm::terminal;
use crossterm::{execute, ErrorKind};
use crossterm::style::Print;
use crossterm::cursor::{CursorShape, MoveTo};
use std::io::{stdout, Write};
pub struct Size {
pub width: usize,
pub height: usize,
}
use std::io::stdout;
// Struct for holding coordinates
#[derive(Copy, Clone)]
pub struct Coords {
pub x: usize,
pub y: usize,
}
// Creating a coordinates from two values
impl Coords {
pub fn from(x: usize, y: usize) -> Self {
Self {
x: 0,
y: 0,
}
Self { x, y }
}
}
// A cursor for writing to the terminal screen
#[derive(Copy, Clone)]
pub struct Cursor {
pub position: Coords,
pub shape: CursorShape,
pub hidden: bool,
}
// When a cursor is created
impl Cursor {
pub fn new() -> Result<Self, ErrorKind> {
let cursor = Self {
let mut cursor = Self {
position: Coords::from(0, 0),
shape: CursorShape::Block,
hidden: true,
};
Cursor::move_to(&mut cursor, 0, 0);
Cursor::move_to(&mut cursor, Coords::from(0, 0));
Cursor::hide(&mut cursor);
Ok(cursor)
}
pub fn move_to(&mut self, x: u16, y: u16) {
self.position = Coords::from(x as usize, y as usize);
execute!(stdout(), MoveTo(x, y)).unwrap()
}
}
pub struct Terminal {
// Cursor methods
impl Cursor {
pub fn move_to(&mut self, position: Coords) {
// Set the new position of the cursor
self.position = position;
// Move the cursor to the desired posiition in the terminal
execute!(stdout(), MoveTo(position.x as u16, position.y as u16)).unwrap();
}
pub fn hide(&mut self) {
// Remember that the cursor is hidden
self.hidden = true;
// Hide the cursor from the terminal screen
execute!(stdout(), Hide).unwrap();
}
pub fn show(&mut self) {
// Remember that the cursor isn't hidden
self.hidden = false;
// Show the cursor to the terminal screen
execute!(stdout(), Show).unwrap();
}
}
// A struct for holding the size of the terminal
pub struct Size {
pub width: usize,
pub height: usize,
}
// The terminal screen
pub struct Screen {
pub size: Size,
pub cursor: Cursor,
}
impl Terminal {
// For when a new terminal screen is created
impl Screen {
pub fn new() -> Result<Self, ErrorKind> {
// Get the size of the terminal
let size = terminal::size()?;
Terminal::clear();
Terminal::enter();
Ok(Self {
// Define a new terminal screen struct
let mut screen = Self {
size: Size {
width: size.0 as usize,
height: size.1 as usize,
},
cursor: Cursor::new().unwrap(),
})
}
};
pub fn enter() {
// Enter the current terminal
// Empty the terminal screen
Screen::clear();
// Enter the terminal screen
screen.enter();
// Return a result containing the terminal
Ok(screen)
}
}
// Terminal functions and methods for managing the terminal
impl Screen {
pub fn enter(&mut self) {
// Hide the cursor
self.cursor.hide();
// Enter the terminal screen
terminal::enable_raw_mode().unwrap();
execute!(stdout(), terminal::EnterAlternateScreen).unwrap();
}
pub fn exit() {
// Exit the current terminal
pub fn exit(&mut self) {
// Show the cursor
self.cursor.show();
// Exit the terminal screen
execute!(stdout(), terminal::LeaveAlternateScreen).unwrap();
terminal::disable_raw_mode().unwrap();
}
@ -84,4 +132,10 @@ impl Terminal {
// Clears the terminal screen
execute!(stdout(), terminal::Clear(terminal::ClearType::All)).unwrap();
}
pub fn write_at(&mut self, text: String, position: Coords) {
// Writes a line at a set of coordinates
self.cursor.move_to(position);
Screen::write(text);
}
}

56
src/tui.rs Normal file
View File

@ -0,0 +1,56 @@
use crate::editor::Editor;
use crate::terminal::{Coords, Screen};
use colored::Colorize;
use crossterm::event::{read, Event, KeyCode, KeyEvent, KeyModifiers};
pub fn draw_status(screen: &mut Screen, editor: &Editor) {
// Calculate where to draw the status bar
let status_height = screen.size.height - 2;
// Get the editor logo from the config
let editor_logo = &format!(" {} ", editor.config.logo) as &str;
// Write the editor logo
screen.write_at(
editor_logo.bright_yellow().bold().reversed().to_string(),
Coords::from(0, status_height),
);
// Get the current mode into a string
let mode_string = &format!(" {} ", editor.mode.as_str()) as &str;
// Calculate where to write the current mode
let x = editor_logo.len() - 1;
// Write the current mode
screen.write_at(
mode_string.green().bold().reversed().to_string(),
Coords::from(x, status_height),
);
// Get the current open file name
let file_name = &format!(" {} ", editor.buffer.name) as &str;
// Calculate where to write the file name
let x = editor_logo.len() + mode_string.len() - 1;
// Write the current file name
screen.write_at(
file_name.magenta().bold().reversed().to_string(),
Coords::from(x, status_height),
);
}
pub fn start(screen: &mut Screen, editor: Editor) {
loop {
// Draw the status bar
draw_status(screen, &editor);
// Check for any key presses
match read().unwrap() {
Event::Key(KeyEvent {
code: KeyCode::Char('q'),
modifiers: KeyModifiers::CONTROL,
..
}) => break,
_ => (),
}
}
screen.exit();
}