Avoid cloning the whole paragraph content just for rendering (#9739)

* Avoid cloning the whole paragraph content just for rendering

* Fix tests
This commit is contained in:
Mo 2024-02-27 18:24:05 +01:00 committed by GitHub
parent 26b3dc29be
commit 00653c772e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 29 additions and 28 deletions

View file

@ -716,7 +716,8 @@ impl EditorView {
} }
} }
let paragraph = Paragraph::new(lines) let text = Text::from(lines);
let paragraph = Paragraph::new(&text)
.alignment(Alignment::Right) .alignment(Alignment::Right)
.wrap(Wrap { trim: true }); .wrap(Wrap { trim: true });
let width = 100.min(viewport.width); let width = 100.min(viewport.width);

View file

@ -2,6 +2,7 @@ use crate::compositor::{Component, Context};
use helix_view::graphics::{Margin, Rect}; use helix_view::graphics::{Margin, Rect};
use helix_view::info::Info; use helix_view::info::Info;
use tui::buffer::Buffer as Surface; use tui::buffer::Buffer as Surface;
use tui::text::Text;
use tui::widgets::{Block, Borders, Paragraph, Widget}; use tui::widgets::{Block, Borders, Paragraph, Widget};
impl Component for Info { impl Component for Info {
@ -31,7 +32,7 @@ impl Component for Info {
let inner = block.inner(area).inner(&margin); let inner = block.inner(area).inner(&margin);
block.render(area, surface); block.render(area, surface);
Paragraph::new(self.text.as_str()) Paragraph::new(&Text::from(self.text.as_str()))
.style(text_style) .style(text_style)
.render(inner, surface); .render(inner, surface);
} }

View file

@ -77,7 +77,7 @@ impl Component for SignatureHelp {
let (_, sig_text_height) = crate::ui::text::required_size(&sig_text, area.width); let (_, sig_text_height) = crate::ui::text::required_size(&sig_text, area.width);
let sig_text_area = area.clip_top(1).with_height(sig_text_height); let sig_text_area = area.clip_top(1).with_height(sig_text_height);
let sig_text_area = sig_text_area.inner(&margin).intersection(surface.area); let sig_text_area = sig_text_area.inner(&margin).intersection(surface.area);
let sig_text_para = Paragraph::new(sig_text).wrap(Wrap { trim: false }); let sig_text_para = Paragraph::new(&sig_text).wrap(Wrap { trim: false });
sig_text_para.render(sig_text_area, surface); sig_text_para.render(sig_text_area, surface);
if self.signature_doc.is_none() { if self.signature_doc.is_none() {
@ -100,7 +100,7 @@ impl Component for SignatureHelp {
let sig_doc_area = area let sig_doc_area = area
.clip_top(sig_text_area.height + 2) .clip_top(sig_text_area.height + 2)
.clip_bottom(u16::from(cx.editor.popup_border())); .clip_bottom(u16::from(cx.editor.popup_border()));
let sig_doc_para = Paragraph::new(sig_doc) let sig_doc_para = Paragraph::new(&sig_doc)
.wrap(Wrap { trim: false }) .wrap(Wrap { trim: false })
.scroll((cx.scroll.unwrap_or_default() as u16, 0)); .scroll((cx.scroll.unwrap_or_default() as u16, 0));
sig_doc_para.render(sig_doc_area.inner(&margin), surface); sig_doc_para.render(sig_doc_area.inner(&margin), surface);

View file

@ -346,7 +346,7 @@ impl Component for Markdown {
let text = self.parse(Some(&cx.editor.theme)); let text = self.parse(Some(&cx.editor.theme));
let par = Paragraph::new(text) let par = Paragraph::new(&text)
.wrap(Wrap { trim: false }) .wrap(Wrap { trim: false })
.scroll((cx.scroll.unwrap_or_default() as u16, 0)); .scroll((cx.scroll.unwrap_or_default() as u16, 0));

View file

@ -33,7 +33,7 @@ impl Component for Text {
fn render(&mut self, area: Rect, surface: &mut Surface, _cx: &mut Context) { fn render(&mut self, area: Rect, surface: &mut Surface, _cx: &mut Context) {
use tui::widgets::{Paragraph, Widget, Wrap}; use tui::widgets::{Paragraph, Widget, Wrap};
let par = Paragraph::new(self.contents.clone()).wrap(Wrap { trim: false }); let par = Paragraph::new(&self.contents).wrap(Wrap { trim: false });
// .scroll(x, y) offsets // .scroll(x, y) offsets
par.render(area, surface); par.render(area, surface);

View file

@ -28,15 +28,15 @@ fn get_line_offset(line_width: u16, text_area_width: u16, alignment: Alignment)
/// # use helix_tui::widgets::{Block, Borders, Paragraph, Wrap}; /// # use helix_tui::widgets::{Block, Borders, Paragraph, Wrap};
/// # use helix_tui::layout::{Alignment}; /// # use helix_tui::layout::{Alignment};
/// # use helix_view::graphics::{Style, Color, Modifier}; /// # use helix_view::graphics::{Style, Color, Modifier};
/// let text = vec![ /// let text = Text::from(vec![
/// Spans::from(vec![ /// Spans::from(vec![
/// Span::raw("First"), /// Span::raw("First"),
/// Span::styled("line",Style::default().add_modifier(Modifier::ITALIC)), /// Span::styled("line",Style::default().add_modifier(Modifier::ITALIC)),
/// Span::raw("."), /// Span::raw("."),
/// ]), /// ]),
/// Spans::from(Span::styled("Second line", Style::default().fg(Color::Red))), /// Spans::from(Span::styled("Second line", Style::default().fg(Color::Red))),
/// ]; /// ]);
/// Paragraph::new(text) /// Paragraph::new(&text)
/// .block(Block::default().title("Paragraph").borders(Borders::ALL)) /// .block(Block::default().title("Paragraph").borders(Borders::ALL))
/// .style(Style::default().fg(Color::White).bg(Color::Black)) /// .style(Style::default().fg(Color::White).bg(Color::Black))
/// .alignment(Alignment::Center) /// .alignment(Alignment::Center)
@ -51,7 +51,7 @@ pub struct Paragraph<'a> {
/// How to wrap the text /// How to wrap the text
wrap: Option<Wrap>, wrap: Option<Wrap>,
/// The text to display /// The text to display
text: Text<'a>, text: &'a Text<'a>,
/// Scroll /// Scroll
scroll: (u16, u16), scroll: (u16, u16),
/// Alignment of the text /// Alignment of the text
@ -70,7 +70,7 @@ pub struct Paragraph<'a> {
/// - Here is another point that is long enough to wrap"#); /// - Here is another point that is long enough to wrap"#);
/// ///
/// // With leading spaces trimmed (window width of 30 chars): /// // With leading spaces trimmed (window width of 30 chars):
/// Paragraph::new(bullet_points.clone()).wrap(Wrap { trim: true }); /// Paragraph::new(&bullet_points).wrap(Wrap { trim: true });
/// // Some indented points: /// // Some indented points:
/// // - First thing goes here and is /// // - First thing goes here and is
/// // long so that it wraps /// // long so that it wraps
@ -78,7 +78,7 @@ pub struct Paragraph<'a> {
/// // is long enough to wrap /// // is long enough to wrap
/// ///
/// // But without trimming, indentation is preserved: /// // But without trimming, indentation is preserved:
/// Paragraph::new(bullet_points).wrap(Wrap { trim: false }); /// Paragraph::new(&bullet_points).wrap(Wrap { trim: false });
/// // Some indented points: /// // Some indented points:
/// // - First thing goes here /// // - First thing goes here
/// // and is long so that it wraps /// // and is long so that it wraps
@ -92,15 +92,12 @@ pub struct Wrap {
} }
impl<'a> Paragraph<'a> { impl<'a> Paragraph<'a> {
pub fn new<T>(text: T) -> Paragraph<'a> pub fn new(text: &'a Text) -> Paragraph<'a> {
where
T: Into<Text<'a>>,
{
Paragraph { Paragraph {
block: None, block: None,
style: Default::default(), style: Default::default(),
wrap: None, wrap: None,
text: text.into(), text,
scroll: (0, 0), scroll: (0, 0),
alignment: Alignment::Left, alignment: Alignment::Left,
} }

View file

@ -17,14 +17,16 @@ fn terminal_buffer_size_should_not_be_limited() {
// let backend = TestBackend::new(10, 10); // let backend = TestBackend::new(10, 10);
// let mut terminal = Terminal::new(backend)?; // let mut terminal = Terminal::new(backend)?;
// let frame = terminal.draw(|f| { // let frame = terminal.draw(|f| {
// let paragraph = Paragraph::new("Test"); // let text = Text::from("Test");
// let paragraph = Paragraph::new(&text);
// f.render_widget(paragraph, f.size()); // f.render_widget(paragraph, f.size());
// })?; // })?;
// assert_eq!(frame.buffer.get(0, 0).symbol, "T"); // assert_eq!(frame.buffer.get(0, 0).symbol, "T");
// assert_eq!(frame.area, Rect::new(0, 0, 10, 10)); // assert_eq!(frame.area, Rect::new(0, 0, 10, 10));
// terminal.backend_mut().resize(8, 8); // terminal.backend_mut().resize(8, 8);
// let frame = terminal.draw(|f| { // let frame = terminal.draw(|f| {
// let paragraph = Paragraph::new("test"); // let text = Text::from("test");
// let paragraph = Paragraph::new(&text);
// f.render_widget(paragraph, f.size()); // f.render_widget(paragraph, f.size());
// })?; // })?;
// assert_eq!(frame.buffer.get(0, 0).symbol, "t"); // assert_eq!(frame.buffer.get(0, 0).symbol, "t");

View file

@ -21,8 +21,8 @@
// terminal // terminal
// .draw(|f| { // .draw(|f| {
// let size = f.size(); // let size = f.size();
// let text = vec![Spans::from(SAMPLE_STRING)]; // let text = Text::from(SAMPLE_STRING);
// let paragraph = Paragraph::new(text) // let paragraph = Paragraph::new(&text)
// .block(Block::default().borders(Borders::ALL)) // .block(Block::default().borders(Borders::ALL))
// .alignment(alignment) // .alignment(alignment)
// .wrap(Wrap { trim: true }); // .wrap(Wrap { trim: true });
@ -88,8 +88,8 @@
// terminal // terminal
// .draw(|f| { // .draw(|f| {
// let size = f.size(); // let size = f.size();
// let text = vec![Spans::from(s)]; // let text = Text::from(s);
// let paragraph = Paragraph::new(text) // let paragraph = Paragraph::new(&text)
// .block(Block::default().borders(Borders::ALL)) // .block(Block::default().borders(Borders::ALL))
// .wrap(Wrap { trim: true }); // .wrap(Wrap { trim: true });
// f.render_widget(paragraph, size); // f.render_widget(paragraph, size);
@ -120,8 +120,8 @@
// terminal // terminal
// .draw(|f| { // .draw(|f| {
// let size = f.size(); // let size = f.size();
// let text = vec![Spans::from(s)]; // let text = Text::from(s);
// let paragraph = Paragraph::new(text) // let paragraph = Paragraph::new(&text)
// .block(Block::default().borders(Borders::ALL)) // .block(Block::default().borders(Borders::ALL))
// .wrap(Wrap { trim: true }); // .wrap(Wrap { trim: true });
// f.render_widget(paragraph, size); // f.render_widget(paragraph, size);
@ -155,8 +155,8 @@
// terminal // terminal
// .draw(|f| { // .draw(|f| {
// let size = f.size(); // let size = f.size();
// let text = Text::from(line);
// let paragraph = Paragraph::new(line).block(Block::default().borders(Borders::ALL)); // let paragraph = Paragraph::new(&text).block(Block::default().borders(Borders::ALL));
// f.render_widget(paragraph, size); // f.render_widget(paragraph, size);
// }) // })
// .unwrap(); // .unwrap();
@ -174,7 +174,7 @@
// let text = Text::from( // let text = Text::from(
// "段落现在可以水平滚动了!\nParagraph can scroll horizontally!\nShort line", // "段落现在可以水平滚动了!\nParagraph can scroll horizontally!\nShort line",
// ); // );
// let paragraph = Paragraph::new(text) // let paragraph = Paragraph::new(&text)
// .block(Block::default().borders(Borders::ALL)) // .block(Block::default().borders(Borders::ALL))
// .alignment(alignment) // .alignment(alignment)
// .scroll(scroll); // .scroll(scroll);