forked from icsharpcode/AvalonEdit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Code Completion.aml
133 lines (125 loc) · 5.05 KB
/
Code Completion.aml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<?xml version="1.0" encoding="utf-8"?>
<topic id="47c58b63-f30c-4290-a2f2-881d21227446" revisionNumber="1">
<developerConceptualDocument xmlns="http://ddue.schemas.microsoft.com/authoring/2003/5" xmlns:xlink="http://www.w3.org/1999/xlink">
<introduction>
<para>
AvalonEdit comes with a code completion drop down window.
You only have to handle the text entering events to determine
when you want to show the window; all the UI is already done for you.
</para>
</introduction>
<section>
<title>Usage of the Code Completion Window</title>
<content>
<code language="cs">
// in the constructor:
textEditor.TextArea.TextEntering += textEditor_TextArea_TextEntering;
textEditor.TextArea.TextEntered += textEditor_TextArea_TextEntered;
}
CompletionWindow completionWindow;
void textEditor_TextArea_TextEntered(object sender, TextCompositionEventArgs e)
{
if (e.Text == ".") {
// Open code completion after the user has pressed dot:
completionWindow = new CompletionWindow(textEditor.TextArea);
IList<ICompletionData> data = completionWindow.CompletionList.CompletionData;
data.Add(new MyCompletionData("Item1"));
data.Add(new MyCompletionData("Item2"));
data.Add(new MyCompletionData("Item3"));
completionWindow.Show();
completionWindow.Closed += delegate {
completionWindow = null;
};
}
}
void textEditor_TextArea_TextEntering(object sender, TextCompositionEventArgs e)
{
if (e.Text.Length > 0 && completionWindow != null) {
if (!char.IsLetterOrDigit(e.Text[0])) {
// Whenever a non-letter is typed while the completion window is open,
// insert the currently selected element.
completionWindow.CompletionList.RequestInsertion(e);
}
}
// Do not set e.Handled=true.
// We still want to insert the character that was typed.
}
</code>
<para>
This code will open the code completion window whenever '.' is pressed.
By default, the
<codeEntityReference>T:ICSharpCode.AvalonEdit.CodeCompletion.CompletionWindow</codeEntityReference>
only handles key presses like Tab and Enter to insert the currently
selected item. To also make it complete when keys like '.' or ';' are pressed,
we attach another handler to the <codeInline>TextEntering</codeInline> event
and tell the completion window to insert the selected item.
</para>
<para>
The <codeInline>CompletionWindow</codeInline> will actually never have
focus - instead, it hijacks
the WPF keyboard input events on the text area and passes them through its
<codeInline>ListBox</codeInline>.
This allows selecting entries in the completion list using the
keyboard and normal typing in the editor at the same time.
</para>
<para>
Here is the implementation of the MyCompletionData class used in the code above:
<code language="cs">
/// Implements AvalonEdit ICompletionData interface to provide the entries in the
/// completion drop down.
public class MyCompletionData : ICompletionData
{
public MyCompletionData(string text)
{
this.Text = text;
}
public System.Windows.Media.ImageSource Image {
get { return null; }
}
public string Text { get; private set; }
// Use this property if you want to show a fancy UIElement in the list.
public object Content {
get { return this.Text; }
}
public object Description {
get { return "Description for " + this.Text; }
}
public void Complete(TextArea textArea, ISegment completionSegment,
EventArgs insertionRequestEventArgs)
{
textArea.Document.Replace(completionSegment, this.Text);
}
}
</code>
Both the content and the description shown may be any content acceptable in WPF,
including custom UIElements.
You may also implement custom logic in the <codeInline>Complete</codeInline>
method if you want to do more than simply inserting the text.
The <codeInline>insertionRequestEventArgs</codeInline> can help decide which
kind of insertion the user wants - depending on how the insertion was triggered,
it is an instance of <codeInline>TextCompositionEventArgs</codeInline>,
<codeInline>KeyEventArgs</codeInline> or <codeInline>MouseEventArgs</codeInline>.
</para>
</content>
</section>
<section>
<title>Code Completion for C#</title>
<content>
<para>
Full C# code completion is not in the scope of AvalonEdit.
You will need a C# parser, a C# type system, and the ability
to resolve C# expressions in your type system.
</para>
<para>
If you want to learn how this is handled in SharpDevelop, please
see:
<externalLink>
<linkText>Code Completion in SharpDevelop</linkText>
<linkUri>https://github.com/icsharpcode/SharpDevelop/wiki/Code-Completion</linkUri>
<linkTarget>_blank</linkTarget>
</externalLink>
</para>
</content>
</section>
</developerConceptualDocument>
</topic>