Fix state sync

This commit is contained in:
Quinten Kock 2025-12-01 12:52:42 +01:00
parent 9f3befdb61
commit aecff9f546
4 changed files with 38 additions and 51 deletions

32
package-lock.json generated
View File

@ -1,15 +1,15 @@
{
"name": "miller",
"version": "0.1.0",
"version": "0.2.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "miller",
"version": "0.1.0",
"version": "0.2.1",
"license": "GPL-3.0-or-later",
"dependencies": {
"chokidar": "^4.0.3",
"chokidar": "^5.0.0",
"electron-squirrel-startup": "^1.0.1",
"node-pty": "^1.1.0-beta39"
},
@ -37,7 +37,7 @@
"@xterm/addon-fit": "^0.10.0",
"@xterm/xterm": "^5.5.0",
"codemirror": "^6.0.2",
"electron": "39.1.1",
"electron": "39.2.4",
"eslint": "^9.39.1",
"eslint-plugin-import": "^2.32.0",
"globals": "^16.5.0",
@ -4723,15 +4723,15 @@
"license": "MIT"
},
"node_modules/chokidar": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
"integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz",
"integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==",
"license": "MIT",
"dependencies": {
"readdirp": "^4.0.1"
"readdirp": "^5.0.0"
},
"engines": {
"node": ">= 14.16.0"
"node": ">= 20.19.0"
},
"funding": {
"url": "https://paulmillr.com/funding/"
@ -5253,9 +5253,9 @@
"license": "MIT"
},
"node_modules/electron": {
"version": "39.1.1",
"resolved": "https://registry.npmjs.org/electron/-/electron-39.1.1.tgz",
"integrity": "sha512-VuFEI1yQ7BH3RYI5VZtwFlzGp4rpPRd5oEc26ZQIItVLcLTbXt4/O7o4hs+1fyg9Q3NvGAifgX5Vp5EBOIFpAg==",
"version": "39.2.4",
"resolved": "https://registry.npmjs.org/electron/-/electron-39.2.4.tgz",
"integrity": "sha512-KxPtwpFceQKSxRtUY39piHLYhJMMyHfOhc70e6zRnKGrbRdK6hzEqssth8IGjlKOdkeT4KCvIEngnNraYk39+g==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
@ -9921,12 +9921,12 @@
}
},
"node_modules/readdirp": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
"integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz",
"integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==",
"license": "MIT",
"engines": {
"node": ">= 14.18.0"
"node": ">= 20.19.0"
},
"funding": {
"type": "individual",

View File

@ -1,7 +1,7 @@
{
"name": "miller",
"productName": "miller",
"version": "0.1.0",
"version": "0.2.1",
"description": "Column-based code editor",
"main": ".vite/build/main.js",
"scripts": {
@ -42,7 +42,7 @@
"@xterm/addon-fit": "^0.10.0",
"@xterm/xterm": "^5.5.0",
"codemirror": "^6.0.2",
"electron": "39.1.1",
"electron": "39.2.4",
"eslint": "^9.39.1",
"eslint-plugin-import": "^2.32.0",
"globals": "^16.5.0",
@ -55,7 +55,7 @@
"vite": "^7.2.2"
},
"dependencies": {
"chokidar": "^4.0.3",
"chokidar": "^5.0.0",
"electron-squirrel-startup": "^1.0.1",
"node-pty": "^1.1.0-beta39"
}

View File

@ -5,6 +5,7 @@ import {
StateEffect,
Text,
Transaction,
ChangeSet,
} from "@codemirror/state";
import { history } from "@codemirror/commands";
import { Editor } from "./editor";
@ -159,10 +160,11 @@ export class OpenFile implements WorkspaceFile {
const transaction = this.rootState.val.update(trs);
this.rootState.val = transaction.state;
// If the transaction introduced document changes, increment version
if (transaction.changes && !transaction.changes.empty) {
this.version = (this.version || 0) + 1;
// TODO: call LSP didChange notification helper here
if (this.changes === undefined) {
this.changes = ChangeSet.empty(this.rootState.val.doc.length);
}
this.changes = this.changes.compose(transaction.changes);
}
if (origin) {
@ -200,9 +202,8 @@ export class OpenFile implements WorkspaceFile {
get languageId(): string {
return inferLanguageFromPath(this.filePath.val || "") || "";
}
get doc(): Text {
return this.rootState.val.doc;
}
doc: Text;
changes: ChangeSet;
// Return an EditorView to be used by the LSP Workspace for position mapping.
// If `main` is provided and belongs to this open file, return it. Otherwise
// return the first available editor view, or null if none exist.

View File

@ -8,8 +8,6 @@ import {
LSPClient,
languageServerExtensions,
Workspace,
WorkspaceFile,
LSPPlugin,
} from "@codemirror/lsp-client";
import { OpenFile } from "./filestate";
@ -100,30 +98,16 @@ class OpenFileWorkspace extends Workspace {
// based on the editor views or the OpenFile state when no view exists.
// TODO: fix (cause vibe coding is useless)
syncFiles() {
let result: any[] = [];
for (let file of this.files) {
const view = file.getView?.();
if (view) {
const plugin = LSPPlugin.get(view);
if (!plugin) continue;
const changes = plugin.unsyncedChanges;
if (!changes.empty) {
result.push({ file, prevDoc: file.doc, changes });
file.doc = view.state.doc;
file.version = this.nextFileVersion(file.uri);
plugin.clear();
}
} else {
// No view; try to find a corresponding OpenFile and update
const path = file.uri.replace(/^file:\/\//, "");
const of = OpenFile.findOpenFile(path);
if (of && of.doc.toString() !== file.doc.toString()) {
const prev = file.doc;
const changes = ChangeSet.empty(prev.length);
result.push({ file, prevDoc: prev, changes });
file.doc = of.doc;
file.version = this.nextFileVersion(file.uri);
}
const result = [];
for (const file of this.files) {
const prevDoc = file.doc;
// TODO: get changes from rootState (tracked in OpenFile) rather than the view's LSPPlugin.
const changes = file.changes;
if (changes && !changes.empty) {
result.push({ file, prevDoc, changes });
file.doc = file.rootState.val.doc;
file.version = this.nextFileVersion(file.uri);
file.changes = ChangeSet.empty(file.doc.length);
}
}
return result;
@ -139,6 +123,7 @@ class OpenFileWorkspace extends Workspace {
console.warn("LSP: attempted to open unknown file", uri);
return;
}
of.doc = view.state.doc;
this.files.push(of);
this.client.didOpen(of);
}
@ -149,6 +134,7 @@ class OpenFileWorkspace extends Workspace {
console.warn("LSP: attempted to update unknown file", uri);
return;
}
// TODO: maybe couple undos across editors for things like LSP rename?
file.dispatch(update);
}