public override int Exec(ref Guid pguidCmdGroup, uint nCmdID, uint nCmdexecopt, IntPtr pvaIn, IntPtr pvaOut)
        {
            if (pguidCmdGroup == _commandGroup && nCmdID == _commandId)
            {
                _vsTextView.GetCaretPos(out int line, out int column);
                string curLine = _view.TextSnapshot.GetLineFromLineNumber(line).GetText();

                var pattern = new Regex(@"([\w .]+)=");
                if (pattern.IsMatch(curLine))
                {
                    GroupCollection groups   = pattern.Match(curLine).Groups;
                    string          ruleName = groups[1].Value.ToString().Trim();

                    SchemaCatalog.TryGetKeyword(ruleName, out Keyword keyword);
                    if (keyword != null && keyword.DocumentationLink != null)
                    {
                        VsShellUtilities.OpenSystemBrowser(keyword.DocumentationLink);
                    }
                    else
                    {
                        VsShellUtilities.OpenSystemBrowser(Constants.Homepage);
                    }
                }
                else
                {
                    VsShellUtilities.OpenSystemBrowser(Constants.Homepage);
                }
                return(VSConstants.S_OK);
            }

            ThreadHelper.ThrowIfNotOnUIThread();

            return(Next.Exec(pguidCmdGroup, nCmdID, nCmdexecopt, pvaIn, pvaOut));
        }
