import { Disposable } from '../../../../util/vs/base/common/lifecycle';
import { IObservable } from '../../../../util/vs/base/common/observableInternal';
import { OffsetRange } from '../../../../util/vs/editor/common/core/ranges/offsetRange';
import { StringText } from '../../../../util/vs/editor/common/core/text/abstractText';
import { IConfigurationService } from '../../../configuration/common/configurationService';
import { IExperimentationService } from '../../../telemetry/common/nullExperimentationService';
import { DocumentId } from '../dataTypes/documentId';
import { RootedEdit } from '../dataTypes/edit';
import { DiffHistoryMergeStrategy } from '../dataTypes/xtabHistoryOptions';
import { ObservableWorkspace } from '../observableWorkspace';
export interface IXtabHistoryDocumentEntry {
    docId: DocumentId;
}
export interface IXtabHistoryEditEntry extends IXtabHistoryDocumentEntry {
    kind: 'edit';
    edit: RootedEdit;
}
export interface IXtabHistoryVisibleRangesEntry extends IXtabHistoryDocumentEntry {
    kind: 'visibleRanges';
    visibleRanges: readonly OffsetRange[];
    documentContent: StringText;
}
export type IXtabHistoryEntry = IXtabHistoryEditEntry | IXtabHistoryVisibleRangesEntry;
/**
 * Controls how consecutive edits to the same document are merged in history.
 */
export type XtabEditMergeStrategy = 
/** Merge when the first replacement of both line-edits starts on the same line. */
{
    readonly kind: DiffHistoryMergeStrategy.SameStartLine;
}
/** Merge when all replacements in both line-edits are within `lineGap` lines of each other. */
 | {
    readonly kind: DiffHistoryMergeStrategy.Proximity;
    readonly lineGap: number;
}
/**
 * Layer 1 (keystroke coalescing): merge if edits are within `lineGap` lines AND arrived within `splitAfterMs`.
 * Layer 2 (logical splitting): if either condition fails, start a new history entry.
 */
 | {
    readonly kind: DiffHistoryMergeStrategy.Hybrid;
    readonly lineGap: number;
    readonly splitAfterMs: number;
};
export declare namespace XtabEditMergeStrategy {
    const sameStartLine: XtabEditMergeStrategy;
    function proximity(lineGap: number): XtabEditMergeStrategy;
    function hybrid(lineGap: number, splitAfterMs: number): XtabEditMergeStrategy;
    /**
     * Constructs a {@link XtabEditMergeStrategy} from config values.
     */
    function fromConfig(strategyKind: DiffHistoryMergeStrategy, lineGap: number, splitAfterMs: number): XtabEditMergeStrategy;
}
export declare class NesXtabHistoryTracker extends Disposable {
    private readonly _configurationService;
    private readonly _expService;
    /** Max # of entries in history */
    private static MAX_HISTORY_SIZE;
    private readonly idToEntry;
    private readonly history;
    private readonly maxHistorySize;
    protected mergeStrategy: IObservable<XtabEditMergeStrategy>;
    constructor(workspace: ObservableWorkspace, maxHistorySize: number | undefined, _configurationService: IConfigurationService, _expService: IExperimentationService);
    getHistory(): IXtabHistoryEntry[];
    /**
     * If the document isn't already in history, add it to the history.
     * If the document is in history either with an edit or selection entry, do not include it again.
     */
    private handleVisibleRangesChange;
    private shouldMerge;
    private handleEdits;
    private pushToHistory;
    private compactHistory;
}
//# sourceMappingURL=nesXtabHistoryTracker.d.ts.map