diff --git a/Terminal.Gui/Core/Autocomplete/AppendAutocomplete.cs b/Terminal.Gui/Core/Autocomplete/AppendAutocomplete.cs
index 2b7eb9244..b8b48d0fe 100644
--- a/Terminal.Gui/Core/Autocomplete/AppendAutocomplete.cs
+++ b/Terminal.Gui/Core/Autocomplete/AppendAutocomplete.cs
@@ -8,43 +8,33 @@ namespace Terminal.Gui {
/// Autocomplete for a which shows suggestions within the box.
/// Displayed suggestions can be completed using the tab key.
///
- public class AppendAutocomplete : IAutocomplete {
+ public class AppendAutocomplete : AutocompleteBase {
private int? currentFragment = null;
private string [] validFragments = new string [0];
private TextField textField;
- public View HostControl { get => textField; set => textField = (TextField)value; }
- public bool PopupInsideContainer { get; set; }
- public int MaxWidth { get; set; }
- public int MaxHeight { get; set; }
- public bool Visible { get; set; }
- public ReadOnlyCollection Suggestions { get; set; }
- public List AllSuggestions { get; set; }
- public int SelectedIdx { get; set; }
- public ColorScheme ColorScheme { get; set; }
- public Key SelectionKey { get; set; } = Key.Tab;
- public Key CloseKey { get; set; }
- public Key Reopen { get; set; }
+ public override View HostControl { get => textField; set => textField = (TextField)value; }
+ public override ColorScheme ColorScheme { get; set; }
- public void ClearSuggestions ()
+ public override void ClearSuggestions ()
{
this.currentFragment = null;
this.validFragments = new string [0];
textField.SetNeedsDisplay ();
}
- public void GenerateSuggestions (int columnOffset = 0)
+ public override void GenerateSuggestions (int columnOffset = 0)
{
validFragments = new string []{ "fish", "flipper", "fun" };
}
- public bool MouseEvent (MouseEvent me, bool fromHost = false)
+ public override bool MouseEvent (MouseEvent me, bool fromHost = false)
{
return false;
}
- public bool ProcessKey (KeyEvent kb)
+ public override bool ProcessKey (KeyEvent kb)
{
var key = kb.Key;
if (key == SelectionKey) {
@@ -60,7 +50,7 @@ namespace Terminal.Gui {
return false;
}
- public void RenderOverlay (Point renderAt)
+ public override void RenderOverlay (Point renderAt)
{
if (!this.MakingSuggestion ()) {
return;
@@ -142,5 +132,10 @@ namespace Terminal.Gui {
textField.SetNeedsDisplay ();
return true;
}
+
+ protected override string GetCurrentWord (int columnOffset = 0)
+ {
+ throw new System.NotImplementedException ();
+ }
}
}
diff --git a/Terminal.Gui/Core/Autocomplete/AutocompleteBase.cs b/Terminal.Gui/Core/Autocomplete/AutocompleteBase.cs
new file mode 100644
index 000000000..ed16a320d
--- /dev/null
+++ b/Terminal.Gui/Core/Autocomplete/AutocompleteBase.cs
@@ -0,0 +1,184 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+using Rune = System.Rune;
+
+namespace Terminal.Gui {
+ public abstract class AutocompleteBase : IAutocomplete
+ {
+ public abstract View HostControl { get; set; }
+ public bool PopupInsideContainer { get; set; }
+
+ ///
+ /// The maximum width of the autocomplete dropdown
+ ///
+ public virtual int MaxWidth { get; set; } = 10;
+
+ ///
+ /// The maximum number of visible rows in the autocomplete dropdown to render
+ ///
+ public virtual int MaxHeight { get; set; } = 6;
+
+ ///
+
+
+ ///
+ /// True if the autocomplete should be considered open and visible
+ ///
+ public virtual bool Visible { get; set; }
+
+ ///
+ /// The strings that form the current list of suggestions to render
+ /// based on what the user has typed so far.
+ ///
+ public virtual ReadOnlyCollection Suggestions { get; set; } = new ReadOnlyCollection (new string [0]);
+
+ ///
+ /// The full set of all strings that can be suggested.
+ ///
+ ///
+ public virtual List AllSuggestions { get; set; } = new List ();
+
+ ///
+ /// The currently selected index into that the user has highlighted
+ ///
+ public virtual int SelectedIdx { get; set; }
+
+
+ ///
+ public abstract ColorScheme ColorScheme { get; set; }
+
+ ///
+ public virtual Key SelectionKey { get; set; } = Key.Enter;
+
+ ///
+ public virtual Key CloseKey { get; set; } = Key.Esc;
+
+ ///
+ public virtual Key Reopen { get; set; } = Key.Space | Key.CtrlMask | Key.AltMask;
+
+ ///
+ public abstract bool MouseEvent (MouseEvent me, bool fromHost = false);
+
+ ///
+ public abstract bool ProcessKey (KeyEvent kb);
+ ///
+ public abstract void RenderOverlay (Point renderAt);
+
+ ///
+ /// Clears
+ ///
+ public virtual void ClearSuggestions ()
+ {
+ Suggestions = Enumerable.Empty ().ToList ().AsReadOnly ();
+ }
+
+
+ ///
+ /// Populates with all strings in that
+ /// match with the current cursor position/text in the
+ ///
+ /// The column offset.
+ public virtual void GenerateSuggestions (int columnOffset = 0)
+ {
+ // if there is nothing to pick from
+ if (AllSuggestions.Count == 0) {
+ ClearSuggestions ();
+ return;
+ }
+
+ var currentWord = GetCurrentWord (columnOffset);
+
+ if (string.IsNullOrWhiteSpace (currentWord)) {
+ ClearSuggestions ();
+ } else {
+ Suggestions = AllSuggestions.Where (o =>
+ o.StartsWith (currentWord, StringComparison.CurrentCultureIgnoreCase) &&
+ !o.Equals (currentWord, StringComparison.CurrentCultureIgnoreCase)
+ ).ToList ().AsReadOnly ();
+
+ EnsureSelectedIdxIsValid ();
+ }
+ }
+
+ ///
+ /// Updates to be a valid index within
+ ///
+ public virtual void EnsureSelectedIdxIsValid ()
+ {
+ SelectedIdx = Math.Max (0, Math.Min (Suggestions.Count - 1, SelectedIdx));
+ }
+
+ ///
+ /// Return true if the given symbol should be considered part of a word
+ /// and can be contained in matches. Base behavior is to use
+ ///
+ ///
+ ///
+ public virtual bool IsWordChar (Rune rune)
+ {
+ return Char.IsLetterOrDigit ((char)rune);
+ }
+
+
+ ///
+ /// Returns the currently selected word from the .
+ ///
+ /// When overriding this method views can make use of
+ ///
+ ///
+ /// The column offset.
+ ///
+ protected abstract string GetCurrentWord (int columnOffset = 0);
+
+ ///
+ ///
+ /// Given a of characters, returns the word which ends at
+ /// or null. Also returns null if the is positioned in the middle of a word.
+ ///
+ ///
+ ///
+ /// Use this method to determine whether autocomplete should be shown when the cursor is at
+ /// a given point in a line and to get the word from which suggestions should be generated.
+ /// Use the to indicate if search the word at left (negative),
+ /// at right (positive) or at the current column (zero) which is the default.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ protected virtual string IdxToWord (List line, int idx, int columnOffset = 0)
+ {
+ StringBuilder sb = new StringBuilder ();
+ var endIdx = idx;
+
+ // get the ending word index
+ while (endIdx < line.Count) {
+ if (IsWordChar (line [endIdx])) {
+ endIdx++;
+ } else {
+ break;
+ }
+ }
+
+ // It isn't a word char then there is no way to autocomplete that word
+ if (endIdx == idx && columnOffset != 0) {
+ return null;
+ }
+
+ // we are at the end of a word. Work out what has been typed so far
+ while (endIdx-- > 0) {
+ if (IsWordChar (line [endIdx])) {
+ sb.Insert (0, (char)line [endIdx]);
+ } else {
+ break;
+ }
+ }
+ return sb.ToString ();
+ }
+ }
+}
+
diff --git a/Terminal.Gui/Core/Autocomplete/Autocomplete.cs b/Terminal.Gui/Core/Autocomplete/PopupAutocomplete.cs
similarity index 69%
rename from Terminal.Gui/Core/Autocomplete/Autocomplete.cs
rename to Terminal.Gui/Core/Autocomplete/PopupAutocomplete.cs
index 9b225e5b8..827248d4c 100644
--- a/Terminal.Gui/Core/Autocomplete/Autocomplete.cs
+++ b/Terminal.Gui/Core/Autocomplete/PopupAutocomplete.cs
@@ -11,12 +11,12 @@ namespace Terminal.Gui {
/// Renders an overlay on another view at a given point that allows selecting
/// from a range of 'autocomplete' options.
///
- public abstract class Autocomplete : IAutocomplete {
+ public abstract class PopupAutocomplete : AutocompleteBase {
private class Popup : View {
- Autocomplete autocomplete;
+ PopupAutocomplete autocomplete;
- public Popup (Autocomplete autocomplete)
+ public Popup (PopupAutocomplete autocomplete)
{
this.autocomplete = autocomplete;
CanFocus = true;
@@ -61,7 +61,7 @@ namespace Terminal.Gui {
///
/// The host control to handle.
///
- public virtual View HostControl {
+ public override View HostControl {
get => hostControl;
set {
hostControl = value;
@@ -74,6 +74,11 @@ namespace Terminal.Gui {
}
}
+ public PopupAutocomplete ()
+ {
+ PopupInsideContainer = true;
+ }
+
private void Top_Removed (object sender, SuperViewChangedEventArgs e)
{
Visible = false;
@@ -112,42 +117,6 @@ namespace Terminal.Gui {
}
}
- ///
- /// Gets or sets If the popup is displayed inside or outside the host limits.
- ///
- public bool PopupInsideContainer { get; set; } = true;
-
- ///
- /// The maximum width of the autocomplete dropdown
- ///
- public virtual int MaxWidth { get; set; } = 10;
-
- ///
- /// The maximum number of visible rows in the autocomplete dropdown to render
- ///
- public virtual int MaxHeight { get; set; } = 6;
-
- ///
- /// True if the autocomplete should be considered open and visible
- ///
- public virtual bool Visible { get; set; }
-
- ///
- /// The strings that form the current list of suggestions to render
- /// based on what the user has typed so far.
- ///
- public virtual ReadOnlyCollection Suggestions { get; set; } = new ReadOnlyCollection (new string [0]);
-
- ///
- /// The full set of all strings that can be suggested.
- ///
- ///
- public virtual List AllSuggestions { get; set; } = new List ();
-
- ///
- /// The currently selected index into that the user has highlighted
- ///
- public virtual int SelectedIdx { get; set; }
///
/// When more suggestions are available than can be rendered the user
@@ -160,7 +129,7 @@ namespace Terminal.Gui {
/// The colors to use to render the overlay. Accessing this property before
/// the Application has been initialized will cause an error
///
- public virtual ColorScheme ColorScheme {
+ public override ColorScheme ColorScheme {
get {
if (colorScheme == null) {
colorScheme = Colors.Menu;
@@ -172,27 +141,12 @@ namespace Terminal.Gui {
}
}
- ///
- /// The key that the user must press to accept the currently selected autocomplete suggestion
- ///
- public virtual Key SelectionKey { get; set; } = Key.Enter;
-
- ///
- /// The key that the user can press to close the currently popped autocomplete menu
- ///
- public virtual Key CloseKey { get; set; } = Key.Esc;
-
- ///
- /// The key that the user can press to reopen the currently popped autocomplete menu
- ///
- public virtual Key Reopen { get; set; } = Key.Space | Key.CtrlMask | Key.AltMask;
-
///
/// Renders the autocomplete dialog inside or outside the given at the
/// given point.
///
///
- public virtual void RenderOverlay (Point renderAt)
+ public override void RenderOverlay (Point renderAt)
{
if (!Visible || HostControl?.HasFocus == false || Suggestions.Count == 0) {
LastPopupPos = null;
@@ -294,12 +248,10 @@ namespace Terminal.Gui {
}
}
- ///
- /// Updates to be a valid index within
- ///
- public virtual void EnsureSelectedIdxIsValid ()
+ public override void EnsureSelectedIdxIsValid ()
{
- SelectedIdx = Math.Max (0, Math.Min (Suggestions.Count - 1, SelectedIdx));
+ base.EnsureSelectedIdxIsValid ();
+
// if user moved selection up off top of current scroll window
if (SelectedIdx < ScrollOffset) {
@@ -311,7 +263,6 @@ namespace Terminal.Gui {
ScrollOffset++;
}
}
-
///
/// Handle key events before e.g. to make key events like
/// up/down apply to the autocomplete control instead of changing the cursor position in
@@ -319,7 +270,7 @@ namespace Terminal.Gui {
///
/// The key event.
/// trueif the key can be handled falseotherwise.
- public virtual bool ProcessKey (KeyEvent kb)
+ public override bool ProcessKey (KeyEvent kb)
{
if (IsWordChar ((char)kb.Key)) {
Visible = true;
@@ -381,7 +332,7 @@ namespace Terminal.Gui {
/// The mouse event.
/// If was called from the popup or from the host.
/// trueif the mouse can be handled falseotherwise.
- public virtual bool MouseEvent (MouseEvent me, bool fromHost = false)
+ public override bool MouseEvent (MouseEvent me, bool fromHost = false)
{
if (fromHost) {
if (!Visible) {
@@ -450,53 +401,7 @@ namespace Terminal.Gui {
}
}
- ///
- /// Clears
- ///
- public virtual void ClearSuggestions ()
- {
- Suggestions = Enumerable.Empty ().ToList ().AsReadOnly ();
- }
-
-
- ///
- /// Populates with all strings in that
- /// match with the current cursor position/text in the
- ///
- /// The column offset.
- public virtual void GenerateSuggestions (int columnOffset = 0)
- {
- // if there is nothing to pick from
- if (AllSuggestions.Count == 0) {
- ClearSuggestions ();
- return;
- }
-
- var currentWord = GetCurrentWord (columnOffset);
-
- if (string.IsNullOrWhiteSpace (currentWord)) {
- ClearSuggestions ();
- } else {
- Suggestions = AllSuggestions.Where (o =>
- o.StartsWith (currentWord, StringComparison.CurrentCultureIgnoreCase) &&
- !o.Equals (currentWord, StringComparison.CurrentCultureIgnoreCase)
- ).ToList ().AsReadOnly ();
-
- EnsureSelectedIdxIsValid ();
- }
- }
-
-
- ///
- /// Return true if the given symbol should be considered part of a word
- /// and can be contained in matches. Base behavior is to use
- ///
- ///
- ///
- public virtual bool IsWordChar (Rune rune)
- {
- return Char.IsLetterOrDigit ((char)rune);
- }
+
///
/// Completes the autocomplete selection process. Called when user hits the .
@@ -541,62 +446,6 @@ namespace Terminal.Gui {
return false;
}
- ///
- /// Returns the currently selected word from the .
- ///
- /// When overriding this method views can make use of
- ///
- ///
- /// The column offset.
- ///
- protected abstract string GetCurrentWord (int columnOffset = 0);
-
- ///
- ///
- /// Given a of characters, returns the word which ends at
- /// or null. Also returns null if the is positioned in the middle of a word.
- ///
- ///
- ///
- /// Use this method to determine whether autocomplete should be shown when the cursor is at
- /// a given point in a line and to get the word from which suggestions should be generated.
- /// Use the to indicate if search the word at left (negative),
- /// at right (positive) or at the current column (zero) which is the default.
- ///
- ///
- ///
- ///
- ///
- ///
- protected virtual string IdxToWord (List line, int idx, int columnOffset = 0)
- {
- StringBuilder sb = new StringBuilder ();
- var endIdx = idx;
-
- // get the ending word index
- while (endIdx < line.Count) {
- if (IsWordChar (line [endIdx])) {
- endIdx++;
- } else {
- break;
- }
- }
-
- // It isn't a word char then there is no way to autocomplete that word
- if (endIdx == idx && columnOffset != 0) {
- return null;
- }
-
- // we are at the end of a word. Work out what has been typed so far
- while (endIdx-- > 0) {
- if (IsWordChar (line [endIdx])) {
- sb.Insert (0, (char)line [endIdx]);
- } else {
- break;
- }
- }
- return sb.ToString ();
- }
///
/// Deletes the text backwards before insert the selected text in the .
@@ -664,3 +513,4 @@ namespace Terminal.Gui {
}
}
}
+
diff --git a/Terminal.Gui/Views/TextField.cs b/Terminal.Gui/Views/TextField.cs
index d4171ea8e..0df6149a4 100644
--- a/Terminal.Gui/Views/TextField.cs
+++ b/Terminal.Gui/Views/TextField.cs
@@ -1315,7 +1315,7 @@ namespace Terminal.Gui {
/// from a range of 'autocomplete' options.
/// An implementation on a TextField.
///
- public class TextFieldAutocomplete : Autocomplete {
+ public class TextFieldAutocomplete : PopupAutocomplete {
///
protected override void DeleteTextBackwards ()
diff --git a/Terminal.Gui/Views/TextView.cs b/Terminal.Gui/Views/TextView.cs
index fe5a3abe5..37dbe2998 100644
--- a/Terminal.Gui/Views/TextView.cs
+++ b/Terminal.Gui/Views/TextView.cs
@@ -1146,7 +1146,7 @@ namespace Terminal.Gui {
///
/// Provides autocomplete context menu based on suggestions at the current cursor
- /// position. Populate to enable this feature
+ /// position. Populate to enable this feature
///
public IAutocomplete Autocomplete { get; protected set; } = new TextViewAutocomplete ();
@@ -1734,7 +1734,6 @@ namespace Terminal.Gui {
}
Height = 1;
LayoutStyle = lyout;
- Autocomplete.PopupInsideContainer = false;
SetNeedsDisplay ();
} else if (multiline && savedHeight != null) {
var lyout = LayoutStyle;
@@ -1743,7 +1742,6 @@ namespace Terminal.Gui {
}
Height = savedHeight;
LayoutStyle = lyout;
- Autocomplete.PopupInsideContainer = true;
SetNeedsDisplay ();
}
}
@@ -4425,7 +4423,7 @@ namespace Terminal.Gui {
/// from a range of 'autocomplete' options.
/// An implementation on a TextView.
///
- public class TextViewAutocomplete : Autocomplete {
+ public class TextViewAutocomplete : PopupAutocomplete {
///
protected override string GetCurrentWord (int columnOffset = 0)