Exemple #2
0
        private void ValidateProperty(Property property)
        {
            bool hasKeyword = SchemaCatalog.TryGetKeyword(property.Keyword.Text, out Keyword keyword);

            // Unknown keyword
            ErrorCatalog.UnknownKeyword.Run(property.Keyword, !hasKeyword, (e) =>
            {
                e.Register(property.Keyword.Text);
            });

            ErrorCatalog.MissingValue.Run(property.Keyword, property.Value == null, (e) =>
            {
                e.Register();
            });

            ErrorCatalog.MissingSeverity.Run(property.Value, hasKeyword, (e) =>
            {
                if (property.Severity == null && keyword.RequiresSeverity)
                {
                    e.Register();
                }
            });

            ErrorCatalog.UnknownValue.Run(property.Value, hasKeyword, (e) =>
            {
                if (!(int.TryParse(property.Value.Text, out int intValue) && intValue > 0))
                {
                    if (keyword.SupportsMultipleValues)
                    {
                        foreach (string value in property.Value.Text?.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                        {
                            if (!keyword.Values.Any(v => v.Name.Is(value.Trim())))
                            {
                                e.Register(value, keyword.Name);
                            }
                        }
                    }
                    else if (!keyword.Values.Any(v => Regex.IsMatch(v.Name, "<.+>")))
                    {
                        if (keyword.Values.Count() > 0 && !keyword.Values.Any(v => v.Name.Is(property.Value.Text)))
                        {
                            e.Register(property.Value.Text, keyword.Name);
                        }
                    }
                }
            });
Exemple #3
0
        public void AugmentCompletionSession(ICompletionSession session, IList<CompletionSet> completionSets)
        {
            if (_disposed || _document.IsParsing)
                return;

            ITextSnapshot snapshot = _buffer.CurrentSnapshot;
            SnapshotPoint? triggerPoint = session.GetTriggerPoint(snapshot);

            if (triggerPoint == null || !triggerPoint.HasValue)
                return;

            SnapshotSpan line = triggerPoint.Value.GetContainingLine().Extent;
            var list = new List<Completion4>();
            int position = triggerPoint.Value.Position;
            ITrackingSpan applicableTo = snapshot.CreateTrackingSpan(position, 0, SpanTrackingMode.EdgeInclusive);

            ParseItem prev = _document.ParseItems.LastOrDefault(p => p.Span.Start < position && !p.Span.Contains(position - 1));
            ParseItem parseItem = _document.ItemAtPosition(position);
            string moniker = null;

            // Property
            if (string.IsNullOrWhiteSpace(line.GetText()) || parseItem?.ItemType == ItemType.Keyword)
            {
                bool isInRoot = !_document.ParseItems.Exists(p => p.ItemType == ItemType.Section && p.Span.Start < position);

                if (isInRoot)
                {
                    if (SchemaCatalog.TryGetKeyword(SchemaCatalog.Root, out Keyword root))
                        list.Add(CreateCompletion(root, root.Category));
                }
                else
                {
                    IEnumerable<Keyword> properties = EditorConfigPackage.CompletionOptions.ShowHiddenKeywords ? SchemaCatalog.AllKeywords : SchemaCatalog.VisibleKeywords;
                    IEnumerable<Keyword> items = properties.Where(i => i.Name != SchemaCatalog.Root);
                    IEnumerable<string> usedKeywords = _document.GetAllIncludedRules();

                    ParseItem parseItemSection = _document.ParseItems.LastOrDefault(p => p.ItemType == ItemType.Section && p.Span.Start < position);
                    if (parseItemSection != null)
                    {
                        Section section = _document.Sections.FirstOrDefault(x => x.Item.Text.Equals(parseItemSection.Text, StringComparison.OrdinalIgnoreCase));
                        if (section != null)
                        {
                            // Set keywords scope to current section
                            usedKeywords = section.Properties.Select(x => x.Keyword.Text).ToList();
                        }
                    }

                    foreach (Keyword property in items)
                    {
                        string keyword = property.Name;

                        // Keyword already used and keyword does not qualify as repeatable
                        if (usedKeywords.Contains(keyword) && !keyword.StartsWith("dotnet_naming_", StringComparison.OrdinalIgnoreCase))
                            continue;

                        list.Add(CreateCompletion(property, property.Category));
                    }
                }

                moniker = "keyword";
            }
            // Value
            else if (parseItem?.ItemType == ItemType.Value)
            {
                if (SchemaCatalog.TryGetKeyword(prev.Text, out Keyword item))
                {
                    if (!item.SupportsMultipleValues && parseItem.Text.Contains(","))
                    {
                        return;
                    }

                    foreach (Value value in item.Values)
                        list.Add(CreateCompletion(value, iconAutomation: "value"));
                }

                moniker = "value";
            }
            // Severity
            else if ((position > 0 && snapshot.Length > 1 && snapshot.GetText(position - 1, 1) == ":") || parseItem?.ItemType == ItemType.Severity)
            {
                if (prev?.ItemType == ItemType.Value || parseItem?.ItemType == ItemType.Severity)
                {
                    Property prop = _document.PropertyAtPosition(prev.Span.Start);
                    if (SchemaCatalog.TryGetKeyword(prop?.Keyword?.Text, out Keyword key) && key.RequiresSeverity)
                        AddSeverity(list);

                    moniker = "severity";
                }
            }
            // Suppression
            else if (parseItem?.ItemType == ItemType.Suppression)
            {
                foreach (Error code in ErrorCatalog.All.OrderBy(e => e.Code))
                    list.Add(CreateCompletion(code));

                moniker = "suppression";
            }

            if (!list.Any())
            {
                if (SchemaCatalog.TryGetKeyword(prev?.Text, out Keyword property))
                {
                    int eq = line.GetText().IndexOf("=");

                    if (eq != -1)
                    {
                        int eqPos = eq + line.Start.Position;

                        if (position > eqPos)
                            foreach (Value value in property.Values)
                                list.Add(CreateCompletion(value));
                    }

                    moniker = "value";
                }
            }
            else
            {
                ITrackingSpan trackingSpan = FindTokenSpanAtPosition(session);
                SnapshotSpan span = trackingSpan.GetSpan(snapshot);
                string text = span.GetText();

                if (text == ":" || text == ",")
                    applicableTo = snapshot.CreateTrackingSpan(new Span(span.Start + 1, 0), SpanTrackingMode.EdgeInclusive);
                else if (!string.IsNullOrWhiteSpace(text))
                    applicableTo = trackingSpan;
            }

            CreateCompletionSet(moniker, completionSets, list, applicableTo);
        }
        bool Commit(bool force)
        {
            if (_currentSession == null)
            {
                return(false);
            }

            if (!_currentSession.SelectedCompletionSet.SelectionStatus.IsSelected && !force)
            {
                _currentSession.Dismiss();
                return(false);
            }
            else
            {
                string moniker = _currentSession.SelectedCompletionSet.Moniker;
                _currentSession.Commit();

                if (!EditorConfigPackage.CompletionOptions.AutoInsertDelimiters)
                {
                    return(true);
                }

                SnapshotPoint     position = TextView.Caret.Position.BufferPosition;
                ITextSnapshotLine line     = TextView.TextBuffer.CurrentSnapshot.GetLineFromPosition(position);
                string            lineText = line.GetText();

                if (moniker == "keyword" && !lineText.Contains("="))
                {
                    TextView.TextBuffer.Insert(position, " = ");

                    // Contains placeholders
                    int start = lineText.IndexOf('<');
                    int end   = lineText.IndexOf('>');

                    if (start > -1 && start < end)
                    {
                        var span = new SnapshotSpan(TextView.TextBuffer.CurrentSnapshot, Span.FromBounds(line.Start + start, line.Start + end + 1));
                        TextView.Selection.Select(span, false);
                        TextView.Caret.MoveTo(span.Start);
                        return(true);
                    }

                    if (EditorConfigPackage.Language.Preferences.AutoListMembers)
                    {
                        StartSession();
                    }
                }
                else if (moniker == "value" && !lineText.Contains(":"))
                {
                    var      document = EditorConfigDocument.FromTextBuffer(TextView.TextBuffer);
                    Property prop     = document.PropertyAtPosition(position - 1);

                    if (SchemaCatalog.TryGetKeyword(prop.Keyword.Text, out Keyword keyword) && prop.Value != null)
                    {
                        if (keyword.RequiresSeverity)
                        {
                            TextView.TextBuffer.Insert(position, ":");

                            if (EditorConfigPackage.Language.Preferences.AutoListMembers)
                            {
                                StartSession();
                            }
                        }
                    }
                }

                return(true);
            }
        }
        public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> qiContent, out ITrackingSpan applicableToSpan)
        {
            applicableToSpan = null;

            SnapshotPoint?point = session.GetTriggerPoint(_buffer.CurrentSnapshot);

            if (session == null || qiContent == null || !point.HasValue || point.Value.Position >= point.Value.Snapshot.Length)
            {
                return;
            }

            ParseItem item = _document.ItemAtPosition(point.Value);

            if (item == null)
            {
                return;
            }

            applicableToSpan = point.Value.Snapshot.CreateTrackingSpan(item.Span, SpanTrackingMode.EdgeNegative);

            if (item.Errors.Any())
            {
                foreach (DisplayError error in item.Errors)
                {
                    qiContent.Add(new Shared.EditorTooltip(error));
                    return;
                }
            }

            Property property = _document.PropertyAtPosition(point.Value);

            SchemaCatalog.TryGetKeyword(property?.Keyword?.Text, out Keyword keyword);

            // Keyword
            if (keyword != null && item.ItemType == ItemType.Keyword)
            {
                qiContent.Add(new Shared.EditorTooltip(keyword));
            }

            // Value
            else if (keyword != null && item.ItemType == ItemType.Value)
            {
                Value value = keyword.Values.FirstOrDefault(v => v.Name.Is(item.Text));

                if (value != null && !string.IsNullOrEmpty(value.Description))
                {
                    qiContent.Add(new Shared.EditorTooltip(value));
                }
            }

            // Severity
            else if (item.ItemType == ItemType.Severity && SchemaCatalog.TryGetSeverity(item.Text, out Severity severity))
            {
                qiContent.Add(new Shared.EditorTooltip(severity));
            }

            // Suppression
            else if (item.ItemType == ItemType.Suppression && ErrorCatalog.TryGetErrorCode(item.Text, out var code))
            {
                qiContent.Add(new Shared.EditorTooltip(code));
            }
        }