Stop rewriting files that only ever had a BOM - #60
Merged
Conversation
UTF-8 BOM 은 본문이 아니라 파일의 표식이다. Monaco 도 그렇게 보고 따로 들고 있어서 getValue() 는 BOM 을 빼고 준다. 그런데 디스크에서 읽은 문자열에는 BOM 이 들어 있고, 그걸 그대로 기준선으로 삼았다. 두 값이 영원히 다르니 — · BOM 파일은 **열자마자 "저장 안 함"** 이 되고, · "모두 저장" 이 손도 안 댄 파일을 고쳐 쓰면서 BOM 을 떼어 버린다. 파일 전체가 바뀐 diff 가 되고, BOM 을 요구하는 도구에서는 빌드가 깨진다. 안쪽은 전부 BOM 없이 다룬다. 읽을 때 떼고, 있었다는 사실만 기억했다가, 디스크에 쓸 때만 도로 붙인다. 비교·오프셋 계산이 전부 BOM 없는 문자열로 도니 한 글자씩 밀리는 일도 없다. 이름을 바꿔도 표식은 그 파일을 따라간다. 쓰는 자리는 넷이다 — 페인 저장(Ctrl+S), 모두 저장, 확장의 document.save(), 제안 수락. 제안 수락은 기준 텍스트가 모델에서 올 때(BOM 없음)와 디스크에서 올 때 (BOM 있음)가 섞이므로, 한 번 떼고 그 파일이 원래 갖고 있었는지로만 다시 붙인다. 같이 확인한 것: 줄 끝(CRLF/LF)과 마지막 줄바꿈 없음은 원래 그대로 보존되고 있었다.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A UTF-8 BOM is not text — it is a mark on the file, and Monaco treats it that way, keeping it outside the model so
getValue()returns the content without it. The string read from disk does contain it, and that string was being used as the saved baseline. The two never match, so:The result is a whole-file diff, and a broken build anywhere the BOM is required.
Everything inside now works BOM-free: it is removed on read, the fact that it was there is remembered, and it is put back only when writing to disk. Comparisons and offset arithmetic all run on the same BOM-free string, so nothing shifts by one. Renaming a file carries the mark with it.
There are four places that write: pane save (
Ctrl+S), Save All, the extension API'sdocument.save(), and accepting a proposal. The proposal path is the awkward one — its base text comes from the model (no BOM) when the buffer is dirty and from disk (BOM) when it is not — so it strips once and re-attaches based only on whether that file ever had one.Verification
A round-trip over five files — open, type a character, delete it, save — comparing bytes before and after: 5 of 5, covering CRLF, LF, BOM, BOM+CRLF, and no trailing newline. Line endings and the missing final newline were already preserved; the BOM was not.
Separately, opening a BOM file and pressing Save All without editing it: the file is now byte-identical, where before it came back without its BOM.
And with the re-attach removed, both BOM cases fail again exactly as before.
954 tests,
npm run typecheckclean.