import { OffsetRange } from '../ranges/offsetRange';
import { StringText } from '../text/abstractText';
import { BaseEdit, BaseReplacement } from './edit';
export declare abstract class BaseStringEdit<T extends BaseStringReplacement<T> = BaseStringReplacement<any>, TEdit extends BaseStringEdit<T, TEdit> = BaseStringEdit<any, any>> extends BaseEdit<T, TEdit> {
    get TReplacement(): T;
    static composeOrUndefined<T extends BaseStringEdit>(edits: readonly T[]): T | undefined;
    /**
     * r := trySwap(e1, e2);
     * e1.compose(e2) === r.e1.compose(r.e2)
    */
    static trySwap(e1: BaseStringEdit, e2: BaseStringEdit): {
        e1: StringEdit;
        e2: StringEdit;
    } | undefined;
    apply(base: string): string;
    /**
     * Creates an edit that reverts this edit.
     */
    inverseOnSlice(getOriginalSlice: (start: number, endEx: number) => string): StringEdit;
    /**
     * Creates an edit that reverts this edit.
     */
    inverse(original: string): StringEdit;
    rebaseSkipConflicting(base: StringEdit): StringEdit;
    tryRebase(base: StringEdit): StringEdit | undefined;
    private _tryRebase;
    toJson(): ISerializedStringEdit;
    isNeutralOn(text: string): boolean;
    removeCommonSuffixPrefix(originalText: string): StringEdit;
    normalizeEOL(eol: '\r\n' | '\n'): StringEdit;
    /**
     * If `e1.apply(source) === e2.apply(source)`, then `e1.normalizeOnSource(source).equals(e2.normalizeOnSource(source))`.
    */
    normalizeOnSource(source: string): StringEdit;
    removeCommonSuffixAndPrefix(source: string): TEdit;
    applyOnText(docContents: StringText): StringText;
    mapData<TData extends IEditData<TData>>(f: (replacement: T) => TData): AnnotatedStringEdit<TData>;
}
export declare abstract class BaseStringReplacement<T extends BaseStringReplacement<T> = BaseStringReplacement<any>> extends BaseReplacement<T> {
    readonly newText: string;
    constructor(range: OffsetRange, newText: string);
    getNewLength(): number;
    toString(): string;
    replace(str: string): string;
    /**
     * Checks if the edit would produce no changes when applied to the given text.
     */
    isNeutralOn(text: string): boolean;
    removeCommonSuffixPrefix(originalText: string): StringReplacement;
    normalizeEOL(eol: '\r\n' | '\n'): StringReplacement;
    removeCommonSuffixAndPrefix(source: string): T;
    removeCommonPrefix(source: string): T;
    removeCommonSuffix(source: string): T;
    toEdit(): StringEdit;
    toJson(): ISerializedStringReplacement;
}
/**
 * Represents a set of replacements to a string.
 * All these replacements are applied at once.
*/
export declare class StringEdit extends BaseStringEdit<StringReplacement, StringEdit> {
    /**
     * Parses an edit from its string representation.
     * E.g. [[2, 12) -> "fgh", [14, 20) -> "qrst", [22, 22) -> "de\n"]
    */
    static parse(toStringValue: string): StringEdit;
    static readonly empty: StringEdit;
    static create(replacements: readonly StringReplacement[]): StringEdit;
    static single(replacement: StringReplacement): StringEdit;
    static replace(range: OffsetRange, replacement: string): StringEdit;
    static insert(offset: number, replacement: string): StringEdit;
    static delete(range: OffsetRange): StringEdit;
    static fromJson(data: ISerializedStringEdit): StringEdit;
    static compose(edits: readonly StringEdit[]): StringEdit;
    /**
     * The replacements are applied in order!
     * Equals `StringEdit.compose(replacements.map(r => r.toEdit()))`, but is much more performant.
    */
    static composeSequentialReplacements(replacements: readonly StringReplacement[]): StringEdit;
    constructor(replacements: readonly StringReplacement[]);
    protected _createNew(replacements: readonly StringReplacement[]): StringEdit;
}
/**
 * Warning: Be careful when changing this type, as it is used for serialization!
*/
export type ISerializedStringEdit = ISerializedStringReplacement[];
/**
 * Warning: Be careful when changing this type, as it is used for serialization!
*/
export interface ISerializedStringReplacement {
    txt: string;
    pos: number;
    len: number;
}
export declare class StringReplacement extends BaseStringReplacement<StringReplacement> {
    static insert(offset: number, text: string): StringReplacement;
    static replace(range: OffsetRange, text: string): StringReplacement;
    static delete(range: OffsetRange): StringReplacement;
    static fromJson(data: ISerializedStringReplacement): StringReplacement;
    equals(other: StringReplacement): boolean;
    tryJoinTouching(other: StringReplacement): StringReplacement | undefined;
    slice(range: OffsetRange, rangeInReplacement?: OffsetRange): StringReplacement;
}
export declare function applyEditsToRanges(sortedRanges: OffsetRange[], edit: StringEdit): OffsetRange[];
/**
 * Represents data associated to a single edit, which survives certain edit operations.
*/
export interface IEditData<T> {
    join(other: T): T | undefined;
}
export declare class VoidEditData implements IEditData<VoidEditData> {
    join(other: VoidEditData): VoidEditData | undefined;
}
/**
 * Represents a set of replacements to a string.
 * All these replacements are applied at once.
*/
export declare class AnnotatedStringEdit<T extends IEditData<T>> extends BaseStringEdit<AnnotatedStringReplacement<T>, AnnotatedStringEdit<T>> {
    static readonly empty: AnnotatedStringEdit<never>;
    static create<T extends IEditData<T>>(replacements: readonly AnnotatedStringReplacement<T>[]): AnnotatedStringEdit<T>;
    static single<T extends IEditData<T>>(replacement: AnnotatedStringReplacement<T>): AnnotatedStringEdit<T>;
    static replace<T extends IEditData<T>>(range: OffsetRange, replacement: string, data: T): AnnotatedStringEdit<T>;
    static insert<T extends IEditData<T>>(offset: number, replacement: string, data: T): AnnotatedStringEdit<T>;
    static delete<T extends IEditData<T>>(range: OffsetRange, data: T): AnnotatedStringEdit<T>;
    static compose<T extends IEditData<T>>(edits: readonly AnnotatedStringEdit<T>[]): AnnotatedStringEdit<T>;
    constructor(replacements: readonly AnnotatedStringReplacement<T>[]);
    protected _createNew(replacements: readonly AnnotatedStringReplacement<T>[]): AnnotatedStringEdit<T>;
    toStringEdit(filter?: (replacement: AnnotatedStringReplacement<T>) => boolean): StringEdit;
}
export declare class AnnotatedStringReplacement<T extends IEditData<T>> extends BaseStringReplacement<AnnotatedStringReplacement<T>> {
    readonly data: T;
    static insert<T extends IEditData<T>>(offset: number, text: string, data: T): AnnotatedStringReplacement<T>;
    static replace<T extends IEditData<T>>(range: OffsetRange, text: string, data: T): AnnotatedStringReplacement<T>;
    static delete<T extends IEditData<T>>(range: OffsetRange, data: T): AnnotatedStringReplacement<T>;
    constructor(range: OffsetRange, newText: string, data: T);
    equals(other: AnnotatedStringReplacement<T>): boolean;
    tryJoinTouching(other: AnnotatedStringReplacement<T>): AnnotatedStringReplacement<T> | undefined;
    slice(range: OffsetRange, rangeInReplacement?: OffsetRange): AnnotatedStringReplacement<T>;
}
//# sourceMappingURL=stringEdit.d.ts.map