Git Product home page Git Product logo

Comments (5)

rhysd avatar rhysd commented on August 15, 2024 4

I'm slowly starting to think about this as a new feature after 0.4.0. This is the biggest missing feature for this crate to be a simple textarea. Since width of each line is repeatedly required on rendering underlying Paragraph widget, lines would need to cache their width. I would need to start with internal refactoring because currently lines are kept as simplest Vec<String> and there is no place for the cache.

from tui-textarea.

brooksvb avatar brooksvb commented on August 15, 2024 2

Based on my incomplete attempt to implement this before getting too busy to continue (#13), there's a couple considerations I'll mention.

In addition to caching line length, the number of rows (wrapped) that a single line occupies based on the area width might be good to cache.

In working out the logic for counting rows and positioning the cursor and viewport, it became quite annoying to try and distinguish between "rows" and "lines", whichever may be which, where one of them refers to a line of text in the text buffer, and one refers to rows in the terminal viewport. I think I have settled on referring to terminal "rows" and text "lines".

Another consideration is support for multiple-byte/char graphemes. Any special characters that are actually composed of multiple characters will change the way line length needs to be computed. I'm not sure if support for those is intended or not.

Another consideration that affects line length and line wrap calculations is whether or not line numbers are active.

I had a decent start to computing row wraps with https://github.com/rhysd/tui-textarea/pull/13/files#diff-4007187965c1fea4fd252a76f5f1007b2ea59f6d86e2f454edee547c5036be24R11

Another consideration that I hadn't yet figured out how to handle is that since text lines do not 1-1 map to terminal rows, and the viewport is positioned based on a text line, it is not possible to position the top edge of the terminal viewport in the middle of a wrapped row. I avoided this complexity with the requirement that scrolling up or down can only be done by an entire text line at a time; it works, but it's not typical expected behavior from a text field.

Perhaps it is necessary to create a buffer of "virtual" lines, that split the source text lines based on line wraps before the terminal renders them, allowing you to set the position in the middle of a wrapped text line.

Another sticky consideration is handling vertical cursor movement properly for wrapped lines. In my implementation, I stuck with a simplified movement that doesn't really consider line wraps. Moving the cursor up and down would not only require considering line wraps, but considering those graphemes that may be composed of multiple characters and affect the counting logic to place the cursor in the right spot.

If you get to this issue and need help, I will try to lend my efforts again.

from tui-textarea.

brooksvb avatar brooksvb commented on August 15, 2024

I was also hoping this was a feature. I'll take a look to see if I can figure out how to implement it.

from tui-textarea.

brooksvb avatar brooksvb commented on August 15, 2024

Here is where a Paragraph widget is created during rendering:

tui-textarea/src/widget.rs

Lines 122 to 125 in d4bbccb

let text = self.text(top_row as usize, height as usize);
let mut inner = Paragraph::new(text)
.style(self.0.style())
.alignment(self.0.alignment());

Paragraph has a wrap() method to control line wrapping:
https://docs.rs/tui/latest/tui/widgets/struct.Wrap.html

So I think the render function could be changed to something like

        let mut inner = Paragraph::new(text)
            .style(self.0.style())
            .alignment(self.0.alignment())
            .wrap(Wrap { trim: false });

Of course a couple things will need to be done like adding a wrap option to the TextArea widget and related methods. I'm not sure if this would interfere with any of the logic for window scrolling and scroll position; perhaps there is an assumption that there is a 1-to-1 relation between a line in the text content and a rendered line in the terminal. I don't fully understand all the scroll position logic in that file.

from tui-textarea.

pythops avatar pythops commented on August 15, 2024

+1 for this one, would be great to have 🙏

from tui-textarea.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.