installBindingsForAlacritty function

Future<String> installBindingsForAlacritty()

Install Shift+Enter keybinding for Alacritty.

Appends the TOML keybinding configuration to alacritty.toml.

Implementation

Future<String> installBindingsForAlacritty() async {
  const keybinding = '''
[[keyboard.bindings]]
key = "Return"
mods = "Shift"
chars = "\\u001B\\r"''';

  final home = Platform.environment['HOME'] ?? '';
  final configPaths = <String>[];

  // XDG config path.
  final xdgConfigHome = Platform.environment['XDG_CONFIG_HOME'];
  if (xdgConfigHome != null) {
    configPaths.add(p.join(xdgConfigHome, 'alacritty', 'alacritty.toml'));
  } else {
    configPaths.add(p.join(home, '.config', 'alacritty', 'alacritty.toml'));
  }

  // Windows-specific path.
  if (Platform.isWindows) {
    final appData = Platform.environment['APPDATA'];
    if (appData != null) {
      configPaths.add(p.join(appData, 'alacritty', 'alacritty.toml'));
    }
  }

  // Find existing config file.
  String? configPath;
  String configContent = '';
  bool configExists = false;

  for (final path in configPaths) {
    try {
      configContent = await File(path).readAsString();
      configPath = path;
      configExists = true;
      break;
    } catch (e) {
      if (e is! FileSystemException) rethrow;
    }
  }

  configPath ??= configPaths.isNotEmpty ? configPaths.first : null;
  if (configPath == null) {
    throw Exception('No valid config path found for Alacritty');
  }

  try {
    if (configExists) {
      // Check if keybinding already exists.
      if (configContent.contains('mods = "Shift"') &&
          configContent.contains('key = "Return"')) {
        return 'Found existing Alacritty Shift+Enter key binding. '
            'Remove it to continue.\n'
            'See $configPath\n';
      }

      // Create backup.
      final randomSha = _randomHex(4);
      final backupPath = '$configPath.$randomSha.bak';
      try {
        await File(configPath).copy(backupPath);
      } catch (_) {
        return 'Error backing up existing Alacritty config. Bailing out.\n'
            'See $configPath\n'
            'Backup path: $backupPath\n';
      }
    } else {
      // Ensure config directory exists.
      await Directory(p.dirname(configPath)).create(recursive: true);
    }

    // Add the keybinding to the config.
    var updatedContent = configContent;
    if (configContent.isNotEmpty && !configContent.endsWith('\n')) {
      updatedContent += '\n';
    }
    updatedContent += '\n$keybinding\n';

    await File(configPath).writeAsString(updatedContent);
    return 'Installed Alacritty Shift+Enter key binding\n'
        'You may need to restart Alacritty for changes to take effect\n'
        'See $configPath\n';
  } catch (e) {
    throw Exception('Failed to install Alacritty Shift+Enter key binding: $e');
  }
}