private async void RetriggerAsync(bool force) { _lastTyped = DateTime.Now; int delay = force ? 50 : _delay; await System.Threading.Tasks.Task.Delay(delay); // Prevents retriggering from happening while typing fast if (_lastTyped.AddMilliseconds(delay) > DateTime.Now) { return; } var doc = JSONEditorDocument.FromTextView(_textView); JSONParseItem parseItem = doc?.JSONDocument.ItemBeforePosition(_textView.Caret.Position.BufferPosition); if (parseItem == null) { return; } JSONMember member = parseItem.FindType <JSONMember>(); if (!member.UnquotedNameText.Equals("id") && !member.UnquotedNameText.Equals("path") && member.UnquotedValueText?.Length <= 1) { return; } JSONObject parent = parseItem.FindType <JSONObject>(); if (JsonHelpers.TryGetInstallationState(parent, out ILibraryInstallationState state)) { VsHelpers.DTE.ExecuteCommand("Edit.ListMembers"); } }
public void OnBlockCreated(ITextBuffer editorBuffer, LanguageProjectionBuffer projectionBuffer) { WindowHelpers.WaitFor(delegate { var textView = TextViewConnectionListener.GetFirstViewForBuffer(editorBuffer); if (textView == null) { return(false); } // Add the inner buffer's EditorDocument to the outer buffer before // broken editor code tries to create a new EditorDocument from the // outer buffer. var editorDocument = JSONEditorDocument.FromTextBuffer(projectionBuffer.IProjectionBuffer); ServiceManager.AddService(editorDocument, textView.TextBuffer); editorDocument.Closing += delegate { ServiceManager.RemoveService <JSONEditorDocument>(textView.TextBuffer); }; // JSONIndenter uses TextView.TextBuffer, and therefore operates on the // entire Markdown buffer, breaking everything. I manually force it to // use the inner projection buffer instead. Beware that this breaks its // ViewCaret property, and I can't fix that unless I mock its TextView. var indenter = ServiceManager.GetService <ISmartIndent>(textView); indenter.GetType().GetField("_textBuffer", BindingFlags.Instance | BindingFlags.NonPublic) .SetValue(indenter, projectionBuffer.IProjectionBuffer); return(true); }); }
private JSONParseItem GetItemBeforePosition(int pos, JSONEditorDocument document) { JSONParseItem item = null; JSONParseItemList children = document.JSONDocument.Children; int start = 0; if (children.Any()) { start = children[0].Start; } if (start < pos) { int i = FindInsertIndex(children, pos, beforeExisting: true) - 1; if (i >= 0) { item = children[i]; if (item is JSONComplexItem) { // Recurse to find the deepest item item = GetItemBeforePosition(item.Start, document); } } } return(item); }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (session == null || qiContent == null) { return; } // Map the trigger point down to our buffer. SnapshotPoint?point = session.GetTriggerPoint(_buffer.CurrentSnapshot); if (!point.HasValue) { return; } JSONEditorDocument doc = JSONEditorDocument.FromTextBuffer(_buffer); JSONParseItem item = doc.JSONDocument.ItemBeforePosition(point.Value.Position); if (item == null || !item.IsValid) { return; } JSONMember dependency = item.FindType <JSONMember>(); if (dependency == null) { return; } var parent = dependency.Parent.FindType <JSONMember>(); if (parent == null || !parent.UnquotedNameText.EndsWith("dependencies", StringComparison.OrdinalIgnoreCase)) { return; } applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(item.Start, item.Length, SpanTrackingMode.EdgeNegative); if (dependency.Value == item) { string version = item.Text.Trim('"', '~', '^'); qiContent.Add(" " + version + " " + Resource.CompletionVersionLatest + Environment.NewLine + "~" + version + " " + Resource.CompletionVersionMinor + Environment.NewLine + "^" + version + " " + Resource.CompletionVersionMajor); } else { UIElement element = CreateTooltip(dependency.UnquotedNameText, item); if (element != null) { qiContent.Add(element); } } }
private async void RetriggerAsync(bool force) { _lastTyped = DateTime.Now; int delay = force ? 50 : _delay; // Don't leave "stale" completion session up while the user is typing, or else we could // get completion from a stale session. ICompletionSession completionSession = _broker.GetSessions(_textView).FirstOrDefault(); if (completionSession != null && completionSession.Properties.TryGetProperty <bool>(RetriggerCompletion, out bool retrigger) && retrigger) { completionSession.Dismiss(); } await System.Threading.Tasks.Task.Delay(delay); // Prevents retriggering from happening while typing fast if (_lastTyped.AddMilliseconds(delay) > DateTime.Now) { return; } // Completion may have gotten invoked via by Web Editor OnPostTypeChar(). Don't invoke again, or else we get flikering completion list // TODO:Review the design here post-preview 4 and make sure this completion controller doesn't clash with Web Editors JSON completion controller completionSession = _broker.GetSessions(_textView).FirstOrDefault(); if (completionSession != null && completionSession.Properties.TryGetProperty <bool>(RetriggerCompletion, out retrigger)) { return; } var doc = JSONEditorDocument.FromTextBuffer(_textView.TextDataModel.DocumentBuffer); if (doc == null) { return; } JSONParseItem parseItem = GetItemBeforePosition(_textView.Caret.Position.BufferPosition, doc.JSONDocument); if (parseItem == null) { return; } JSONMember member = parseItem.FindType <JSONMember>(); if (member == null || (!member.UnquotedNameText.Equals(ManifestConstants.Library) && !member.UnquotedNameText.Equals(ManifestConstants.Destination) && member.UnquotedValueText?.Length <= 1)) { return; } JSONObject parent = parseItem.FindType <JSONObject>(); if (JsonHelpers.TryGetInstallationState(parent, out ILibraryInstallationState state)) { VsHelpers.DTE.ExecuteCommand("Edit.ListMembers"); } }
private JSONMember GetLibraries(ITextBuffer textBuffer) { JSONEditorDocument document = JSONEditorDocument.FromTextBuffer(textBuffer); if (document != null) { IEnumerable <JSONMember> jsonMembers = document.JSONDocument.TopLevelValue.FindType <JSONObject>().Children.OfType <JSONMember>(); return(jsonMembers.FirstOrDefault(m => m.UnquotedNameText == ManifestConstants.Libraries)); } return(null); }
public void OnTextViewCreated(ITextView textView, ITextBuffer textBuffer) { var jsonBuffer = textView.BufferGraph.GetTextBuffers(tb => tb.ContentType.IsOfType("JSON")).FirstOrDefault(); if (jsonBuffer == null) { return; } // Attach the inner buffer's Document to the outer // buffer so that it can be found from the TextView var editorDocument = JSONEditorDocument.FromTextBuffer(jsonBuffer) ?? JSONEditorDocument.Attach(jsonBuffer); ServiceManager.AddService(editorDocument, textView.TextDataModel.DocumentBuffer); editorDocument.Closing += delegate { ServiceManager.RemoveService <JSONEditorDocument>(textView.TextBuffer); }; }
public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> qiContent, out ITrackingSpan applicableToSpan) { applicableToSpan = null; if (session == null || qiContent == null || qiContent.Count > 0) { return; } // Map the trigger point down to our buffer. SnapshotPoint?point = session.GetTriggerPoint(_buffer.CurrentSnapshot); if (!point.HasValue) { return; } var doc = JSONEditorDocument.FromTextBuffer(_buffer); JSONParseItem item = doc.JSONDocument.ItemBeforePosition(point.Value.Position); if (item == null || !item.IsValid) { return; } JSONMember member = item.FindType <JSONMember>(); if (member == null || member.Name == null) { return; } IJSONSchema schema = _schemaResolver.DetermineSchemaForTextBuffer(_buffer); if (schema != null) { IJSONSchemaPropertyNameCompletionInfo info = Foo(schema, member); if (info != null && !string.IsNullOrEmpty(info.PropertyDocumentation)) { applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(item.Start, item.Length, SpanTrackingMode.EdgeNegative); qiContent.Add(info.DisplayText + Environment.NewLine + info.PropertyDocumentation); } } }
public void OnBlockCreated(ITextBuffer editorBuffer, LanguageProjectionBuffer projectionBuffer) { WindowHelpers.WaitFor(delegate { var textView = TextViewConnectionListener.GetFirstViewForBuffer(editorBuffer); if (textView == null) { return(false); } // Attach the inner buffer's Document to the outer // buffer so that it can be found from the TextView var editorDocument = JSONEditorDocument.FromTextBuffer(projectionBuffer.IProjectionBuffer) ?? JSONEditorDocument.Attach(projectionBuffer.IProjectionBuffer); ServiceManager.AddService(editorDocument, editorBuffer); editorDocument.Closing += delegate { ServiceManager.RemoveService <JSONEditorDocument>(textView.TextBuffer); }; return(true); }); }
/// <summary> /// This must be delayed so that the TextViewConnectionListener /// has a chance to initialize the WebEditor host. /// </summary> public bool EnsureInitialized() { if (_tree == null && WebEditor.Host != null) { try { JSONEditorDocument document = JSONEditorDocument.FromTextBuffer(_textBuffer); _tree = document.JSONDocument; RegisterSmartTagProviders(); WebEditor.OnIdle += OnIdle; } catch (Exception) { } } return(_tree != null); }
protected override bool Execute(VSConstants.VSStd2KCmdID commandId, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut) { var selection = TextView.GetSelection("JSON"); if (selection == null) { return(false); } var doc = JSONEditorDocument.FromTextBuffer(selection.Value.Snapshot.TextBuffer); if (doc == null) { return(false); } var visitor = new JSONItemCollector <JSONMember>(true); doc.JSONDocument.Accept(visitor); var properties = visitor.Items.Where(i => !i.IsValid && i.Name != null).Reverse(); if (properties.Count() == 0) { return(false); } try { InsertMissingQuotes(properties); } catch { // Do nothing } return(false); }