Files
Terminal.Gui/Terminal.Gui/Views/AutocompleteFilepathContext.cs
dodexahedron 34bef2c839 Fixes #3242 - Replaces simple null checks (#3248)
* Replace all 342 `== null` with `is null`

* Replace 354 `!= null` with `is { }`

* Wrap these in conditionals since they break tests against Release configuration

The members they depend on do not exist in Release configuration

* Split these up and dispose properly

This test needs to be revisited for several reasons at some point.

* Fix release configuration tests

* Declare interface these already support

* Annotate constructor properly and use throw helper

* Move class to its own file

* Rename these files so they nest in the solution explorer

* Make this a record type and remove now-redundant/illegal members

* Reference passing to avoid some struct copies

* Simplify this

* Carry reference passing through as appropriate

* Turn this into a record struct

* Remove unused internal constructor and its test

It was only used by that test.

* Simplify this constructor

* This should be a property

* Simplify constructor

* Simplify GetHashCode

* Mark this ignored just in case

* Missed a couple of opportunities for reference passing

* record struct already does this by value

* Remove unused class

* Simplify the type initializer and Reset method

* Implement INotifyCollectionChanged and IDictionary by delegating to ColorSchemes

* Fix for reflection-based configuration

* Make CI  build happy by disambiguiating this attribute
2024-02-16 16:46:25 -07:00

99 lines
3.3 KiB
C#

using System.IO.Abstractions;
using System.Runtime.InteropServices;
namespace Terminal.Gui;
internal class AutocompleteFilepathContext : AutocompleteContext
{
public AutocompleteFilepathContext (string currentLine, int cursorPosition, FileDialogState state)
: base (TextModel.ToRuneCellList (currentLine), cursorPosition)
{
State = state;
}
public FileDialogState State { get; set; }
}
internal class FilepathSuggestionGenerator : ISuggestionGenerator
{
private FileDialogState state;
public IEnumerable<Suggestion> GenerateSuggestions (AutocompleteContext context)
{
if (context is AutocompleteFilepathContext fileState)
{
state = fileState.State;
}
if (state is null)
{
return Enumerable.Empty<Suggestion> ();
}
var path = TextModel.ToString (context.CurrentLine);
int last = path.LastIndexOfAny (FileDialog.Separators);
if (string.IsNullOrWhiteSpace (path) || !Path.IsPathRooted (path))
{
return Enumerable.Empty<Suggestion> ();
}
string term = path.Substring (last + 1);
// If path is /tmp/ then don't just list everything in it
if (string.IsNullOrWhiteSpace (term))
{
return Enumerable.Empty<Suggestion> ();
}
if (term.Equals (state?.Directory?.Name))
{
// Clear suggestions
return Enumerable.Empty<Suggestion> ();
}
bool isWindows = RuntimeInformation.IsOSPlatform (OSPlatform.Windows);
string [] suggestions = state.Children.Where (d => !d.IsParent)
.Select (
e => e.FileSystemInfo is IDirectoryInfo d
? d.Name + Path.DirectorySeparatorChar
: e.FileSystemInfo.Name
)
.ToArray ();
string [] validSuggestions = suggestions
.Where (
s => s.StartsWith (
term,
isWindows
? StringComparison.InvariantCultureIgnoreCase
: StringComparison.InvariantCulture
)
)
.OrderBy (m => m.Length)
.ToArray ();
// nothing to suggest
if (validSuggestions.Length == 0 || validSuggestions [0].Length == term.Length)
{
return Enumerable.Empty<Suggestion> ();
}
return validSuggestions.Select (
f => new Suggestion (term.Length, f, f)
)
.ToList ();
}
public bool IsWordChar (Rune rune)
{
if (rune.Value == '\n')
{
return false;
}
return true;
}
}