getSuggestions method

  1. @override
Future<List<CompletionSuggestion>> getSuggestions(
  1. String query,
  2. SuggestionContext context
)
override

Implementation

@override
Future<List<CompletionSuggestion>> getSuggestions(
  String query,
  SuggestionContext context,
) async {
  String searchPath;
  String prefix;

  if (query.startsWith('@')) {
    prefix = query.substring(1);
    searchPath = context.currentDirectory ?? '.';
  } else {
    prefix = query;
    searchPath = context.currentDirectory ?? '.';
  }

  // Resolve path.
  final parts = prefix.split('/');
  final dirPart = parts.length > 1
      ? parts.sublist(0, parts.length - 1).join('/')
      : '';
  final filePart = parts.last.toLowerCase();

  String targetDir;
  if (prefix.startsWith('/')) {
    targetDir = dirPart.isEmpty ? '/' : dirPart;
  } else if (prefix.startsWith('~/')) {
    final home = Platform.environment['HOME'] ?? '.';
    targetDir = dirPart.isEmpty ? home : '$home/${dirPart.substring(2)}';
  } else {
    targetDir = dirPart.isEmpty ? searchPath : '$searchPath/$dirPart';
  }

  final suggestions = <CompletionSuggestion>[];

  try {
    final dir = Directory(targetDir);
    if (!await dir.exists()) return suggestions;

    await for (final entity in dir.list()) {
      final name =
          entity.uri.pathSegments.where((s) => s.isNotEmpty).lastOrNull ?? '';

      // Skip hidden files unless query starts with '.'
      if (name.startsWith('.') && !filePart.startsWith('.')) continue;

      // Fuzzy match.
      if (filePart.isNotEmpty && !_fuzzyMatch(name, filePart)) continue;

      final isDir = entity is Directory;
      final relativePath = dirPart.isEmpty ? name : '$dirPart/$name';
      final icon = isDir ? 'folder' : _fileIcon(name);

      suggestions.add(
        CompletionSuggestion(
          value: relativePath,
          displayText: name,
          description: isDir ? 'Directory' : _fileDescription(name),
          type: isDir ? SuggestionType.directory : SuggestionType.file,
          icon: icon,
          score: _fuzzyScore(name, filePart),
          insertText: isDir ? '$relativePath/' : relativePath,
        ),
      );
    }
  } catch (_) {
    // Permission denied or other IO error.
  }

  suggestions.sort((a, b) => b.score.compareTo(a.score));
  return suggestions.take(20).toList();
}