zoxideGenerator top-level property

FigGenerator zoxideGenerator
final

Implementation

final FigGenerator zoxideGenerator = FigGenerator(
  trigger: 'change',
  script: (List<String> tokens) {
    // TS: if tokens.length < 2 || tokens[1] === "" then no query args
    final queryArgs =
        tokens.where((t) => t != 'z' && !t.startsWith('-')).toList();
    final queryPart = queryArgs.isEmpty
        ? 'zoxide query --list --score'
        : 'zoxide query --list --score -- ${queryArgs.join(' ')}';
    return ['bash', '-c', '$queryPart && echo "___SEP___" && pwd && ls -d */'];
  },
  postProcess: (String out, [List<String>? tokens]) {
    final parts = out.split('___SEP___');
    final zoxideOut = parts[0];
    final cwdOut = parts.length > 1 ? parts[1] : '';

    String cwd = '';
    if (cwdOut.isNotEmpty) {
      final lines = cwdOut.trim().split('\n');
      if (lines.isNotEmpty) cwd = lines[0].trim();
    }

    // Build path -> suggestion for zoxide (path = fullPath always)
    final zoxideByPath = <String, FigSuggestion>{};
    for (final line in zoxideOut.split('\n')) {
      final trimmed = line.trim();
      if (trimmed.isEmpty) continue;
      final spaceIndex = trimmed.indexOf(' ');
      if (spaceIndex == -1) continue;

      final scoreStr = trimmed.substring(0, spaceIndex);
      final fullPath = trimmed.substring(spaceIndex + 1);
      final score = double.tryParse(scoreStr) ?? 0;

      final splitPath = fullPath.split('/');
      final parentPath = splitPath.sublist(0, splitPath.length - 1).join('/');
      final folderName = splitPath.last;
      final isInCwd = cwd.isNotEmpty && cwd == parentPath;
      final priority = isInCwd ? 9000 : score.toInt();

      zoxideByPath[fullPath] = FigSuggestion(
        name: isInCwd ? folderName : fullPath,
        description: 'Score: $score',
        icon: '💾',
        priority: priority,
      );
    }

    // CWD folders: path = cwd/name, priority 8999 (just below zoxide cwd matches)
    final merged = Map<String, FigSuggestion>.from(zoxideByPath);
    if (cwd.isNotEmpty) {
      final lines = cwdOut.trim().split('\n');
      for (var i = 1; i < lines.length; i++) {
        final line = lines[i].trim();
        if (line.isEmpty) continue;
        final name = line.replaceAll('/', '');
        final path = '$cwd/$name';
        if (!merged.containsKey(path)) {
          merged[path] = FigSuggestion(
            name: name,
            description: 'Score: 0',
            icon: '📁',
            priority: 8999,
          );
        }
      }
    }

    return merged.values.toList();
  },
);