Convert a "content position" (from strip_styling output) back to a "structural visual" position (includes } and empty content markers). When `skip_structural` is true, returns the visual position immediately before the `content_pos`-th visible character — or at the end of the visual text when `content_pos` equals the content length. This means the cursor only ever lands on visible-character boun
(raw: &str, content_pos: usize, snap_to_content: bool)
| 2406 | /// the cursor only ever lands on visible-character boundaries (used by |
| 2407 | /// `no_styles_movement`). |
| 2408 | pub fn content_to_cursor(raw: &str, content_pos: usize, snap_to_content: bool) -> usize { |
| 2409 | let chars: Vec<char> = raw.chars().collect(); |
| 2410 | let len = chars.len(); |
| 2411 | let mut visual = 0usize; |
| 2412 | let mut content = 0usize; |
| 2413 | let mut escaped = false; |
| 2414 | let mut in_style_def = false; |
| 2415 | |
| 2416 | if snap_to_content { |
| 2417 | // No-structural mode: check `content >= content_pos` BEFORE advancing |
| 2418 | for i in 0..len { |
| 2419 | let c = chars[i]; |
| 2420 | |
| 2421 | if escaped { |
| 2422 | if content >= content_pos { |
| 2423 | return visual; |
| 2424 | } |
| 2425 | visual += 1; |
| 2426 | content += 1; |
| 2427 | escaped = false; |
| 2428 | continue; |
| 2429 | } |
| 2430 | |
| 2431 | match c { |
| 2432 | '\\' => { escaped = true; } |
| 2433 | '{' if !in_style_def => { in_style_def = true; } |
| 2434 | '|' if in_style_def => { |
| 2435 | in_style_def = false; |
| 2436 | if i + 1 < len && chars[i + 1] == '}' { |
| 2437 | visual += 1; // empty content marker — skip |
| 2438 | } |
| 2439 | } |
| 2440 | '}' if !in_style_def => { |
| 2441 | visual += 1; // } exit marker — skip |
| 2442 | } |
| 2443 | _ if in_style_def => {} |
| 2444 | _ => { |
| 2445 | if content >= content_pos { |
| 2446 | return visual; |
| 2447 | } |
| 2448 | visual += 1; |
| 2449 | content += 1; |
| 2450 | } |
| 2451 | } |
| 2452 | } |
| 2453 | } else { |
| 2454 | // Structural mode: break when `content >= content_pos` at top of loop |
| 2455 | for i in 0..len { |
| 2456 | if content >= content_pos { |
| 2457 | break; |
| 2458 | } |
| 2459 | let c = chars[i]; |
| 2460 | |
| 2461 | if escaped { |
| 2462 | visual += 1; |
| 2463 | content += 1; |
| 2464 | escaped = false; |
| 2465 | continue; |
no outgoing calls