Skip to content

feat(api): a plain text file edits and saves with the names of Document - #902

Open
andiwand wants to merge 3 commits into
mainfrom
fix/save-text
Open

andiwand wants to merge 3 commits into
mainfrom
fix/save-text

Conversation

@andiwand

@andiwand andiwand commented Sep 13, 2026

Copy link
Copy Markdown
Member

Problem

In the npm package, a .txt file cannot be saved. Document.isEditable, isSavable, edit and save all send the call to the document of the session. A text file has no document, so each call throws NoDocumentFile. But capabilities().save is true for a txt, and wasm/README.md says that txt can be saved.

In Python, Java and Objective-C/Swift, a txt can be saved, but only with TextFile.write_edited / writeEdited. A document uses edit and save, so a host has to tell a txt from a document before a save.

A check of all bindings also found a bug in core. TextFile::is_savable checked only the encoding, but the docs of the bindings say that it is false for a file type that the library does not write. JsonFile is an abstract::TextFile too. Thus a json file reported that it was savable, its view wrote data-odr-editable="true", and write_edited wrote it. The file type table declares json without edit or save.

Change

  • core: TextFile gets the names of Document:
    • edit(operations) keeps the edit in the file of the text engine. Every handle over the file and the next render see it.
    • save(path), save(ostream) and save_to_memory() write the text as UTF-8.
    • write_edited stays, and its doc marks it deprecated. No caller breaks.
  • core: TextFile::is_savable is false where the file type is not text_file.
  • Python, Java, Objective-C/Swift: bind edit, save and save_to_memory / saveToMemory. write_edited / writeEdited stays, marked deprecated. Java uses @Deprecated.
  • wasm: for a text file, isEditable, isSavable, edit and save use the TextFile, so a host uses the same doc.edit(...) and doc.save() as for a document. save(password) throws UnsupportedOperation.
  • Docs: decision 3 of docs/design/txt-editing.md now describes the Document names. editing.md, the wasm AGENTS.md and README.md, and the changelog are updated too.

Tests

  • gtest: TextFile.an_edit_stays_in_the_file_until_it_is_saved and TextFile.json_is_not_savable. The test for an encoding that cannot be decoded also covers edit and save.
  • wasm: a round trip for txt, a refusal for json, and a NoDocumentFile refusal for a pdf.
  • Python, JUnit and XCTest: a test for edit + save + save_to_memory. The old write_edited tests stay, to show that the aliases still work.

Verification

All suites ran locally on macOS:

Suite Result
odr_test --gtest_filter='TextFile.*:*apabilit*' 21 of 21 pass
pytest python/tests/test_file.py 28 of 28 pass
JNI JUnit (ctest --test-dir .../jni) 63 of 63 pass
wasm node suite 52 of 52 pass
swift test on the macOS xcframework 44 of 44 pass

The changed C++ files also compile with -Werror -Wall -Wextra. The test data has no json inputs, so no reference output changes.

🤖 Generated with Claude Code

https://claude.ai/code/session_018ZehrLdwNTE8sBLxNZZYpW

andiwand and others added 2 commits September 13, 2026 21:23
The wasm Document sent isEditable, isSavable, edit and save to the
document of the session. A txt has no document, so each call threw
NoDocumentFile, and a .txt could not be saved from the browser. Python,
Java and Objective-C were not affected, because they bind
TextFile::write_edited.

For a text file, the four calls now use the TextFile. The edit puts the
edited bytes in place of the session's file, so the next render shows
them. The save writes the file as UTF-8.

TextFile::is_savable now also requires FileType::text_file. JsonFile is a
TextFile too, so a json view was editable and write_edited wrote it,
but the table declares json unsaved.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018ZehrLdwNTE8sBLxNZZYpW
A host saved a document with edit and save, but a plain text file with
write_edited. So each binding had to tell a txt from a document before
a save.

TextFile now has edit, save and save_to_memory. The edit keeps the text
in the file of the text engine, so every handle over the file and the
next render see it. The save writes the text as UTF-8. Python, Java,
Objective-C and Swift bind the new names, and the wasm binding uses
them instead of a reopen of the edited bytes.

write_edited stays in core and in every binding, and its doc marks it
deprecated, so no caller breaks.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018ZehrLdwNTE8sBLxNZZYpW
@andiwand andiwand changed the title fix(wasm): a plain text file saves through edit and save feat(api): a plain text file edits and saves with the names of Document Sep 13, 2026
Black joined the edit call in test_file.py, so the format job passes.
The changelog entries, the TextFile::edit doc and decision 3 of
txt-editing.md no longer tell what the code did before.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018ZehrLdwNTE8sBLxNZZYpW
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant