Skip to content
This repository was archived by the owner on Oct 4, 2021. It is now read-only.

Commit 61dc150

Browse files
committed
[Debugger] Improved code-completion handling for adding new watch expressions
Fixes https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1018525/
1 parent 6c652fe commit 61dc150

File tree

1 file changed

+69
-1
lines changed

1 file changed

+69
-1
lines changed

main/src/addins/MonoDevelop.Debugger/MonoDevelop.Debugger/DebuggerAsyncCompletionSource.cs

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,75 @@ public Task<object> GetDescriptionAsync (IAsyncCompletionSession session, Comple
8888

8989
public CompletionStartData InitializeCompletion (CompletionTrigger trigger, SnapshotPoint triggerLocation, CancellationToken token)
9090
{
91+
switch (trigger.Character) {
92+
case '.': // we want member completion for this
93+
case '<': // we want type completion for this
94+
case '(': // we want parameter completion for this
95+
break;
96+
default:
97+
if (!char.IsLetterOrDigit (trigger.Character))
98+
return new CompletionStartData (CompletionParticipation.DoesNotProvideItems);
99+
break;
100+
}
101+
91102
var text = triggerLocation.Snapshot.GetText (0, triggerLocation.Position);
103+
104+
if (IsInsideQuotedString (text, triggerLocation.Position))
105+
return new CompletionStartData (CompletionParticipation.DoesNotProvideItems);
106+
92107
var span = GetWordSpan (text, triggerLocation.Position);
93108

94109
return new CompletionStartData (CompletionParticipation.ProvidesItems, new SnapshotSpan (triggerLocation.Snapshot, span));
95110
}
96111

112+
static bool IsInsideQuotedString (string text, int position)
113+
{
114+
bool quoted = false;
115+
int index = 0;
116+
117+
do {
118+
while (index < position && text[index] != '"')
119+
index++;
120+
121+
if (index == position)
122+
break;
123+
124+
if (index > 0 && text[index - 1] == '\'') {
125+
// char literal
126+
index++;
127+
} else {
128+
// quoted string
129+
var literal = index > 0 && text[index - 1] == '@';
130+
var escaped = false;
131+
quoted = true;
132+
index++;
133+
134+
while (index < position) {
135+
if (text[index] == '\\') {
136+
escaped = !escaped;
137+
} else if (text[index] == '"') {
138+
if (escaped) {
139+
escaped = false;
140+
} else {
141+
quoted = false;
142+
index++;
143+
144+
if (literal && index < position && text[index] == '"') {
145+
quoted = true;
146+
} else {
147+
break;
148+
}
149+
}
150+
}
151+
152+
index++;
153+
}
154+
}
155+
} while (index < position);
156+
157+
return quoted;
158+
}
159+
97160
public static Span GetWordSpan (string text, int position)
98161
{
99162
var start = position;
@@ -129,7 +192,7 @@ public IAsyncCompletionCommitManager GetOrCreate (ITextView textView)
129192

130193
sealed class DebuggerAsyncCompletionCommitManager : IAsyncCompletionCommitManager
131194
{
132-
static readonly char[] CommitCharacters = new char[] { ' ', '\t', '\n', '.', ',', '<', '>', '(', ')', '[', ']' };
195+
static readonly char[] CommitCharacters = new char[] { ' ', '\t', '\n', '.', ',', '<', '>', '(', ')', '[', ']', '\'', '"' };
133196

134197
public IEnumerable<char> PotentialCommitCharacters {
135198
get { return CommitCharacters; }
@@ -142,6 +205,11 @@ public bool ShouldCommitCompletion (IAsyncCompletionSession session, SnapshotPoi
142205

143206
public CommitResult TryCommit (IAsyncCompletionSession session, ITextBuffer buffer, CompletionItem item, char typedChar, CancellationToken token)
144207
{
208+
if (typedChar == '\'' || typedChar == '"') {
209+
// User is entering a char or string, dismiss the completion window.
210+
return new CommitResult (true, CommitBehavior.None);
211+
}
212+
145213
// Note: Hitting Return should *always* complete the current selection, but other typed chars require examining context...
146214
if (typedChar != '\0' && typedChar != '\n') {
147215
var text = buffer.CurrentSnapshot.GetText ();

0 commit comments

Comments
 (0)