installBindingsForZed function

Future<String> installBindingsForZed()

Install Shift+Enter keybinding for Zed.

Modifies the keymap.json file in Zed's config directory.

Implementation

Future<String> installBindingsForZed() async {
  final home = Platform.environment['HOME'] ?? '';
  final zedDir = p.join(home, '.config', 'zed');
  final keymapPath = p.join(zedDir, 'keymap.json');

  try {
    await Directory(zedDir).create(recursive: true);

    String keymapContent = '[]';
    bool fileExists = false;

    try {
      keymapContent = await File(keymapPath).readAsString();
      fileExists = true;
    } catch (e) {
      if (e is! FileSystemException) rethrow;
    }

    if (fileExists) {
      // Check if keybinding already exists.
      if (keymapContent.contains('shift-enter')) {
        return 'Found existing Zed Shift+Enter key binding. '
            'Remove it to continue.\n'
            'See $keymapPath\n';
      }

      // Create backup.
      final randomSha = _randomHex(4);
      final backupPath = '$keymapPath.$randomSha.bak';
      try {
        await File(keymapPath).copy(backupPath);
      } catch (_) {
        return 'Error backing up existing Zed keymap. Bailing out.\n'
            'See $keymapPath\n'
            'Backup path: $backupPath\n';
      }
    }

    // Parse and modify the keymap.
    List<dynamic> keymap;
    try {
      keymap = jsonDecode(keymapContent) as List<dynamic>? ?? [];
    } catch (_) {
      keymap = [];
    }

    // Add the new keybinding for terminal context.
    keymap.add({
      'context': 'Terminal',
      'bindings': {
        'shift-enter': ['terminal::SendText', '\x1b\r'],
      },
    });

    // Write the updated keymap.
    final updatedContent =
        '${const JsonEncoder.withIndent('  ').convert(keymap)}\n';
    await File(keymapPath).writeAsString(updatedContent);

    return 'Installed Zed Shift+Enter key binding\n'
        'See $keymapPath\n';
  } catch (e) {
    throw Exception('Failed to install Zed Shift+Enter key binding: $e');
  }
}