import { Emitter, Event } from '../common/event';
import { CommandRegistry, Command } from '../common/command';
import { Disposable } from '../common/disposable';
import { KeyCode, KeySequence, Key } from './keyboard/keys';
import { KeyboardLayoutService } from './keyboard/keyboard-layout-service';
import { ContributionProvider } from '../common/contribution-provider';
import { ILogger } from '../common/logger';
import { StatusBar } from './status-bar/status-bar';
import { ContextKeyService } from './context-key-service';
import { CorePreferences } from '../common/core-preferences';
import * as common from '../common/keybinding';
import { TernarySearchTree } from '../common/ternary-search-tree';
export declare enum KeybindingScope {
    DEFAULT = 0,
    USER = 1,
    WORKSPACE = 2,
    END = 3
}
export declare namespace KeybindingScope {
    const length: number;
}
/**
 * @deprecated import from `@theia/core/lib/common/keybinding` instead
 */
export type Keybinding = common.Keybinding;
export declare const Keybinding: typeof common.Keybinding;
export interface ResolvedKeybinding extends common.Keybinding {
    /**
     * The KeyboardLayoutService may transform the `keybinding` depending on the
     * user's keyboard layout. This property holds the transformed keybinding that
     * should be used in the UI. The value is undefined if the KeyboardLayoutService
     * has not been called yet to resolve the keybinding.
     */
    resolved?: KeyCode[];
}
export interface ScopedKeybinding extends common.Keybinding {
    /** Current keybinding scope */
    scope: KeybindingScope;
}
export declare const KeybindingContribution: unique symbol;
/**
 * Allows extensions to contribute {@link common.Keybinding}s
 */
