Skip to main content

Overview

CommandShortcutEvent defines the implementation of shortcut events based on keyboard commands (modifier keys + regular keys). These events handle common editor operations like copy, paste, undo, redo, and navigation.

Constructor

CommandShortcutEvent({
  required String key,
  required String command,
  required CommandShortcutEventHandler handler,
  required String Function()? getDescription,
  String? windowsCommand,
  String? macOSCommand,
  String? linuxCommand,
})

Parameters

key
String
required
The unique key for the shortcut event. Usually uses the description as the key.Example: 'undo', 'copy the selected content'
command
String
required
The string representation for the keyboard keys. Supports multiple key combinations separated by commas.Modifier key mapping:
  • ctrl - Ctrl key
  • meta - Command (macOS) or Control (Windows)
  • alt - Alt key
  • shift - Shift key
  • cmd - Alias for meta
  • win - Alias for meta
Examples:
  • 'ctrl+c' - Single combination
  • 'ctrl+y,ctrl+shift+z' - Multiple combinations
handler
CommandShortcutEventHandler
required
The handler function to execute when the shortcut is triggered.Type signature:
typedef CommandShortcutEventHandler = KeyEventResult Function(
  EditorState editorState,
);
Returns KeyEventResult.handled if processed, or KeyEventResult.ignored if not.
getDescription
String Function()
Callback function that returns a localized description of the command. Used for displaying shortcuts in UI.Example: () => AppFlowyEditorL10n.current.cmdUndo
windowsCommand
String
Platform-specific command for Windows. Overrides command on Windows.Example: 'ctrl+y'
macOSCommand
String
Platform-specific command for macOS. Overrides command on macOS.Example: 'cmd+z'
linuxCommand
String
Platform-specific command for Linux. Overrides command on Linux.

Properties

key

final String key
The unique identifier for this shortcut event.

command

String command
The current command string. Automatically set based on the platform.

handler

final CommandShortcutEventHandler handler
The function that handles the shortcut event.

keybindings

List<Keybinding> get keybindings
List of parsed keybinding objects from the command string. Read-only.

description

String? get description
Localized description of the command. Returns null if getDescription is not provided.

Methods

updateCommand()

void updateCommand({
  String? command,
  String? windowsCommand,
  String? macOSCommand,
  String? linuxCommand,
})
Updates the command based on the current platform. The appropriate platform-specific command takes precedence. Parameters:
  • command - Default command for all platforms
  • windowsCommand - Windows-specific override
  • macOSCommand - macOS-specific override
  • linuxCommand - Linux-specific override

clearCommand()

void clearCommand()
Completely clears the command, ensuring it cannot be triggered until updated again using updateCommand().

canRespondToRawKeyEvent()

bool canRespondToRawKeyEvent(KeyEvent event)
Checks if this shortcut can respond to the given key event. Parameters:
  • event - The key event to check
Returns: true if this shortcut matches the event.

execute()

KeyEventResult execute(EditorState editorState)
Executes the shortcut event handler. Parameters:
  • editorState - The current editor state
Returns: KeyEventResult.handled or KeyEventResult.ignored.

copyWith()

CommandShortcutEvent copyWith({
  String? key,
  String Function()? getDescription,
  String? command,
  CommandShortcutEventHandler? handler,
})
Creates a copy of this event with updated properties.

Examples

Copy Command

final CommandShortcutEvent copyCommand = CommandShortcutEvent(
  key: 'copy the selected content',
  getDescription: () => AppFlowyEditorL10n.current.cmdCopySelection,
  command: 'ctrl+c',
  macOSCommand: 'cmd+c',
  handler: (editorState) {
    final selection = editorState.selection?.normalized;
    if (selection == null || selection.isCollapsed) {
      return KeyEventResult.ignored;
    }

    // Get plain text
    final text = editorState.getTextInSelection(selection).join('\n');

    // Get HTML
    final nodes = editorState.getSelectedNodes(selection: selection);
    final document = Document.blank()..insert([0], nodes);
    final html = documentToHTML(document);

    () async {
      await AppFlowyClipboard.setData(
        text: text.isEmpty ? null : text,
        html: html.isEmpty ? null : html,
      );
    }();

    return KeyEventResult.handled;
  },
);

Undo Command

final CommandShortcutEvent undoCommand = CommandShortcutEvent(
  key: 'undo',
  getDescription: () => AppFlowyEditorL10n.current.cmdUndo,
  command: 'ctrl+z',
  macOSCommand: 'cmd+z',
  handler: (editorState) {
    editorState.undoManager.undo();
    return KeyEventResult.handled;
  },
);

Redo Command

Multiple key combinations for the same action:
final CommandShortcutEvent redoCommand = CommandShortcutEvent(
  key: 'redo',
  getDescription: () => AppFlowyEditorL10n.current.cmdRedo,
  command: 'ctrl+y,ctrl+shift+z',  // Two ways to redo on Windows/Linux
  macOSCommand: 'cmd+shift+z',      // One way on macOS
  handler: (editorState) {
    editorState.undoManager.redo();
    return KeyEventResult.handled;
  },
);

Platform-Specific Commands

final CommandShortcutEvent selectAllCommand = CommandShortcutEvent(
  key: 'select all',
  command: 'ctrl+a',           // Windows/Linux default
  macOSCommand: 'cmd+a',        // macOS uses cmd instead of ctrl
  handler: (editorState) {
    final selection = Selection(
      start: Position(path: [0], offset: 0),
      end: editorState.document.last.selectionEndPosition,
    );
    editorState.updateSelectionWithReason(selection);
    return KeyEventResult.handled;
  },
);

Updating Commands Dynamically

final event = CommandShortcutEvent(
  key: 'custom',
  command: 'ctrl+k',
  handler: (editorState) {
    // Custom logic
    return KeyEventResult.handled;
  },
);

// Later, update the command
event.updateCommand(
  command: 'ctrl+shift+k',
  macOSCommand: 'cmd+shift+k',
);

// Or clear it temporarily
event.clearCommand();

Usage

To use command shortcut events in your editor:
import 'package:appflowy_editor/appflowy_editor.dart';

final editor = AppFlowyEditor(
  editorState: editorState,
  commandShortcutEvents: [
    copyCommand,
    undoCommand,
    redoCommand,
    selectAllCommand,
    // Add more command shortcuts...
  ],
);

Command String Format

The command string uses a specific format:
  • Modifiers: ctrl, meta, cmd, win, alt, shift
  • Separator: + or - between modifiers and keys
  • Multiple combinations: Use , to separate different key combinations
  • Case insensitive: Commands are parsed in lowercase
Examples:
  • 'ctrl+c' - Ctrl + C
  • 'cmd+shift+z' - Command + Shift + Z (macOS)
  • 'ctrl+y,ctrl+shift+z' - Either Ctrl+Y OR Ctrl+Shift+Z
  • 'meta+enter' - Meta + Enter (Command on macOS, Control on Windows)

Key Event Results

Handlers should return:
  • KeyEventResult.handled - Event was processed, prevent further handling
  • KeyEventResult.ignored - Event was not processed, allow other handlers

See Also

Build docs developers (and LLMs) love