Merge pull request #107 from dermetfan/prefix

return length and width from utils::prefix(_length)
This commit is contained in:
Alexandre Bury 2017-02-01 11:56:04 -08:00 committed by GitHub
commit 57c1c1ad61
5 changed files with 37 additions and 24 deletions

View File

@ -9,7 +9,7 @@ use std::rc::Rc;
use theme::{BorderStyle, ColorStyle, Effect, Theme};
use unicode_segmentation::UnicodeSegmentation;
use utils::prefix_length;
use utils::prefix;
use vec::Vec2;
/// Convenient interface to draw on a subset of the screen.
@ -73,7 +73,7 @@ impl<'a> Printer<'a> {
let room = self.size.x - p.x;
// We want the number of CHARACTERS, not bytes.
// (Actually we want the "width" of the string, see unicode-width)
let prefix_len = prefix_length(text.graphemes(true), room, "");
let prefix_len = prefix(text.graphemes(true), room, "").length;
let text = &text[..prefix_len];
let p = p + self.offset;

View File

@ -3,7 +3,7 @@
use With;
use unicode_segmentation::UnicodeSegmentation;
use unicode_width::UnicodeWidthStr;
use utils::prefix_length;
use utils::prefix;
/// Generates rows of text in constrained width.
///
@ -119,11 +119,11 @@ impl<'a> Iterator for LinesIterator<'a> {
// First attempt: only break on spaces.
let prefix_length =
match prefix_length(content.split(' '), allowed_width, " ") {
match prefix(content.split(' '), allowed_width, " ").length {
// If this fail, fallback: only break on graphemes.
// There's no whitespace to skip there.
// And don't reserve the white space anymore.
0 => prefix_length(content.graphemes(true), self.width, ""),
0 => prefix(content.graphemes(true), self.width, "").length,
other => {
// If it works, advance the cursor by 1
// to jump the whitespace.

View File

@ -9,7 +9,15 @@ mod reader;
pub use self::lines_iterator::{LinesIterator, Row};
pub use self::reader::ProgressReader;
/// Computes the length of a prefix that fits in the given `width`.
/// The length and width of a part of a string.
pub struct Prefix {
/// The length (in bytes) of the string.
pub length: usize,
/// The unicode-width of the string.
pub width: usize
}
/// Computes the length (number of bytes) and width of a prefix that fits in the given `width`.
///
/// Takes non-breakable elements from `iter`, while keeping the
/// string width under `width` (and adding the length of `delimiter`
@ -26,15 +34,15 @@ pub use self::reader::ProgressReader;
/// extern crate unicode_segmentation;
/// use unicode_segmentation::UnicodeSegmentation;
///
/// # use cursive::utils::prefix_length;
/// # use cursive::utils::prefix;
/// # fn main() {
/// let my_text = "blah...";
/// // This returns the number of bytes for a prefix of `my_text` that
/// // fits within 5 cells.
/// prefix_length(my_text.graphemes(true), 5, "");
/// prefix(my_text.graphemes(true), 5, "");
/// # }
/// ```
pub fn prefix_length<'a, I>(iter: I, available_width: usize, delimiter: &str) -> usize
pub fn prefix<'a, I>(iter: I, available_width: usize, delimiter: &str) -> Prefix
where I: Iterator<Item = &'a str>
{
let delimiter_width = delimiter.width();
@ -58,10 +66,15 @@ pub fn prefix_length<'a, I>(iter: I, available_width: usize, delimiter: &str) ->
// We counted delimiter once too many times,
// but only if the iterator was non empty.
if sum == 0 { sum } else { sum - delimiter_len }
let length = if sum == 0 { sum } else { sum - delimiter_len };
Prefix {
length: length,
width: current_width
}
}
/// Computes the length of a suffix that fits in the given `width`.
/// Computes the length (number of bytes) and width of a suffix that fits in the given `width`.
///
/// Doesn't break inside elements returned by `iter`.
///
@ -69,15 +82,15 @@ pub fn prefix_length<'a, I>(iter: I, available_width: usize, delimiter: &str) ->
/// suffix from `text` that fits in `width`.
///
/// This is a shortcut for `prefix_length(iter.rev(), width, delimiter)`
pub fn suffix_length<'a, I>(iter: I, width: usize, delimiter: &str) -> usize
pub fn suffix<'a, I>(iter: I, width: usize, delimiter: &str) -> Prefix
where I: DoubleEndedIterator<Item = &'a str>
{
prefix_length(iter.rev(), width, delimiter)
prefix(iter.rev(), width, delimiter)
}
/// Computes the length of a suffix that fits in the given `width`.
/// Computes the length (number of bytes) and width of a suffix that fits in the given `width`.
///
/// Breaks between any two graphemes.
pub fn simple_suffix_length(text: &str, width: usize) -> usize {
suffix_length(text.graphemes(true), width, "")
pub fn simple_suffix(text: &str, width: usize) -> Prefix {
suffix(text.graphemes(true), width, "")
}

View File

@ -8,7 +8,7 @@ use std::rc::Rc;
use theme::{ColorStyle, Effect};
use unicode_segmentation::UnicodeSegmentation;
use unicode_width::UnicodeWidthStr;
use utils::simple_suffix_length;
use utils::simple_suffix;
use vec::Vec2;
use view::View;
@ -240,8 +240,8 @@ impl EditView {
// From the end, count the length until we reach `available`.
// Then sum the byte lengths.
let suffix_length =
simple_suffix_length(&self.content[self.offset..self.cursor],
available);
simple_suffix(&self.content[self.offset..self.cursor],
available).length;
self.offset = self.cursor - suffix_length;
// Make sure the cursor is in view
assert!(self.cursor >= self.offset);
@ -250,8 +250,8 @@ impl EditView {
// If we have too much space
if self.content[self.offset..].width() < self.last_length {
let suffix_length = simple_suffix_length(&self.content,
self.last_length - 1);
let suffix_length = simple_suffix(&self.content,
self.last_length - 1).length;
self.offset = self.content.len() - suffix_length;
}
}

View File

@ -7,7 +7,7 @@ use odds::vec::VecExt;
use theme::{ColorStyle, Effect};
use unicode_segmentation::UnicodeSegmentation;
use unicode_width::UnicodeWidthStr;
use utils::{LinesIterator, Row, prefix_length};
use utils::{LinesIterator, Row, prefix};
use vec::Vec2;
use view::{ScrollBase, SizeCache, View};
@ -126,7 +126,7 @@ impl TextArea {
let prev_row = self.rows[row_id - 1];
let prev_text = &self.content[prev_row.start..prev_row.end];
let offset = prefix_length(prev_text.graphemes(true), x, "");
let offset = prefix(prev_text.graphemes(true), x, "").length;
self.cursor = prev_row.start + offset;
}
@ -139,7 +139,7 @@ impl TextArea {
let next_row = self.rows[row_id + 1];
let next_text = &self.content[next_row.start..next_row.end];
let offset = prefix_length(next_text.graphemes(true), x, "");
let offset = prefix(next_text.graphemes(true), x, "").length;
self.cursor = next_row.start + offset;
}