Keep trailing semicolons attached to the preceding word when wrapping (#54546)

Eric Holk created

When soft-wrapping text, `LineWrapper::is_word_char` determines which
characters stick to the preceding word at wrap boundaries. The list
already includes trailing punctuation like `,`, `.`, and `:`, but was
missing `;`. As a result, a message like "we won't pass it on; no big
deal" could wrap with `;` isolated at the start of the next line (`on` /
`; no`).

This was most visible in the agent panel message editor but affects any
surface that uses soft-wrapping.

Also adds `assert_word("on;")` to `test_is_word_char` to guard against
regressions.

Release Notes:

- Fixed trailing `;` being wrapped to a new line instead of staying
attached to the preceding word.

Change summary

crates/gpui/src/text_system/line_wrapper.rs | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

Detailed changes

crates/gpui/src/text_system/line_wrapper.rs 🔗

@@ -241,8 +241,9 @@ impl LineWrapper {
 
         // Some other known special characters that should be treated as word characters,
         // e.g. `a-b`, `var_name`, `I'm`/`won’t`, '@mention`, `#hashtag`, `100%`, `3.1415`,
-        // `2^3`, `a~b`, `a=1`, `Self::new`, etc.
-        matches!(c, '-' | '_' | '.' | '\'' | '’' | '‘' | '$' | '%' | '@' | '#' | '^' | '~' | ',' | '=' | ':') ||
+        // `2^3`, `a~b`, `a=1`, `Self::new`, etc. Trailing punctuation like `,`, `.`, `:`, `;`
+        // is included so it stays attached to the preceding word when wrapping.
+        matches!(c, '-' | '_' | '.' | '\'' | '’' | '‘' | '$' | '%' | '@' | '#' | '^' | '~' | ',' | '=' | ':' | ';') ||
         // `⋯` character is special used in Zed, to keep this at the end of the line.
         matches!(c, '⋯')
     }
@@ -837,6 +838,7 @@ mod tests {
         assert_word("$variable");
         assert_word("a=1");
         assert_word("Self::is_word_char");
+        assert_word("on;");
         assert_word("more⋯");
         assert_word("won’t");
         assert_word("‘twas");