zed/crates/language/src
Apoorva Verma d9ada8487b
Fix hard-tab block autoindent skipping unindented lines (#60406)
# Objective

Fixes #59979

With hard tabs on, expanding a multi-line snippet only re-indents the
lines that already start with a tab. Anything with no leading whitespace
(closing brackets, mostly) stays at column 0.

## Solution

Block autoindent shifts each line by the first line's delta, but only
when the line's indent kind matches the target kind. A line with no
indentation defaults to `IndentKind::Space`, so under hard tabs it never
matches and gets skipped. An empty indent doesn't really have a kind, so
I let it adopt the target kind before the check. Lines that actually
have space indentation in a tab buffer are still left alone. Normalizing
those felt like a bigger question than this bug, happy to look at it
separately if wanted.

## Testing

New `test_autoindent_block_mode_with_hard_tabs`, same shape as the
snippet in the issue. Fails on main (closing brace stays at column 0),
passes with the fix. `cargo test -p language` and `-p editor` are green,
clippy and fmt too.

## Self-Review Checklist:

- [x] 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 multi-line snippets leaving unindented lines at column 0 when
`hard_tabs` is enabled.
2026-07-07 07:45:54 +00:00
..
buffer multi_buffer: Optimize a bunch of things (#48519) 2026-02-05 20:10:02 +00:00
syntax_map Fix json! empty-string highlighting in Rust (#55126) 2026-05-31 18:42:00 +00:00
buffer.rs Fix hard-tab block autoindent skipping unindented lines (#60406) 2026-07-07 07:45:54 +00:00
buffer_tests.rs Fix hard-tab block autoindent skipping unindented lines (#60406) 2026-07-07 07:45:54 +00:00
diagnostic.rs Extract language_core and grammars crates from language (#52238) 2026-03-25 23:41:09 +00:00
diagnostic_set.rs Require multibuffer excerpts to be ordered and nonoverlapping (#52364) 2026-04-01 17:25:32 +00:00
file_content.rs Fix bad GitHub merge queue merge (#54721) 2026-04-23 23:47:30 +00:00
language.rs language: Support emitting multiple runnables from a single tree-sitter match (#57276) 2026-06-02 13:59:39 +00:00
language_registry.rs lsp: Register available LSP adapters locally when in remote development (#54915) 2026-06-01 06:32:55 +00:00
language_settings.rs Fix excluded language servers starting nonetheless (#60000) 2026-07-03 08:22:48 +00:00
manifest.rs Extract language_core and grammars crates from language (#52238) 2026-03-25 23:41:09 +00:00
modeline.rs Support ex: in vim modelines (#58121) 2026-06-01 18:54:29 +00:00
outline.rs Anchor sticky scroll to symbol name rows (#56333) 2026-06-15 11:03:26 +00:00
proto.rs Require multibuffer excerpts to be ordered and nonoverlapping (#52364) 2026-04-01 17:25:32 +00:00
runnable.rs language: Support emitting multiple runnables from a single tree-sitter match (#57276) 2026-06-02 13:59:39 +00:00
syntax_map.rs gpui_shared_string: Implement SharedString via smol_str (#54649) 2026-04-24 08:58:26 +00:00
task_context.rs language: Support emitting multiple runnables from a single tree-sitter match (#57276) 2026-06-02 13:59:39 +00:00
text_diff.rs Reduce amount of monomorphizations from FnMut closures (#49453) 2026-02-18 12:00:02 +01:00
toolchain.rs Extract language_core and grammars crates from language (#52238) 2026-03-25 23:41:09 +00:00