zed/crates/vim/src
Ichimura Tomoo 81463223d5
Support opening and saving files with legacy encodings (#44819)
## Summary

Addresses #16965

This PR adds support for **opening and saving** files with legacy
encodings (non-UTF-8).
Previously, Zed failed to open files encoded in Shift-JIS, EUC-JP, Big5,
etc., displaying a "Could not open file" error screen. This PR
implements automatic encoding detection upon opening and ensures the
original encoding is preserved when saving.

## Implementation Details

1.  **Worktree (Loading)**:
* Updated `load_file` to use `chardetng` for automatic encoding
detection.
* Files are decoded to UTF-8 internal strings for editing, while
preserving the detected `Encoding` metadata.
2.  **Language / Buffer**:
* Added an `encoding` field to the `Buffer` struct to store the detected
encoding.
3.  **Worktree (Saving)**:
    * Updated `write_file` to accept the stored encoding.
    * **Performance Optimization**:
* **UTF-8 Path**: Uses the existing optimized `fs.save` (streaming
chunks directly from Rope), ensuring no performance regression for the
vast majority of files.
* **Legacy Encoding Path**: Implemented a fallback that converts the
Rope to a contiguous `String/Bytes` in memory, re-encodes it to the
target format (e.g., Shift-JIS), and writes it to disk.
* *Note*: This fallback involves memory allocation, but it is necessary
to support legacy encodings without refactoring the `fs` crate's
streaming interfaces.

## Changes

- `crates/worktree`:
    - Add dependencies: `encoding_rs`, `chardetng`.
    - Update `load_file` to detect encoding and decode content.
    - Update `write_file` to handle re-encoding on save.
- `crates/language`: Add `encoding` field and accessors to `Buffer`.
- `crates/project`: Pass encoding information between Worktree and
Buffer.
- `crates/vim`: Update `:w` command to use the new `write_file`
signature.

## Verification

I validated this manually using a Rust script to generate test files
with various encodings.

**Results:**

*  **Success (Opened & Saved correctly):**
    * **Japanese:** `Shift-JIS` (CP932), `EUC-JP`, `ISO-2022-JP`
    * **Chinese:** `Big5` (Traditional), `GBK/GB2312` (Simplified)
* **Western/Unicode:** `Windows-1252` (CP1252), `UTF-16LE`, `UTF-16BE`
* ⚠️ **limitations (Detection accuracy):**
* Some specific encodings like `KOI8-R` or generic `Latin1` (ISO-8859-1)
may partially display replacement characters (`?`) depending on the file
content length. This is a known limitation of the heuristic detection
library (`chardetng`) rather than the saving logic.


Release Notes:

- Added support for opening and saving files with legacy encodings
(Shift-JIS, Big5, etc.)

---------

Co-authored-by: CrazyboyQCD <53971641+CrazyboyQCD@users.noreply.github.com>
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
2025-12-17 19:46:17 +00:00
..
digraph
helix multi_buffer: Typed MultiBufferOffset (#42707) 2025-11-19 22:00:58 +00:00
normal vim: Fix global mark overwriting inconsistency (#44765) 2025-12-15 10:13:18 -07:00
test vim: Add scroll keybindings for the OutlinePanel (#42438) 2025-12-15 15:40:37 +00:00
change_list.rs editor: Remove buffer and display map fields from SelectionsCollection (#42175) 2025-11-07 11:21:14 +01:00
command.rs Support opening and saving files with legacy encodings (#44819) 2025-12-17 19:46:17 +00:00
digraph.rs vim: Downgrade user config error from panic to log (#42070) 2025-11-06 08:37:04 +00:00
helix.rs editor: Don't merge adjacent selections (#44811) 2025-12-15 17:32:54 +01:00
indent.rs vim: Make indenting selected lines with > and < in Helix mode no longer deselect them (#37665) 2025-09-09 13:18:22 -06:00
insert.rs vim: Fix cursor movement after entering Helix normal mode (#40528) 2025-10-23 11:15:12 +00:00
mode_indicator.rs Theme-able Vim Mode wrapper (#39813) 2025-10-21 04:30:30 +00:00
motion.rs Bump Rust version to 1.92 (#44649) 2025-12-17 01:42:04 +01:00
normal.rs vim: Fix paste action for visual modes (#43031) 2025-11-20 11:12:57 -07:00
object.rs vim: Attempt to fix flaky vim tests on windows (#45089) 2025-12-17 10:31:36 +00:00
replace.rs editor: Add active match highlight for buffer and project search (#44098) 2025-12-04 03:55:04 +05:30
rewrap.rs Remove unnecessary argument from Vim#update_editor (#36001) 2025-08-11 16:10:06 -06:00
state.rs vim: Fix global mark overwriting inconsistency (#44765) 2025-12-15 10:13:18 -07:00
surrounds.rs multi_buffer: Typed MultiBufferOffset (#42707) 2025-11-19 22:00:58 +00:00
test.rs commit view: Fix layout shift while loading commit (#44548) 2025-12-10 15:01:49 +00:00
vim.rs Revert "editor: Refactor cursor_offset_on_selection field in favor of VimModeSettings" (#44960) 2025-12-16 08:50:27 +00:00
visual.rs multi_buffer: Typed MultiBufferOffset (#42707) 2025-11-19 22:00:58 +00:00