export interface KeybindingContribution {
    /**
     * Registers keybindings.
     * @param keybindings the keybinding registry.
     */
    registerKeybindings(keybindings: KeybindingRegistry): void;
}
export declare const KeybindingContext: unique symbol;
export interface KeybindingContext {
    /**
     * The unique ID of the current context.
     */
    readonly id: string;
    isEnabled(arg: common.Keybinding): boolean;
}
export declare namespace KeybindingContexts {
    const NOOP_CONTEXT: KeybindingContext;
    const DEFAULT_CONTEXT: KeybindingContext;
}
export declare class KeybindingRegistry {
    static readonly PASSTHROUGH_PSEUDO_COMMAND = "passthrough";
    protected keySequence: KeySequence;
    protected readonly contexts: {
        [id: string]: KeybindingContext;
    };
    protected readonly keymaps: ScopedKeybinding[][];
    /**
     * Ternary search tree for efficient keybinding lookup.
     * Maps resolved key sequences to arrays of bindings sorted by scope (highest first).
     */
    protected keybindingTree: TernarySearchTree<KeySequence, ScopedKeybinding[]> | undefined;
    protected readonly corePreferences: CorePreferences;
    protected readonly keyboardLayoutService: KeyboardLayoutService;
    protected readonly contextProvider: ContributionProvider<KeybindingContext>;
    protected readonly commandRegistry: CommandRegistry;
    protected readonly contributions: ContributionProvider<KeybindingContribution>;
    protected readonly statusBar: StatusBar;
    protected readonly logger: ILogger;
    protected readonly whenContextService: ContextKeyService;
    onStart(): Promise<void>;
    protected keybindingsChanged: Emitter<void>;
    /**
     * Event that is fired when the resolved keybindings change due to a different keyboard layout
     * or when a new keymap is being set
     */
    get onKeybindingsChanged(): Event<void>;
    /**
     * Registers the keybinding context arguments into the application. Fails when an already registered
     * context is being registered.
     *
     * @param contexts the keybinding contexts to register into the application.
     */
    protected registerContext(...contexts: KeybindingContext[]): void;
    /**
     * Register a default keybinding to the registry.
     *
     * Keybindings registered later have higher priority during evaluation.
     *
     * @param binding the keybinding to be registered
     */
    registerKeybinding(binding: common.Keybinding): Disposable;
    /**
     * Register multiple default keybindings to the registry
     *
     * @param bindings An array of keybinding to be registered
     */
    registerKeybindings(...bindings: common.Keybinding[]): Disposable;
    /**
     * Unregister all keybindings from the registry that are bound to the key of the given keybinding
     *
     * @param binding a keybinding specifying the key to be unregistered
     */
    unregisterKeybinding(binding: common.Keybinding): void;
    /**
     * Unregister all keybindings with the given key from the registry
     *
     * @param key a key to be unregistered
     */
    unregisterKeybinding(key: string): void;
    /**
     * Unregister all existing keybindings for the given command
     * @param command the command to unregister all keybindings for
     */
    unregisterKeybinding(command: Command): void;
    protected doRegisterKeybindings(bindings: common.Keybinding[], scope?: KeybindingScope): Disposable;
    protected doRegisterKeybinding(binding: common.Keybinding, scope?: KeybindingScope): Disposable;
    /**
     * Ensures that keybindings are inserted in order of increasing length of binding to ensure that if a
     * user triggers a short keybinding (e.g. ctrl+k), the UI won't wait for a longer one (e.g. ctrl+k enter)
     */
    protected insertBindingIntoScope(item: common.Keybinding & {
        scope: KeybindingScope;
    }, scope: KeybindingScope): void;
    /**
     * Ensure that the `resolved` property of the given binding is set by calling the KeyboardLayoutService.
     */
    resolveKeybinding(binding: ResolvedKeybinding): KeyCode[];
    /**
     * Clear all `resolved` properties of registered keybindings so the KeyboardLayoutService is called
     * again to resolve them. This is necessary when the user's keyboard layout has changed.
     */
    protected clearResolvedKeybindings(): void;
    /**
     * Invalidates the keybinding tree, causing it to be rebuilt on next access.
     */
    protected invalidateKeybindingTree(): void;
    /**
     * Gets or builds the keybinding tree for efficient lookup.
     * The tree maps resolved key sequences to arrays of bindings sorted by scope (highest first).
     */
    protected getKeybindingTree(): TernarySearchTree<KeySequence, ScopedKeybinding[]>;
    /**
     * Builds a ternary search tree from all registered keybindings for efficient lookup.
     * Bindings are indexed by their resolved key sequence.
     * Bindings are stored in the order they should be checked: highest scope first,
     * and within the same scope, in the order they appear in keymaps (later-registered first).
     */
    protected buildKeybindingTree(): TernarySearchTree<KeySequence, ScopedKeybinding[]>;
    /**
     * Checks whether a colliding {@link common.Keybinding} exists in a specific scope.
     * @param binding the keybinding to check
     * @param scope the keybinding scope to check
     * @returns true if there is a colliding keybinding
     */
    containsKeybindingInScope(binding: common.Keybinding, scope?: KeybindingScope): boolean;
    /**
     * Get a user visible representation of a {@link common.Keybinding}.
     * @returns an array of strings representing all elements of the {@link KeySequence} defined by the {@link common.Keybinding}
     * @param keybinding the keybinding
     * @param separator the separator to be used to stringify {@link KeyCode}s that are part of the {@link KeySequence}
     */
    acceleratorFor(keybinding: common.Keybinding, separator?: string, asciiOnly?: boolean): string[];
    /**
     * Get a user visible representation of a {@link KeySequence}.
     * @returns an array of strings representing all elements of the {@link KeySequence}
     * @param keySequence the keysequence
     * @param separator the separator to be used to stringify {@link KeyCode}s that are part of the {@link KeySequence}
     */
    acceleratorForSequence(keySequence: KeySequence, separator?: string, asciiOnly?: boolean): string[];
    /**
     * Get a user visible representation of a key code (a key with modifiers).
     * @returns a string representing the {@link KeyCode}
     * @param keyCode the keycode
     * @param separator the separator used to separate keys (key and modifiers) in the returning string
     * @param asciiOnly if `true`, no special characters will be substituted into the string returned. Ensures correct keyboard shortcuts in Electron menus.
     */
    acceleratorForKeyCode(keyCode: KeyCode, separator?: string, asciiOnly?: boolean): string;
    componentsForKeyCode(keyCode: KeyCode, asciiOnly?: boolean): string[];
    /**
     * @param asciiOnly if `true`, no special characters will be substituted into the string returned. Ensures correct keyboard shortcuts in Electron menus.
     *
     * Return a user visible representation of a single key.
     */
    acceleratorForKey(key: Key, asciiOnly?: boolean): string;
    /**
     * Finds collisions for a key sequence inside a list of bindings (error-free)
     *
     * @param bindings the reference bindings
     * @param candidate the sequence to match
     */
    protected getKeySequenceCollisions(bindings: ScopedKeybinding[], candidate: KeySequence): KeybindingRegistry.KeybindingsResult;
    /**
     * Get all keybindings associated to a commandId.
     *
     * @param commandId The ID of the command for which we are looking for keybindings.
     * @returns an array of {@link ScopedKeybinding}
     */
    getKeybindingsForCommand(commandId: string): ScopedKeybinding[];
    protected isActive(binding: common.Keybinding): boolean;
    /**
     * Tries to execute a keybinding.
     *
     * @param binding to execute
     * @param event keyboard event.
     */
    protected executeKeyBinding(binding: common.Keybinding, event: KeyboardEvent): void;
    /**
     * Only execute if it has no context (global context) or if we're in that context.
     */
    protected isEnabled(binding: common.Keybinding, event: KeyboardEvent): boolean;
    isEnabledInScope(binding: common.Keybinding, target: HTMLElement | undefined): boolean;
    dispatchCommand(id: string, target?: EventTarget): void;
    dispatchKeyDown(input: KeyboardEventInit | KeyCode | string, target?: EventTarget): void;
    protected asKeyboardEventInit(input: KeyboardEventInit | KeyCode | string): KeyboardEventInit & Partial<{
        keyCode: number;
    }>;
    registerEventListeners(win: Window): Disposable;
    /**
     * Run the command matching to the given keyboard event.
     */
    run(event: KeyboardEvent): void;
    /**
     * Match first binding in the current context.
     * Keybindings ordered by a scope and by a registration order within the scope.
     *
     * Uses a ternary search tree for efficient O(log n) lookup instead of O(n) iteration.
     * The tree is lazily built and invalidated when keybindings change.
     *
     * When multiple bindings match, bindings that use context keys local to the focused
     * element are given priority over bindings that only use global context keys.
     */
    matchKeybinding(keySequence: KeySequence, event?: KeyboardEvent): KeybindingRegistry.Match;
    /**
     * Selects the most appropriate binding from a list of enabled bindings.
     * Prioritizes bindings whose `when` clause uses context keys that are locally
     * defined at the focused element, as these are more specific to the user's
     * current focus context.
     *
     * @param enabledBindings Array of enabled bindings to choose from (must not be empty)
     * @param event Optional keyboard event to get the focused element from
     * @returns The selected binding
     */
    protected selectBindingByLocalContext(enabledBindings: ScopedKeybinding[], event?: KeyboardEvent): ScopedKeybinding;
    /**
     * Returns true if the binding is usable
     * @param binding Binding to be checked
     */
    protected isUsable(binding: common.Keybinding): boolean;
    /**
     * Return a new filtered array containing only the usable bindings among the input bindings
     * @param bindings Bindings to filter
     */
    protected getUsableBindings<T extends common.Keybinding>(bindings: T[]): T[];
    /**
     * Return true of string a pseudo-command id, in other words a command id
     * that has a special meaning and that we won't find in the command
     * registry.
     *
     * @param commandId commandId to test
     */
    isPseudoCommand(commandId: string): boolean;
    /**
     * Sets a new keymap replacing all existing {@link common.Keybinding}s in the given scope.
     * @param scope the keybinding scope
     * @param bindings an array containing the new {@link common.Keybinding}s
     */
    setKeymap(scope: KeybindingScope, bindings: common.Keybinding[]): void;
    protected readonly toResetKeymap: Map<KeybindingScope, Disposable>;
    /**
     * Reset keybindings for a specific scope
     * @param scope scope to reset the keybindings for
     */
    resetKeybindingsForScope(scope: KeybindingScope): void;
    /**
     * Reset keybindings for all scopes(only leaves the default keybindings mapped)
     */
    resetKeybindings(): void;
    /**
     * Get all {@link common.Keybinding}s for a {@link KeybindingScope}.
     * @returns an array of {@link common.ScopedKeybinding}
     * @param scope the keybinding scope to retrieve the {@link common.Keybinding}s for.
     */
    getKeybindingsByScope(scope: KeybindingScope): ScopedKeybinding[];
}
export declare namespace KeybindingRegistry {
    type Match = {
        kind: 'full' | 'partial';
        binding: ScopedKeybinding;
    } | undefined;
    class KeybindingsResult {
        full: ScopedKeybinding[];
        partial: ScopedKeybinding[];
        shadow: ScopedKeybinding[];
        /**
         * Merge two results together inside `this`
         *
         * @param other the other KeybindingsResult to merge with
         * @return this
         */
        merge(other: KeybindingsResult): KeybindingsResult;
        /**
         * Returns a new filtered KeybindingsResult
         *
         * @param fn callback filter on the results
         * @return filtered new result
         */
        filter(fn: (binding: common.Keybinding) => boolean): KeybindingsResult;
    }
}
//# sourceMappingURL=keybinding.d.ts.map