aboutsummaryrefslogtreecommitdiffstats
path: root/src/ratatui/widgets/paragraph.rs
diff options
context:
space:
mode:
authorVladislav Stepanov <8uk.8ak@gmail.com>2023-04-14 23:18:58 +0400
committerGitHub <noreply@github.com>2023-04-14 20:18:58 +0100
commitc05d2850420a2c163b8f62c33a6cef7c0ae1ad8d (patch)
tree2c44a44eda7e76fa74e78ac1fd02f55c1ed4d804 /src/ratatui/widgets/paragraph.rs
parentSwitch to uuidv7 (#864) (diff)
downloadatuin-c05d2850420a2c163b8f62c33a6cef7c0ae1ad8d.zip
Workspace reorder (#868)
* Try different workspace structure Move main crate (atuin) to be on the same level with other crates in this workspace * extract common dependencies to the workspace definition * fix base64 v0.21 deprecation warning * questionable: update deps & fix chrono deprecations possible panic sites are unchanged, they're just more visible now * Revert "questionable: update deps & fix chrono deprecations" This reverts commit 993e60f8dea81a1625a04285a617959ad09a0866.
Diffstat (limited to 'src/ratatui/widgets/paragraph.rs')
-rw-r--r--src/ratatui/widgets/paragraph.rs214
1 files changed, 0 insertions, 214 deletions
diff --git a/src/ratatui/widgets/paragraph.rs b/src/ratatui/widgets/paragraph.rs
deleted file mode 100644
index 5edfe08e..00000000
--- a/src/ratatui/widgets/paragraph.rs
+++ /dev/null
@@ -1,214 +0,0 @@
-use crate::ratatui::{
- buffer::Buffer,
- layout::{Alignment, Rect},
- style::Style,
- text::{StyledGrapheme, Text},
- widgets::{
- reflow::{LineComposer, LineTruncator, WordWrapper},
- Block, Widget,
- },
-};
-use std::iter;
-use unicode_width::UnicodeWidthStr;
-
-fn get_line_offset(line_width: u16, text_area_width: u16, alignment: Alignment) -> u16 {
- match alignment {
- Alignment::Center => (text_area_width / 2).saturating_sub(line_width / 2),
- Alignment::Right => text_area_width.saturating_sub(line_width),
- Alignment::Left => 0,
- }
-}
-
-/// A widget to display some text.
-///
-/// # Examples
-///
-/// ```
-/// # use ratatui::text::{Text, Spans, Span};
-/// # use ratatui::widgets::{Block, Borders, Paragraph, Wrap};
-/// # use ratatui::style::{Style, Color, Modifier};
-/// # use ratatui::layout::{Alignment};
-/// let text = vec![
-/// Spans::from(vec![
-/// Span::raw("First"),
-/// Span::styled("line",Style::default().add_modifier(Modifier::ITALIC)),
-/// Span::raw("."),
-/// ]),
-/// Spans::from(Span::styled("Second line", Style::default().fg(Color::Red))),
-/// ];
-/// Paragraph::new(text)
-/// .block(Block::default().title("Paragraph").borders(Borders::ALL))
-/// .style(Style::default().fg(Color::White).bg(Color::Black))
-/// .alignment(Alignment::Center)
-/// .wrap(Wrap { trim: true });
-/// ```
-#[derive(Debug, Clone)]
-pub struct Paragraph<'a> {
- /// A block to wrap the widget in
- block: Option<Block<'a>>,
- /// Widget style
- style: Style,
- /// How to wrap the text
- wrap: Option<Wrap>,
- /// The text to display
- text: Text<'a>,
- /// Scroll
- scroll: (u16, u16),
- /// Alignment of the text
- alignment: Alignment,
-}
-
-/// Describes how to wrap text across lines.
-///
-/// ## Examples
-///
-/// ```
-/// # use ratatui::widgets::{Paragraph, Wrap};
-/// # use ratatui::text::Text;
-/// let bullet_points = Text::from(r#"Some indented points:
-/// - First thing goes here and is long so that it wraps
-/// - Here is another point that is long enough to wrap"#);
-///
-/// // With leading spaces trimmed (window width of 30 chars):
-/// Paragraph::new(bullet_points.clone()).wrap(Wrap { trim: true });
-/// // Some indented points:
-/// // - First thing goes here and is
-/// // long so that it wraps
-/// // - Here is another point that
-/// // is long enough to wrap
-///
-/// // But without trimming, indentation is preserved:
-/// Paragraph::new(bullet_points).wrap(Wrap { trim: false });
-/// // Some indented points:
-/// // - First thing goes here
-/// // and is long so that it wraps
-/// // - Here is another point
-/// // that is long enough to wrap
-/// ```
-#[derive(Debug, Clone, Copy)]
-pub struct Wrap {
- /// Should leading whitespace be trimmed
- pub trim: bool,
-}
-
-impl<'a> Paragraph<'a> {
- pub fn new<T>(text: T) -> Paragraph<'a>
- where
- T: Into<Text<'a>>,
- {
- Paragraph {
- block: None,
- style: Default::default(),
- wrap: None,
- text: text.into(),
- scroll: (0, 0),
- alignment: Alignment::Left,
- }
- }
-
- pub fn block(mut self, block: Block<'a>) -> Paragraph<'a> {
- self.block = Some(block);
- self
- }
-
- pub fn style(mut self, style: Style) -> Paragraph<'a> {
- self.style = style;
- self
- }
-
- pub fn wrap(mut self, wrap: Wrap) -> Paragraph<'a> {
- self.wrap = Some(wrap);
- self
- }
-
- pub fn scroll(mut self, offset: (u16, u16)) -> Paragraph<'a> {
- self.scroll = offset;
- self
- }
-
- pub fn alignment(mut self, alignment: Alignment) -> Paragraph<'a> {
- self.alignment = alignment;
- self
- }
-}
-
-impl<'a> Widget for Paragraph<'a> {
- fn render(mut self, area: Rect, buf: &mut Buffer) {
- buf.set_style(area, self.style);
- let text_area = match self.block.take() {
- Some(b) => {
- let inner_area = b.inner(area);
- b.render(area, buf);
- inner_area
- }
- None => area,
- };
-
- if text_area.height < 1 {
- return;
- }
-
- let style = self.style;
- let mut styled = self.text.lines.iter().flat_map(|spans| {
- spans
- .0
- .iter()
- .flat_map(|span| span.styled_graphemes(style))
- // Required given the way composers work but might be refactored out if we change
- // composers to operate on lines instead of a stream of graphemes.
- .chain(iter::once(StyledGrapheme {
- symbol: "\n",
- style: self.style,
- }))
- });
-
- let mut line_composer: Box<dyn LineComposer> = if let Some(Wrap { trim }) = self.wrap {
- Box::new(WordWrapper::new(&mut styled, text_area.width, trim))
- } else {
- let mut line_composer = Box::new(LineTruncator::new(&mut styled, text_area.width));
- if let Alignment::Left = self.alignment {
- line_composer.set_horizontal_offset(self.scroll.1);
- }
- line_composer
- };
- let mut y = 0;
- while let Some((current_line, current_line_width)) = line_composer.next_line() {
- if y >= self.scroll.0 {
- let mut x = get_line_offset(current_line_width, text_area.width, self.alignment);
- for StyledGrapheme { symbol, style } in current_line {
- let width = symbol.width();
- if width == 0 {
- continue;
- }
- buf.get_mut(text_area.left() + x, text_area.top() + y - self.scroll.0)
- .set_symbol(if symbol.is_empty() {
- // If the symbol is empty, the last char which rendered last time will
- // leave on the line. It's a quick fix.
- " "
- } else {
- symbol
- })
- .set_style(*style);
- x += width as u16;
- }
- }
- y += 1;
- if y >= text_area.height + self.scroll.0 {
- break;
- }
- }
- }
-}
-
-#[cfg(test)]
-mod test {
- use super::*;
-
- #[test]
- fn zero_width_char_at_end_of_line() {
- let line = "foo\0";
- let paragraph = Paragraph::new(line);
- let mut buf = Buffer::with_lines(vec![line]);
- paragraph.render(*buf.area(), &mut buf);
- }
-}