From 3008a92048b72ca03e6352769683e955ba61b212 Mon Sep 17 00:00:00 2001 From: Sondre Wold Date: Sun, 21 Apr 2024 07:21:15 +0200 Subject: [PATCH] Editor and Terminal basics --- octo/Cargo.toml | 2 ++ octo/src/.editor.rs.swp | Bin 0 -> 12288 bytes octo/src/.terminal.rs.swp | Bin 0 -> 12288 bytes octo/src/editor.rs | 60 ++++++++++++++++++++++++++++++++++++++ octo/src/main.rs | 8 ++++- octo/src/terminal.rs | 52 +++++++++++++++++++++++++++++++++ 6 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 octo/src/.editor.rs.swp create mode 100644 octo/src/.terminal.rs.swp create mode 100644 octo/src/editor.rs create mode 100644 octo/src/terminal.rs diff --git a/octo/Cargo.toml b/octo/Cargo.toml index 17e593b..bc088c1 100644 --- a/octo/Cargo.toml +++ b/octo/Cargo.toml @@ -6,3 +6,5 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +crossterm = "0.27.0" +termion = "3.0.0" diff --git a/octo/src/.editor.rs.swp b/octo/src/.editor.rs.swp new file mode 100644 index 0000000000000000000000000000000000000000..e95abb777709dc8259cf31202ced9e82d919f00f GIT binary patch literal 12288 zcmeI2&x;&I6vt~-1QR!k;wca+laO@7?(CQq5^J*?h>1ZYD7!`^2t!YIwbO1-*QBc2 zb+gRIyLb{Jh#+{>g9q^s(1Ry0O8x;A45A)#@gg{WtEW3%^CN5aB!MdU%yd`1diCo2 zUNsEUo!09wU8c`BTLkS%LXLcPJiZx!Gk5h%LX^lN$+v_V+N*68c53nR`BxWDHM^q6 zXIt-94wo*7Fz@k9tEIjaZ}SirBGh8^p=7wkqeKhYlxnso*XtB;3hYaPT*r%N=E?G@ zXN#kLtZ|e+{nV9xxp2l#0jGddz$xGqa0)mDoB~b(r@(`)fbP$c8`#1_HuwpA3%&v$ zf(w9w=fE=f>v2MEfiJ)ZAOUXx2Ij%T;J1T>`~rRkpMngmgTvra@Hh7M2ly3y4?YG1 zpg<3py`KlqfJ5LBa0{B;1n-06AO@GfF|Z1jfoo0yr+`zyDc}@v3jD7MP^(FNc*C-`F3l2qtY{{h z|7!lkMfIP}%-J(L@4Chwhr`OG@_D=T`Ct9x5ss`)pJ{!WWID}`dX3%6&1hh9Q+J*^k$u#5e3rFhgvHI{K0m!`DrkyZLyxhcjZ4+?Y7KQ{^tTf$qiA^aFG#We3k zFV{r~K3!a+>s;ljK8v8K(h*~cVC}%|CFhw}Mh96XkCC2kHBgqzJ_W6%HNojBk5-rwj|1cfrOMy!<7H>B@nVpqJfd1q zgcN9gcUohj?yLf1G!7tTU0@q1?o!x(-YF`-TF4ZIHC%^SUzuRX?@UjWaF3hHu~KOI z%f}&#svJhS7b%*m%<8zAS*A^|(ZQBC$Isl}37_p|-=R)q+YU4pqCYOB%rpCt?U1C` zPwBmO^9b*D@(E8@Im?8&jXl?||gr!Y{u&f4YE;?mY;^{Ss= zJtto|d+#X%@K83u2G{@_U;}J`4X^<=zy_Xm1FpX!9$^vB`GvgU&nru3f6FH}zy{a= z8(;%$fDNz#Hoykh02^QfY~UF*5T`;6o);o|0mrqZ;Bv`=+_LLE{O+_Dxo}bHVC( zvf7l@=fAoL!=yA;n=rhkoeqXgIchYvtH~%QvOkj7sXelZQ3?e+9_^x4 zd8cKwLsd=VpQ8Jq>ZWRYGRFs8LhSr8wDM9Gw+? oR5zp*?BOk5>QxW%S$!DdRjxaZ);FdNR@uU)Xv+6Z<`hEz3k~zL6#xJL literal 0 HcmV?d00001 diff --git a/octo/src/editor.rs b/octo/src/editor.rs new file mode 100644 index 0000000..bef7795 --- /dev/null +++ b/octo/src/editor.rs @@ -0,0 +1,60 @@ +use crate::Terminal; +use termion::event::Key; + +fn die(e: std::io::Error) { + Terminal::clear_screen(); + panic!("{:?}", e); +} + +pub struct Editor { + should_quit: bool, + terminal: Terminal, +} + +impl Editor { + pub fn run(&mut self) { + loop { + if let Err(error) = self.refresh_screen() { + die(error); + } + if self.should_quit { + break; + } + if let Err(error) = self.process_keypress() { + die(error); + } + } + } + pub fn default() -> Self { + Self { + should_quit: false, + terminal: Terminal::default().expect("Failed to create terminal"), + } + } + + fn refresh_screen(&self) -> Result<(), std::io::Error> { + Terminal::clear_screen(); + Terminal::cursor_position(0, 0); + if self.should_quit { + println!("Goodbye.\r"); + } else { + self.draw_rows(); + Terminal::cursor_position(0, 0); + } + Terminal::flush() + } + + fn process_keypress(&mut self) -> Result<(), std::io::Error> { + let pressed_key = Terminal::read_key()?; + match pressed_key { + Key::Ctrl('q') => self.should_quit = true, + _ => (), + }; + Ok(()) + } + fn draw_rows(&self) { + for _ in 0..self.terminal.size().height { + println!("~\r"); + } + } +} diff --git a/octo/src/main.rs b/octo/src/main.rs index e7a11a9..0637681 100644 --- a/octo/src/main.rs +++ b/octo/src/main.rs @@ -1,3 +1,9 @@ +#![warn(clippy::all, clippy::pedantic)] +mod editor; +mod terminal; +use editor::Editor; +pub use terminal::Terminal; + fn main() { - println!("Hello, world!"); + Editor::default().run(); } diff --git a/octo/src/terminal.rs b/octo/src/terminal.rs new file mode 100644 index 0000000..599d873 --- /dev/null +++ b/octo/src/terminal.rs @@ -0,0 +1,52 @@ +use std::io::{self, stdout, Write}; +use termion::event::Key; +use termion::input::TermRead; +use termion::raw::{IntoRawMode, RawTerminal}; + +pub struct Size { + pub width: u16, + pub height: u16, +} + +pub struct Terminal { + size: Size, + _stdout: RawTerminal, +} + +impl Terminal { + pub fn default() -> Result { + let size = termion::terminal_size()?; + Ok(Self { + size: Size { + width: size.0, + height: size.1, + }, + _stdout: stdout().into_raw_mode()?, + }) + } + pub fn size(&self) -> &Size { + &self.size + } + + pub fn clear_screen() { + print!("{}", termion::clear::All); + } + + pub fn cursor_position(x: u16, y: u16) { + let x = x.saturating_add(1); + let y = y.saturating_add(1); + print!("{}", termion::cursor::Goto(x, y)); + } + + pub fn flush() -> Result<(), std::io::Error> { + io::stdout().flush() + } + + pub fn read_key() -> Result { + loop { + if let Some(key) = io::stdin().lock().keys().next() { + return key; + } + } + } +} -- 2.39.5