use std::io::Result;
use std::io::Write;
use crossterm::cursor;
use crossterm::cursor::SetCursorStyle;
use crossterm::terminal;
use crossterm::QueueableCommand;
use crate::core::styled_buffer::StyledBuffer;
use crate::view;
pub struct StyledEditorView {
stdout: std::io::BufWriter<std::io::Stderr>,
start_position: (u16, u16),
terminal_size: (u16, u16),
}
impl Default for StyledEditorView {
fn default() -> Self {
Self {
stdout: std::io::BufWriter::new(std::io::stderr()),
start_position: (0, 0),
terminal_size: terminal::size().unwrap_or((0, 0)),
}
}
}
impl StyledEditorView {
pub fn render_line_buffer(&mut self, buffer: &StyledBuffer) -> Result<()> {
let buffer_position = buffer.position() as u16;
self.stdout
.queue(cursor::MoveToRow(self.start_position.1))?;
self.stdout
.queue(cursor::MoveToColumn(self.start_position.0))?;
self.stdout
.queue(terminal::Clear(terminal::ClearType::FromCursorDown))?;
view::base::render_styled_buffer(&mut self.stdout, buffer)?;
self.update_cursor_position(buffer_position)?;
self.flush()?;
Ok(())
}
pub fn update_cursor_position(&mut self, position: u16) -> Result<()> {
let mut move_to_position = self.start_position.0 + position;
while self.terminal_size.0 > 0 && move_to_position > self.terminal_size.0 {
move_to_position -= self.terminal_size.0;
}
self.stdout.queue(cursor::MoveToColumn(move_to_position))?;
Ok(())
}
pub fn number_of_lines(&mut self, position: u16) -> usize {
let mut lines = 1;
let mut move_to_position = self.start_position.0 + position;
while self.terminal_size.0 > 0 && move_to_position > self.terminal_size.0 {
move_to_position -= self.terminal_size.0;
lines += 1;
}
lines
}
pub fn render_prompt_buffer(&mut self, prompt: &StyledBuffer) -> Result<()> {
view::base::render_styled_buffer(&mut self.stdout, prompt)?;
self.flush()?;
Ok(())
}
pub fn render_hint(&mut self, hint: &StyledBuffer) -> Result<()> {
view::base::render_styled_buffer(&mut self.stdout, hint)?;
let (column, _) = cursor::position()?;
self.stdout.queue(cursor::MoveToColumn(column))?;
self.stdout.flush()?;
Ok(())
}
pub fn set_cursor_style(&mut self, style: SetCursorStyle) -> Result<()> {
self.stdout.queue(style)?;
Ok(())
}
pub fn set_start_position(&mut self, position: (u16, u16)) {
self.start_position = position;
}
pub fn flush(&mut self) -> Result<()> {
self.stdout.flush()?;
Ok(())
}
}