private void TextBufferChangedOnBackground(object sender, TextContentChangedEventArgs e) { if (e.Changes.Count == 0) { return; } if (e.Changes[0].NewLength == 0) { state.Sb.Clear(); return; } // Check if user is typing into what we're trying to suggest if (state.Sb.ToString().StartsWith(e.Changes[0].NewText)) { state.Sb.Remove(0, e.Changes[0].NewLength); return; } // 2.If user is typing a completely different thing, check cache // a. Synchronous cache check // b. If nothing, async query (the function might not query, but whatever) var codeBeforeCaret = new SnapshotSpan(view.TextSnapshot, 0, curCaretBufferPosition).GetText(); var normalized = DocumentProcessor.NormalizeCode(codeBeforeCaret) + e.Changes[0].NewText; var completion = state.Cache.GetCompletion(normalized); state.Sb.Clear(); state.Sb.Append(completion); if (completion.Length == 0) { // Used to grab the filename view.TextBuffer.Properties.TryGetProperty(typeof(ITextDocument), out ITextDocument doc); _ = Task.Run(() => RequestServer(normalized, doc)); } else { state.Sb.Remove(0, e.Changes[0].NewLength); } }