Код: Выделить всё
public class AutocompleteProvider
{
private CompletionWindow? _completionWindow;
public CompletionWindow? GetCompletionWindow()
{
return _completionWindow;
}
public void HandleTextEntered(TextArea textArea, string enteredText)
{
if (char.IsLetterOrDigit(enteredText[0]) || enteredText == ".")
{
ShowCompletionWindow(textArea);
}
if (enteredText == "\"")
{
textArea.Document.Insert(textArea.Caret.Offset, "\"");
textArea.Caret.Offset--;
}
}
private void ShowCompletionWindow(TextArea textArea)
{
if (_completionWindow != null)
return;
_completionWindow = new CompletionWindow(textArea);
var data = _completionWindow.CompletionList.CompletionData;
AddBasicCompletions(data);
AddServiceCompletions(data);
AddInstanceCompletions(data);
AddCustomCompletions(data);
AddDocumentCompletions(textArea.Document, data);
_completionWindow.CompletionList.PreviewKeyDown += (sender, e) =>
{
if (e.Key == Key.Tab && _completionWindow.CompletionList.SelectedItem is ICompletionData selectedItem)
{
ApplyCompletion(textArea, selectedItem);
e.Handled = true;
}
else if (e.Key == Key.Escape)
{
_completionWindow.Close();
e.Handled = true;
}
};
_completionWindow.Show();
_completionWindow.Closed += delegate
{
_completionWindow = null;
};
}
private void AddBasicCompletions(IList data)
{
string[] keywords = { "local", "function", "end", "if", "then", "else", "elseif", "for", "while", "do", "print" };
foreach (var keyword in keywords)
{
data.Add(new AutocompleteCompletionData(keyword));
}
}
private void AddServiceCompletions(IList data)
{
string[] services = { "game:GetService(\"\")", "workspace", "players", "script" };
foreach (var service in services)
{
data.Add(new AutocompleteCompletionData(service));
}
}
private void AddInstanceCompletions(IList data)
{
string[] instances = { "Instance.new(\"\")", "Vector3.new(\"\")", "CFrame.new(\"\")" };
foreach (var instance in instances)
{
data.Add(new AutocompleteCompletionData(instance));
}
}
private void AddCustomCompletions(IList data)
{
string[] variableNames = { "myVariable", "playerName", "position", "velocity" };
foreach (var variable in variableNames)
{
data.Add(new AutocompleteCompletionData(variable));
}
data.Add(new AutocompleteCompletionData("functionName()\n -- DEINE FUNKTION HIER\nend"));
}
private void AddDocumentCompletions(TextDocument document, IList data)
{
string text = document.Text;
var words = new HashSet();
foreach (var word in text.Split(new[] { ' ', '\n', '\r', '\t', '(', ')', '{', '}' }, StringSplitOptions.RemoveEmptyEntries))
{
if (word.Length > 2 && char.IsLetter(word[0]))
words.Add(word);
}
foreach (var word in words)
{
data.Add(new AutocompleteCompletionData(word));
}
}
private void ApplyCompletion(TextArea textArea, ICompletionData selectedItem)
{
string completionText = selectedItem.Text;
if (!string.IsNullOrEmpty(completionText))
{
int wordStartOffset = GetWordStartOffset(textArea);
int lengthToReplace = textArea.Caret.Offset - wordStartOffset;
string currentWord = textArea.Document.GetText(wordStartOffset, lengthToReplace);
textArea.Document.Replace(wordStartOffset, lengthToReplace, completionText);
textArea.Caret.Offset = wordStartOffset + completionText.Length;
}
_completionWindow?.Close();
}
public void HandleTextEntering(TextArea textArea, TextCompositionEventArgs e)
{
if (e.Text.Length > 0 && _completionWindow != null)
{
// Filter
string currentText = e.Text;
_completionWindow.CompletionList.SelectItem(currentText);
}
}
private int GetWordStartOffset(TextArea textArea)
{
int offset = textArea.Caret.Offset;
while (offset > 0 && !char.IsWhiteSpace(textArea.Document.GetCharAt(offset - 1)) && char.IsLetterOrDigit(textArea.Document.GetCharAt(offset - 1)))
{
offset--;
}
return offset;
}
}
public class AutocompleteCompletionData : ICompletionData
{
public double Priority { get; set; }
public AutocompleteCompletionData(string text)
{
Text = text;
}
public System.Windows.Media.ImageSource? Image => null;
public string Text { get; }
public object Content => Text;
public object Description => "Vervollständigung: " + Text;
public void Complete(TextArea textArea, ISegment completionSegment, EventArgs insertionRequestEventArgs)
{
textArea.Document.Replace(completionSegment, Text);
}
}
Проверка кода: проверка кода на наличие потенциальных проблем, связанных с допустимостью значений NULL и отсутствующими ссылками.
Скорректированная возможность принятия значений NULL:
Изменен _completionWindow на тип, допускающий значение NULL (CompletionWindow?).
Гарантирована правильная инициализация _completionWindow и проверка на наличие нулевых ссылок.
Включение пространства имен:
Добавлены необходимые пространства имен для компонентов Window и AvalonEdit.
Исправления обработки событий:
Обработчики событий textEditor (TextEntering и TextEntered) правильно определены и подключены в конструкторе MainWindow.
Пересмотренная логика автозаполнения:
Исправлена логика обработки ввода и завершения текста. , специально для отображения и применения дополнений.
Подробнее здесь: https://stackoverflow.com/questions/791 ... te-for-lua
Мобильная версия