mirror of
https://github.com/zed-industries/zed.git
synced 2026-08-22 23:45:58 +00:00
Some checks are pending
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
deploy_nightly_docs / deploy_docs (push) Waiting to run
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / build_visual_tests_binary (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions
# Objective Fixes #60192 Closes https://github.com/zed-industries/zed/issues/62308 `editor: align selection` lines cursors up by their buffer column, and that column counts bytes. If a multi-byte character sits before the cursor, the byte column is larger than the position the cursor is actually drawn at, so the row gets padded with the wrong number of spaces. The issue reports it with `←` (3 bytes) and `π` (2 bytes): ``` a ← 1 # one bc ← π # two ``` Put a cursor on each `#`, run the action, and the result is still misaligned: ``` a ← 1 # one bc ← π # two ``` This is not the columnar selection bug fixed in #57097. That one was `select_columns` in `selection.rs`, where the output is a selection range. This one is `align_selections` in `editor.rs`, where the output is inserted spaces, so the same byte-column assumption was left behind in a second place, and fixing it here needs a rounding step that the first fix did not. ## Solution Measure each cursor by its x offset in the laid-out display row (`DisplaySnapshot::x_for_display_point`), take the target for a column as the furthest x across the rows, then turn the difference into whole spaces by dividing by the advance width of `' '`. The offset that carries into later columns becomes an x offset instead of a column count. The display map has already expanded tabs by the time the row is laid out, so a leading tab now counts as its expanded width instead of as a single byte. Two things I would look at first in review: - The division rounds instead of truncating. The x offsets are built by repeated float addition, so a gap that should be exactly three spaces can arrive as 2.9999998, and truncating inserts two. - The function returns early if the space advance is missing or zero. Dividing by zero gives `inf`, which saturates to a huge `u32` and then tries to allocate that many spaces. I did not add any public items and did not touch `selection.rs`. ## Testing `cargo test -p editor align` on Windows: 6 passed, 0 failed. That is the new test plus the two existing `align_selections` tests, which I did not change and which still pass. `test_align_selections_with_multibyte_chars` covers the repro from the issue, a second column whose offset has to carry past a multi-byte character in the first, a leading tab, a non-BMP character, and a case where multi-byte characters sit after the cursors and nothing should move. I also checked that the test catches the bug rather than just passing: reverting the change in `editor.rs` and keeping the test makes it fail on the repro, inserting four spaces where three are right. Putting the change back makes it pass. The two older align tests pass either way, since they are pure ASCII. What I have not covered: - Wide CJK characters, combining marks, and ZWJ clusters. These should be right by construction, since the code measures advances rather than counting characters, but I have no tests for them. The headless text system behind `gpui::test` gives every BMP character the same advance, so a test there would assert the test double's behavior rather than the real renderer's. - Proportional fonts. Aligning with inserted spaces cannot be exact when glyph widths vary. The code rounds to the nearest whole space. - Soft-wrapped rows. I measure x from the start of the wrapped row but still group cursors by buffer row, so two cursors on one buffer row that sit either side of a wrap boundary get measured from different origins, and the carried offset crosses that boundary as if they shared one. The old byte-column code did not have that particular failure. I left it alone because fixing it is a different change, but I would rather flag it than have you find it. - I work on Windows and have no macOS machine. The arithmetic is platform independent, so I do not expect a difference, but I have not checked. To try it: paste the two lines from the issue, put a cursor on each `#` with `editor: select next`, then run `editor: align selection`. The two `#` should line up. ## Self-Review Checklist: - [ ] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable --- Release Notes: - Fixed `editor: align selections` misaligning rows and Vim `ctrl-d` / `ctrl-u` / `ctrl-f` leaving the cursor behind on lines with multi-byte characters or tabs. --------- Co-authored-by: Kirill Bulatov <kirill@zed.dev>
118 lines
4.1 KiB
TOML
118 lines
4.1 KiB
TOML
[files]
|
|
ignore-files = true
|
|
ignore-hidden = false
|
|
extend-exclude = [
|
|
".git/",
|
|
|
|
# Typewriter model names used for agent branch names aren't typos.
|
|
"crates/agent_ui/src/branch_names.rs",
|
|
|
|
# Contributor names aren't typos.
|
|
".mailmap",
|
|
|
|
# File suffixes aren't typos.
|
|
"crates/theme/src/icon_theme.rs",
|
|
"crates/extensions_ui/src/extension_suggest.rs",
|
|
|
|
# Some mock data is flagged as typos.
|
|
"crates/assistant_tools/src/web_search_tool.rs",
|
|
|
|
# Suppress false positives in database schema.
|
|
"crates/collab/migrations/20251208000000_test_schema.sql",
|
|
|
|
# Vendored JSON schemas from SchemaStore.
|
|
"crates/json_schema_store/src/schemas/",
|
|
|
|
# Not our typos.
|
|
"crates/livekit_api/",
|
|
# Vim makes heavy use of partial typing tables.
|
|
"crates/vim/",
|
|
# Editor, file finder, and fuzzy matching rely on partial typing and custom in-string syntax.
|
|
"crates/file_finder/src/file_finder_tests.rs",
|
|
"crates/fuzzy_nucleo/src/strings.rs",
|
|
"crates/editor/src/editor_tests.rs",
|
|
"crates/editor/src/edit_prediction_tests.rs",
|
|
# There are some names in the test data that are incorrectly flagged as typos.
|
|
"crates/git/test_data/blame_incremental_complex",
|
|
"crates/git/test_data/golden/blame_incremental_complex.json",
|
|
# We have some base64-encoded data that is incorrectly being flagged.
|
|
"crates/rpc/src/auth.rs",
|
|
# glsl isn't recognized by this tool.
|
|
"extensions/glsl/languages/glsl/",
|
|
# Protols is the name of the language server.
|
|
"extensions/proto/extension.toml",
|
|
"extensions/proto/src/language_servers/protols.rs",
|
|
# Windows likes its abbreviations.
|
|
"crates/gpui_windows/src/directx_renderer.rs",
|
|
"crates/gpui_windows/src/events.rs",
|
|
"crates/gpui_windows/src/direct_write.rs",
|
|
"crates/gpui_windows/src/window.rs",
|
|
# Some typos in the base mdBook CSS.
|
|
"docs/theme/css/",
|
|
# Automatically generated JS.
|
|
"docs/theme/c15t@*.js",
|
|
# Spellcheck triggers on `|Fixe[sd]|` regex part.
|
|
"script/danger/dangerfile.ts",
|
|
# File type extensions are not typos
|
|
"crates/zed/resources/windows/zed.iss",
|
|
# typos-cli doesn't understand our `vˇariable` markup
|
|
"crates/editor/src/hover_links.rs",
|
|
# typos-cli doesn't understand `setis` is intentional test case
|
|
"crates/editor/src/code_completion_tests.rs",
|
|
# Linux repository structure is not a valid text, hence we should not check it for typos
|
|
"crates/project_panel/benches/linux_repo_snapshot.txt",
|
|
# Some multibuffer test cases have word fragments that register as typos
|
|
"crates/multi_buffer/src/multi_buffer_tests.rs",
|
|
# Macos apis
|
|
"crates/gpui_macos/src/dispatcher.rs",
|
|
# Tests contain partially incomplete words (by design)
|
|
"crates/edit_prediction_cli/src/split_commit.rs",
|
|
"crates/edit_prediction_metrics/src/kept_rate.rs",
|
|
# Eval examples contain intentionally partial words (e.g. "secur" for "secure")
|
|
"crates/edit_prediction_cli/evals/",
|
|
# Tests contain `baˇr` that cause `"ba" should be "by" or "be".`-like false-positives
|
|
"crates/editor/src/document_symbols.rs",
|
|
]
|
|
|
|
[default]
|
|
extend-ignore-re = [
|
|
# PNG is a file format, not a typo
|
|
"PNG",
|
|
'cl\[ist]',
|
|
'\[lan\]guage',
|
|
'"ba"',
|
|
"doas",
|
|
# ProtoLS crate with tree-sitter Protobuf grammar.
|
|
"protols",
|
|
# x11rb SelectionNotifyEvent struct field
|
|
"requestor",
|
|
# macOS version
|
|
"Big Sur",
|
|
# Not an actual typo but an intentionally invalid color, in `color_extractor`
|
|
"#fof",
|
|
# Stripped version of reserved keyword `type`
|
|
"typ",
|
|
# AMD GPU Services
|
|
"ags",
|
|
# AMD GPU Services
|
|
"AGS",
|
|
# "noet" is a vim variable (ideally to ignore locally)
|
|
"noet",
|
|
# Yarn Plug'n'Play
|
|
"PnP",
|
|
# `image` crate method: Delay::from_numer_denom_ms
|
|
"numer",
|
|
# Abbreviation for foreignObject in mermaid SVG processing
|
|
"fo",
|
|
# Mermaid CSS class name for state diagram composites
|
|
"composit",
|
|
# Used in truncating tests to ensure byte-length vs char like in café
|
|
"caf…",
|
|
'\[elete\]',
|
|
"GHIzJ",
|
|
]
|
|
check-filename = true
|
|
|
|
[default.extend-words]
|
|
scap = "scap"
|
|
writeable = "writeable"
|