@@ -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