5 warnings

This commit is contained in:
ldlda committed 2025-07-03 18:17:16 +07:00
1 parent c165b3fa94
commit a4cafc0ef9
2 files changed
+212 -74

No files matched your search

+211 -73
View File
@@ -1,29 +1,31 @@
use crossterm::event::Event; use crossterm::event::{
use crossterm::event::{self, KeyCode, KeyEvent, KeyEventKind, KeyModifiers, MouseEvent}; self, Event, KeyCode, KeyEvent, KeyEventKind, KeyModifiers, MouseEvent, MouseEventKind,
use ratatui::text::{ToLine, ToSpan}; };
use ratatui::widgets::Clear;
use ratatui::{ use ratatui::{
Frame, Terminal, Frame, Terminal,
layout::{Constraint, Layout, Spacing}, layout::{Constraint, Layout, Position, Rect, Size, Spacing},
prelude::Backend, prelude::Backend,
style::{Style, Stylize}, style::{Style, Stylize},
text::{Line, Span, Text}, text::{Line, Span, Text, ToLine, ToSpan},
widgets::{Block, BorderType, Padding, Paragraph}, widgets::{Block, BorderType, Clear, Padding, Paragraph, Wrap},
}; };
use ratatui_explorer::{FileExplorer, Input}; use ratatui_explorer::{FileExplorer, Input};
use std::io::{BufRead, BufReader};
use std::path::Path;
use std::{ use std::{
fmt::Debug, fmt::Debug,
fs::File, fs::File,
io::{self}, io::{self, BufRead, BufReader},
path::PathBuf, path::{Path, PathBuf},
}; };
#[derive(Default)]
pub struct DocCache { pub struct DocCache {
content: String, content: String,
/// height - width. up down first, left right second.
offset: (u16, u16), offset: (u16, u16),
length_hint: u16, /// same format as offset
screen: Rect,
/// is also lines - max len, which means height width.
length_hint: (u16, u16),
} }
pub struct Doc { pub struct Doc {
doc: PathBuf, doc: PathBuf,
@@ -95,6 +97,23 @@ impl<'a> App<'a> {
} }
} }
#[derive(Debug, PartialEq, Eq, Clone)]
enum TextScroll {
UpOne,
DownOne,
UpHalf,
DownHalf,
UpFull,
DownFull,
Up(u16),
Down(u16),
// not when i Wrap.
Left(u16),
Right(u16),
LeftOne,
RightOne,
}
#[derive(Debug, Default, PartialEq, Eq, Clone)] #[derive(Debug, Default, PartialEq, Eq, Clone)]
enum Message { enum Message {
#[default] #[default]
@@ -105,7 +124,7 @@ enum Message {
DocSwitcherAction(Input), DocSwitcherAction(Input),
/// close doc switcher because there is a new file coming /// close doc switcher because there is a new file coming
NewDoc, NewDoc,
TextScroll(Option<bool>, Option<bool>), TextScroll(TextScroll),
} }
impl App<'_> { impl App<'_> {
pub fn run<B: Backend>(&mut self, term: &mut Terminal<B>) -> io::Result<()> { pub fn run<B: Backend>(&mut self, term: &mut Terminal<B>) -> io::Result<()> {
@@ -118,7 +137,7 @@ impl App<'_> {
} }
Ok(()) Ok(())
} }
fn view(&self, frame: &mut Frame) { fn view(&mut self, frame: &mut Frame) {
frame.render_widget(Clear, frame.area()); // tf this about frame.render_widget(Clear, frame.area()); // tf this about
let [header, main, foot] = Layout::vertical([ let [header, main, foot] = Layout::vertical([
@@ -142,6 +161,14 @@ impl App<'_> {
Span::from("lda").style(Style::new().fg(ratatui::style::Color::Indexed(202))); Span::from("lda").style(Style::new().fg(ratatui::style::Color::Indexed(202)));
frame.render_widget(lda_text, lda); frame.render_widget(lda_text, lda);
let content_block = Block::bordered().title(Line::from(" file content ").left_aligned()); let content_block = Block::bordered().title(Line::from(" file content ").left_aligned());
// NOOOO this is only reason self is mut
if let Some(Doc {
cache: Some(DocCache { ref mut screen, .. }),
..
}) = self.doc
{
*screen = content_block.inner(main);
}
let mut file_name = Text::default().blue().centered(); let mut file_name = Text::default().blue().centered();
let content; let content;
@@ -150,7 +177,9 @@ impl App<'_> {
file_name.push_span(doc.doc.display().to_string()); file_name.push_span(doc.doc.display().to_string());
if let Some(cache) = &doc.cache { if let Some(cache) = &doc.cache {
let text = Text::from(cache.content.as_str()); let text = Text::from(cache.content.as_str());
content = Paragraph::new(text).scroll(cache.offset); content = Paragraph::new(text)
.wrap(Wrap { trim: false })
.scroll(cache.offset); // pronblem
} else { } else {
content = Paragraph::new("errored buhhhhhh".to_line().centered()) content = Paragraph::new("errored buhhhhhh".to_line().centered())
} }
@@ -162,10 +191,14 @@ impl App<'_> {
frame.render_widget(header_box, header); frame.render_widget(header_box, header);
frame.render_widget(content, main); frame.render_widget(content, main);
frame.render_widget( frame.render_widget(
Line::from_iter([ {
Span::from("enter to choose file, "), let mut line = Line::default();
Span::from("esc or q to quit"), if self.explorer.is_some() {
]), line.push_span(Span::from("enter to choose file, "));
};
line.push_span(Span::from("esc or q to quit"));
line
},
foot, foot,
); );
{ {
@@ -232,7 +265,11 @@ impl App<'_> {
Err(_e) => self.state = AppState::FileError, Err(_e) => self.state = AppState::FileError,
}; };
} }
Message::OpenDocSwitcher => self.state = AppState::DocSwitcher, Message::OpenDocSwitcher => {
if self.explorer.is_some() {
self.state = AppState::DocSwitcher
};
}
Message::NewDoc => { Message::NewDoc => {
let Some(ref mut expl) = self.explorer else { let Some(ref mut expl) = self.explorer else {
// no way bro doesnt have this and then close doc // no way bro doesnt have this and then close doc
@@ -250,6 +287,9 @@ impl App<'_> {
{ {
self.doc = Some(Doc::new(file_name)); self.doc = Some(Doc::new(file_name));
return Some(Message::ReloadDoc); return Some(Message::ReloadDoc);
} else if let Some(Doc { cache: None, .. }) = self.doc {
self.state = AppState::FileError;
return None;
} }
} }
return Some(Message::Main); return Some(Message::Main);
@@ -280,20 +320,21 @@ impl App<'_> {
}; // noooo }; // noooo
} }
Message::TextScroll(up, right) => { Message::TextScroll(thing) => {
if let Some(ref mut doc) = self.doc { if let Some(Doc {
if let Some(up) = up { cache: Some(ref mut cache),
let bij = if up { -1 } else { 1 }; // fuck is this about ..
if let Some(ref mut cache) = doc.cache { }) = self.doc
cache.offset.0 = cache.offset.0.saturating_add_signed(bij); && !matches!(
} // disabled here
}; thing,
if let Some(right) = right { TextScroll::Left(_)
let bij = if right { 1 } else { -1 }; | TextScroll::Right(_)
if let Some(ref mut cache) = doc.cache { | TextScroll::LeftOne
cache.offset.1 = cache.offset.1.saturating_add_signed(bij); | TextScroll::RightOne
} )
}; {
cache.update_scroll(thing);
} }
} }
}; };
@@ -336,7 +377,13 @@ impl App<'_> {
Ok(None) Ok(None)
} }
_ => match ev { _ => {
macro_rules! osScroll {
($this:expr) => {
Ok(Some(Message::TextScroll($this)))
};
}
match ev {
event::Event::Key(KeyEvent { event::Event::Key(KeyEvent {
code, code,
modifiers, modifiers,
@@ -346,6 +393,7 @@ impl App<'_> {
if kind == KeyEventKind::Release { if kind == KeyEventKind::Release {
return Ok(None); return Ok(None);
} }
if code == KeyCode::Char('q') || code == KeyCode::Esc { if code == KeyCode::Char('q') || code == KeyCode::Esc {
return Ok(Some(Message::Quit)); return Ok(Some(Message::Quit));
} else if code == KeyCode::Char('r') } else if code == KeyCode::Char('r')
@@ -357,44 +405,84 @@ impl App<'_> {
} }
// no what is this code block // no what is this code block
if self.doc.is_some() { if self.doc.is_some() {
let updown = tri_state( match code {
code.is_up() || code.is_char('k'), KeyCode::Up | KeyCode::Char('k') => {
code.is_down() || code.is_char('j'), return osScroll!(TextScroll::UpOne);
); }
let leftright = tri_state( KeyCode::Down | KeyCode::Char('j') => {
code.is_right() || code.is_char('l'), return osScroll!(TextScroll::DownOne);
code.is_left() || code.is_char('h'), }
); KeyCode::Right | KeyCode::Char('l') => {
return Ok(Some(Message::TextScroll(updown, leftright))); return osScroll!(TextScroll::RightOne);
}
KeyCode::Left | KeyCode::Char('h') => {
return osScroll!(TextScroll::LeftOne);
}
KeyCode::Char('u') => return osScroll!(TextScroll::UpHalf),
KeyCode::Char('d') => return osScroll!(TextScroll::DownHalf),
KeyCode::Char('f') => return osScroll!(TextScroll::UpFull),
KeyCode::Char('b') => return osScroll!(TextScroll::DownFull),
_ => (),
};
}; };
Ok(None) Ok(None)
} }
event::Event::Mouse(MouseEvent { Event::Mouse(MouseEvent {
kind, kind,
column: _, column,
row: _, row,
modifiers, modifiers,
}) => { }) => {
if self.doc.is_some() { if let Some(Doc {
eprintln!("{modifiers}"); cache: Some(DocCache { screen, .. }),
let updown = tri_state( ..
kind.is_scroll_up() && !modifiers.contains(KeyModifiers::SHIFT), }) = self.doc
kind.is_scroll_down() && !modifiers.contains(KeyModifiers::SHIFT), && screen.contains(Position::new(column, row))
); {
let leftright = tri_state( match kind {
kind.is_scroll_right() MouseEventKind::ScrollDown
|| (kind.is_scroll_down() if !modifiers.contains(KeyModifiers::SHIFT) =>
&& modifiers.contains(KeyModifiers::SHIFT)), {
kind.is_scroll_left() return osScroll!(TextScroll::Down(
|| (kind.is_scroll_up() TextScroll::SCROLL_STEPS
&& modifiers.contains(KeyModifiers::SHIFT)), ));
); }
return Ok(Some(Message::TextScroll(updown, leftright))); MouseEventKind::ScrollUp
if !modifiers.contains(KeyModifiers::SHIFT) =>
{
return osScroll!(TextScroll::Up(TextScroll::SCROLL_STEPS));
}
MouseEventKind::ScrollLeft => {
return osScroll!(TextScroll::Left(
TextScroll::SCROLL_STEPS
));
}
MouseEventKind::ScrollUp
if modifiers.contains(KeyModifiers::SHIFT) =>
{
return osScroll!(TextScroll::Left(
TextScroll::SCROLL_STEPS
));
}
MouseEventKind::ScrollRight => {
return osScroll!(TextScroll::Right(
TextScroll::SCROLL_STEPS
));
}
MouseEventKind::ScrollDown
if modifiers.contains(KeyModifiers::SHIFT) => {}
_ => {
return osScroll!(TextScroll::Right(
TextScroll::SCROLL_STEPS
));
}
}
} }
Ok(None) Ok(None)
} }
_ => Ok(None), _ => Ok(None),
}, }
}
} }
} }
} }
@@ -421,25 +509,67 @@ impl Doc {
} }
impl DocCache { impl DocCache {
pub fn new(doc: impl AsRef<Path>) -> io::Result<Self> { pub fn new(doc: impl AsRef<Path>) -> io::Result<Self> {
read_lines(&doc).map(|(l, content)| Self { read_lines(&doc).map(|((l, m), content)| Self {
content, content,
offset: (0, 0), offset: (0, 0),
length_hint: l as _, length_hint: (l as _, m as _),
..Default::default()
}) })
} }
pub fn reload_doc(&mut self, doc: impl AsRef<Path>) -> io::Result<()> { pub fn reload_doc(&mut self, doc: impl AsRef<Path>) -> io::Result<()> {
let a = read_lines(doc)?; // bail as early as possible let a = read_lines(doc)?; // bail as early as possible
self.content.clear(); self.content.clear();
let lh; let (lh, m);
(lh, self.content) = a; ((lh, m), self.content) = a;
self.length_hint = lh as _; self.length_hint = (lh as _, m as _);
Ok(()) Ok(())
} }
fn update_scroll(&mut self, update: TextScroll) {
{
let bih = get_size_as_ldaformat(&self.screen);
let (up, right) = update.to_two_numbers(bih);
if up != 0 {
self.offset.0 = self
.offset
.0
.saturating_add_signed(-up) // real
.min(self.length_hint.0.saturating_sub(bih.0));
};
if right != 0 {
unreachable!("disabled left right handling from update");
self.offset.1 = self
.offset
.1
.saturating_add_signed(right)
.min(self.length_hint.1.saturating_sub(bih.1));
};
}
}
}
impl TextScroll {
const SCROLL_STEPS: u16 = 3;
pub fn to_two_numbers(&self, (height, _width): (u16, u16)) -> (i16, i16) {
match self {
TextScroll::UpOne => (1, 0),
TextScroll::DownOne => (-1, 0),
TextScroll::UpHalf => ((height / 2) as _, 0),
TextScroll::DownHalf => (-((height / 2) as i16), 0),
TextScroll::UpFull => (height as _, 0),
TextScroll::DownFull => (-(height as i16), 0),
TextScroll::Up(r) => (*r as _, 0),
TextScroll::Down(r) => (-(*r as i16), 0),
// not ever getting it
_ => unreachable!("disabled left right handling from update"),
TextScroll::Left(r) => (0, -(*r as i16)),
TextScroll::Right(r) => (0, (*r as i16)),
TextScroll::LeftOne => (0, -1),
TextScroll::RightOne => (0, 1),
}
}
} }
/// returns some true if real, some false if fake, none if neither, /// returns some true if real, some false if fake, none if neither,
/// idk what happens if both /// idk what happens if both
fn tri_state(real: bool, fake: bool) -> Option<bool> { fn _tri_state(real: bool, fake: bool) -> Option<bool> {
if real { if real {
Some(true) Some(true)
} else if fake { } else if fake {
@@ -449,20 +579,28 @@ fn tri_state(real: bool, fake: bool) -> Option<bool> {
} }
} }
fn get_size_as_ldaformat(r: &Rect) -> (u16, u16) {
let Size { height, width } = r.as_size();
(height, width)
}
/// this works for now /// this works for now
fn read_lines(doc: impl AsRef<Path>) -> io::Result<(usize, String)> { fn read_lines(doc: impl AsRef<Path>) -> io::Result<((usize, usize), String)> {
let file = File::open(doc)?; let file = File::open(doc)?;
let lenf = file.metadata()?.len() as _; let lenf = file.metadata()?.len() as _;
let mut strg = String::with_capacity(lenf); let mut strg = String::with_capacity(lenf);
let mut fuek = BufReader::with_capacity(lenf, file); let mut fuek = BufReader::with_capacity(lenf, file);
let mut c = 0; let mut c = 0;
let mut m = 0;
loop { loop {
let r = fuek.read_line(&mut strg)?; let mut str_new = String::new();
let r = fuek.read_line(&mut str_new)?;
if r > 0 { if r > 0 {
c += 1; c += 1;
m = m.max(str_new.len());
strg.push_str(&str_new);
} else { } else {
break; break;
} }
} }
Ok((c, strg)) Ok(((c, m), strg))
} }
+1 -1
View File
@@ -12,7 +12,7 @@ fn main() -> color_eyre::Result<()> {
let mut r = ratatui::init(); let mut r = ratatui::init();
let mut exp = FileExplorer::new()?; let mut exp = FileExplorer::new()?;
app::App::new() app::App::new()
.with_doc("src/main.rs")? .with_doc("src/app.rs")?
.with_explorer(&mut exp) .with_explorer(&mut exp)
.run(&mut r)?; .run(&mut r)?;
ratatui::restore(); ratatui::restore();