Repository: helix-editor/helix (language: rust)

Issue:
Soft wrap doesn't correctly handle combining diacritical marks
### Summary

Currently soft wrap treats letters with [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) as "word boundaries", which will cause it to insert line breaks in the middle of words like éclair or résumé.

![éclair](https://github.com/user-attachments/assets/27c5097d-7002-4633-9690-fcd4e92ccd4c)

### Reproduction Steps

_No response_

### Helix log

_No response_

### Platform

Linux

### Terminal Emulator

foot version: 1.20.1 +pgo +ime +graphemes +toplevel-icon -assertions

### Installation Method

source

### Helix Version

25.01-21-g9721144e


Discussion / hints:

Fix patch:
diff --git a/helix-core/src/graphemes.rs b/helix-core/src/graphemes.rs
index 4ca85d315cc1..c914df8bd1b4 100644
--- a/helix-core/src/graphemes.rs
+++ b/helix-core/src/graphemes.rs
@@ -64,7 +64,7 @@ impl<'a> Grapheme<'a> {
     }
 
     pub fn is_whitespace(&self) -> bool {
-        !matches!(&self, Grapheme::Other { g } if !g.chars().all(char_is_whitespace))
+        !matches!(&self, Grapheme::Other { g } if !g.chars().next().is_some_and(char_is_whitespace))
     }
 
     // TODO currently word boundaries are used for softwrapping.
@@ -72,7 +72,7 @@ impl<'a> Grapheme<'a> {
     // This could however be improved in the future by considering unicode
     // character classes but
     pub fn is_word_boundary(&self) -> bool {
-        !matches!(&self, Grapheme::Other { g,.. } if g.chars().all(char_is_word))
+        !matches!(&self, Grapheme::Other { g,.. } if g.chars().next().is_some_and(char_is_word))
     }
 }
 


Test patch:
diff --git a/helix-core/src/doc_formatter/test.rs b/helix-core/src/doc_formatter/test.rs
index 415ce8f6a131..21be2e535df4 100644
--- a/helix-core/src/doc_formatter/test.rs
+++ b/helix-core/src/doc_formatter/test.rs
@@ -102,6 +102,14 @@ fn long_word_softwrap() {
     );
 }
 
+#[test]
+fn softwrap_multichar_grapheme() {
+    assert_eq!(
+        softwrap_text("xxxx xxxx xxx a\u{0301}bc\n"),
+        "xxxx xxxx xxx \n.ábc \n "
+    )
+}
+
 fn softwrap_text_at_text_width(text: &str) -> String {
     let mut text_fmt = TextFormat::new_test(true);
     text_fmt.soft_wrap_at_text_width = true;