parseVimCommand function

VimCommand parseVimCommand(
  1. String input
)

Implementation

VimCommand parseVimCommand(String input) {
  final trimmed = input.trim();
  if (trimmed.isEmpty) return const NoOpCommand(raw: '');

  // :w [file]
  if (trimmed == 'w' || trimmed.startsWith('w ')) {
    final file = trimmed.length > 2 ? trimmed.substring(2).trim() : null;
    return WriteCommand(fileName: file);
  }

  // :q / :q!
  if (trimmed == 'q') return const QuitCommand();
  if (trimmed == 'q!') return const QuitCommand(force: true);

  // :wq / :x
  if (trimmed == 'wq' || trimmed == 'x') return const WriteQuitCommand();

  // :s/old/new/[g][c]
  final subMatch = RegExp(r'^s/([^/]*)/([^/]*)/?([gc]*)$').firstMatch(trimmed);
  if (subMatch != null) {
    final flags = subMatch.group(3) ?? '';
    return SubstituteCommand(
      pattern: subMatch.group(1)!,
      replacement: subMatch.group(2)!,
      global: flags.contains('g'),
      confirmEach: flags.contains('c'),
    );
  }

  // :set option[=value]
  if (trimmed.startsWith('set ')) {
    final rest = trimmed.substring(4).trim();
    final eqIdx = rest.indexOf('=');
    if (eqIdx >= 0) {
      return SetCommand(
        option: rest.substring(0, eqIdx).trim(),
        value: rest.substring(eqIdx + 1).trim(),
      );
    }
    return SetCommand(option: rest);
  }

  // :! shell command
  if (trimmed.startsWith('!')) {
    return ShellCommand(command: trimmed.substring(1).trim());
  }

  // :<number> goto line
  final lineNum = int.tryParse(trimmed);
  if (lineNum != null) {
    return GotoLineCommand(line: lineNum);
  }

  return NoOpCommand(raw: trimmed);
}