2
0

AutocompleteFilepathContext.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. using System.IO.Abstractions;
  2. using System.Runtime.InteropServices;
  3. namespace Terminal.Gui.Views;
  4. internal class AutocompleteFilepathContext (string currentLine, int cursorPosition, FileDialogState state)
  5. : AutocompleteContext (Cell.ToCellList (currentLine), cursorPosition)
  6. {
  7. public FileDialogState State { get; set; } = state;
  8. }
  9. internal class FilepathSuggestionGenerator : ISuggestionGenerator
  10. {
  11. private FileDialogState state;
  12. public IEnumerable<Suggestion> GenerateSuggestions (AutocompleteContext context)
  13. {
  14. if (context is AutocompleteFilepathContext fileState)
  15. {
  16. state = fileState.State;
  17. }
  18. if (state is null)
  19. {
  20. return Enumerable.Empty<Suggestion> ();
  21. }
  22. var path = Cell.ToString (context.CurrentLine);
  23. int last = path.LastIndexOfAny (FileDialog.Separators);
  24. if (string.IsNullOrWhiteSpace (path) || !Path.IsPathRooted (path))
  25. {
  26. return Enumerable.Empty<Suggestion> ();
  27. }
  28. string term = path.Substring (last + 1);
  29. // If path is /tmp/ then don't just list everything in it
  30. if (string.IsNullOrWhiteSpace (term))
  31. {
  32. return Enumerable.Empty<Suggestion> ();
  33. }
  34. if (term.Equals (state?.Directory?.Name))
  35. {
  36. // Clear suggestions
  37. return Enumerable.Empty<Suggestion> ();
  38. }
  39. bool isWindows = RuntimeInformation.IsOSPlatform (OSPlatform.Windows);
  40. string [] suggestions = state.Children.Where (d => !d.IsParent)
  41. .Select (
  42. e => e.FileSystemInfo is IDirectoryInfo d
  43. ? d.Name + Path.DirectorySeparatorChar
  44. : e.FileSystemInfo.Name
  45. )
  46. .ToArray ();
  47. string [] validSuggestions = suggestions
  48. .Where (
  49. s => s.StartsWith (
  50. term,
  51. isWindows
  52. ? StringComparison.InvariantCultureIgnoreCase
  53. : StringComparison.InvariantCulture
  54. )
  55. )
  56. .OrderBy (m => m.Length)
  57. .ToArray ();
  58. // nothing to suggest
  59. if (validSuggestions.Length == 0 || validSuggestions [0].Length == term.Length)
  60. {
  61. return Enumerable.Empty<Suggestion> ();
  62. }
  63. return validSuggestions.Select (
  64. f => new Suggestion (term.Length, f, f)
  65. )
  66. .ToList ();
  67. }
  68. public bool IsWordChar (Rune rune)
  69. {
  70. if (rune.Value == '\n')
  71. {
  72. return false;
  73. }
  74. return true;
  75. }
  76. }