deploy: current vibn theia state
Some checks failed
Playwright Tests / Playwright Tests (ubuntu-22.04, Node.js 22.x) (push) Has been cancelled
3PP License Check / 3PP License Check (11, 22.x, ubuntu-22.04) (push) Has been cancelled
Publish packages to NPM / Perform Publishing (push) Has been cancelled

Made-with: Cursor
This commit is contained in:
2026-02-27 12:01:08 -08:00
commit 8bb5110148
3782 changed files with 640947 additions and 0 deletions

View File

@@ -0,0 +1,177 @@
// *****************************************************************************
// Copyright (C) 2018 TypeFox and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0.
//
// This Source Code may also be made available under the following Secondary
// Licenses when the conditions for such availability set forth in the Eclipse
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
// with the GNU Classpath Exception which is available at
// https://www.gnu.org/software/classpath/license.html.
//
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
// *****************************************************************************
import * as jsdiff from 'diff';
import { ContentLinesArrayLike } from './content-lines';
import { Position, Range, uinteger } from '@theia/core/shared/vscode-languageserver-protocol';
export class DiffComputer {
computeDiff(previous: ContentLinesArrayLike, current: ContentLinesArrayLike): DiffResult[] {
const diffResult = diffArrays(previous, current);
return diffResult;
}
computeDirtyDiff(previous: ContentLinesArrayLike, current: ContentLinesArrayLike): DirtyDiff {
const changes: Change[] = [];
const diffResult = this.computeDiff(previous, current);
let currentRevisionLine = -1;
let previousRevisionLine = -1;
for (let i = 0; i < diffResult.length; i++) {
const change = diffResult[i];
const next = diffResult[i + 1];
if (change.added) {
// case: addition
changes.push({ previousRange: LineRange.createEmptyLineRange(previousRevisionLine + 1), currentRange: toLineRange(change) });
currentRevisionLine += change.count!;
} else if (change.removed && next && next.added) {
const isFirstChange = i === 0;
const isLastChange = i === diffResult.length - 2;
const isNextEmptyLine = next.value.length > 0 && current[next.value[0]].length === 0;
const isPrevEmptyLine = change.value.length > 0 && previous[change.value[0]].length === 0;
if (isFirstChange && isNextEmptyLine) {
// special case: removing at the beginning
changes.push({ previousRange: toLineRange(change), currentRange: LineRange.createEmptyLineRange(0) });
previousRevisionLine += change.count!;
} else if (isFirstChange && isPrevEmptyLine) {
// special case: adding at the beginning
changes.push({ previousRange: LineRange.createEmptyLineRange(0), currentRange: toLineRange(next) });
currentRevisionLine += next.count!;
} else if (isLastChange && isNextEmptyLine) {
changes.push({ previousRange: toLineRange(change), currentRange: LineRange.createEmptyLineRange(currentRevisionLine + 2) });
previousRevisionLine += change.count!;
} else {
// default case is a modification
changes.push({ previousRange: toLineRange(change), currentRange: toLineRange(next) });
currentRevisionLine += next.count!;
previousRevisionLine += change.count!;
}
i++; // consume next eagerly
} else if (change.removed && !(next && next.added)) {
// case: removal
changes.push({ previousRange: toLineRange(change), currentRange: LineRange.createEmptyLineRange(currentRevisionLine + 1) });
previousRevisionLine += change.count!;
} else {
// case: unchanged region
currentRevisionLine += change.count!;
previousRevisionLine += change.count!;
}
}
return { changes };
}
}
class ArrayDiff extends jsdiff.Diff {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
override tokenize(value: any): any {
return value;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
override join(value: any): any {
return value;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
override removeEmpty(value: any): any {
return value;
}
}
const arrayDiff = new ArrayDiff();
/**
* Computes diff without copying data.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function diffArrays(oldArr: ContentLinesArrayLike, newArr: ContentLinesArrayLike): DiffResult[] {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return arrayDiff.diff(oldArr as any, newArr as any) as any;
}
function toLineRange({ value }: DiffResult): LineRange {
const [start, end] = value;
return LineRange.create(start, end + 1);
}
export interface DiffResult {
value: [number, number];
count?: number;
added?: boolean;
removed?: boolean;
}
export interface DirtyDiff {
readonly changes: readonly Change[];
}
export interface Change {
readonly previousRange: LineRange;
readonly currentRange: LineRange;
}
export namespace Change {
export function isAddition(change: Change): boolean {
return LineRange.isEmpty(change.previousRange);
}
export function isRemoval(change: Change): boolean {
return LineRange.isEmpty(change.currentRange);
}
export function isModification(change: Change): boolean {
return !isAddition(change) && !isRemoval(change);
}
}
export interface LineRange {
readonly start: number;
readonly end: number;
}
export namespace LineRange {
export function create(start: number, end: number): LineRange {
if (start < 0 || end < 0 || start > end) {
throw new Error(`Invalid line range: { start: ${start}, end: ${end} }`);
}
return { start, end };
}
export function createSingleLineRange(line: number): LineRange {
return create(line, line + 1);
}
export function createEmptyLineRange(line: number): LineRange {
return create(line, line);
}
export function isEmpty(range: LineRange): boolean {
return range.start === range.end;
}
export function getStartPosition(range: LineRange): Position {
if (isEmpty(range)) {
return getEndPosition(range);
}
return Position.create(range.start, 0);
}
export function getEndPosition(range: LineRange): Position {
if (range.end < 1) {
return Position.create(0, 0);
}
return Position.create(range.end - 1, uinteger.MAX_VALUE);
}
export function toRange(range: LineRange): Range {
return Range.create(getStartPosition(range), getEndPosition(range));
}
export function getLineCount(range: LineRange): number {
return range.end - range.start;
}
}