Skip to content

Commit 763a5c9

Browse files
committed
fix(Unicode): fixes two bugs where non-English characters were stripped or caused a panic with help wrapping
Closes #626
1 parent 881a647 commit 763a5c9

File tree

3 files changed

+20
-22
lines changed

3 files changed

+20
-22
lines changed

Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ strsim = { version = "~0.5.1", optional = true }
2020
yaml-rust = { version = "~0.3.2", optional = true }
2121
clippy = { version = "~0.0.79", optional = true }
2222
unicode-width = { version = "~0.1.3", optional = true }
23+
unicode-segmentation = { version = "~0.1.2", optional = true }
2324
term_size = { version = "~0.1.0", optional = true }
2425

2526
[dev-dependencies]
@@ -30,7 +31,7 @@ default = ["suggestions", "color", "wrap_help"]
3031
suggestions = ["strsim"]
3132
color = ["ansi_term", "libc"]
3233
yaml = ["yaml-rust"]
33-
wrap_help = ["libc", "unicode-width", "term_size"]
34+
wrap_help = ["libc", "unicode-width", "term_size", "unicode-segmentation"]
3435
lints = ["clippy", "nightly"]
3536
nightly = [] # for building with nightly and unstable features
3637
unstable = [] # for building with unstable features on stable Rust

src/app/help.rs

+16-21
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::cmp;
55
use std::usize;
66

77
use vec_map::VecMap;
8+
use unicode_segmentation::UnicodeSegmentation;
89

910
use errors::{Error, Result as ClapResult};
1011

@@ -463,33 +464,27 @@ impl<'a> Help<'a> {
463464
debug!("Enough space to wrap...");
464465
if longest_w < avail_chars {
465466
sdebugln!("Yes");
466-
let mut indices = vec![];
467-
let mut idx = 0;
468-
loop {
469-
idx += avail_chars - 1;
470-
if idx >= help.len() {
471-
break;
467+
let mut prev_space = 0;
468+
let mut j = 0;
469+
let mut i = 0;
470+
for (idx, g) in (&*help.clone()).grapheme_indices(true) {
471+
debugln!("iter;idx={},g={}", idx, g);
472+
if g != " " { continue; }
473+
if str_width(&help[j..idx]) < avail_chars {
474+
debugln!("Still enough space...");
475+
prev_space = idx;
476+
continue;
472477
}
473-
// 'a' arbitrary non space char
474-
if help.chars().nth(idx).unwrap_or('a') != ' ' {
475-
idx = find_idx_of_space(&*help, idx);
476-
}
477-
debugln!("Adding idx: {}", idx);
478-
debugln!("At {}: {:?}", idx, help.chars().nth(idx));
479-
indices.push(idx);
480-
if str_width(&help[idx..]) <= avail_chars {
481-
break;
482-
}
483-
}
484-
for (i, idx) in indices.iter().enumerate() {
485-
debugln!("iter;i={},idx={}", i, idx);
486-
let j = idx + (2 * i);
478+
debugln!("Adding Newline...");
479+
j = prev_space + (2 * i);
480+
debugln!("i={},prev_space={},j={}", i, prev_space, j);
487481
debugln!("removing: {}", j);
488-
debugln!("at {}: {:?}", j, help.chars().nth(j));
482+
debugln!("char at {}: {}", j, &help[j..j]);
489483
help.remove(j);
490484
help.insert(j, '{');
491485
help.insert(j + 1, 'n');
492486
help.insert(j + 2, '}');
487+
i += 1;
493488
}
494489
} else {
495490
sdebugln!("No");

src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,8 @@ extern crate bitflags;
416416
extern crate vec_map;
417417
#[cfg(feature = "wrap_help")]
418418
extern crate term_size;
419+
#[cfg(feature = "wrap_help")]
420+
extern crate unicode_segmentation;
419421

420422
#[cfg(feature = "yaml")]
421423
pub use yaml_rust::YamlLoader;

0 commit comments

Comments
 (0)