Example #1
0
        protected virtual void SetupNewTextView(IVsTextView textView)
        {
            Contract.ThrowIfNull(textView);

            var wpfTextView = EditorAdaptersFactoryService.GetWpfTextView(textView);

            Contract.ThrowIfNull(wpfTextView, "Could not get IWpfTextView for IVsTextView");

            Debug.Assert(!wpfTextView.Properties.ContainsProperty(typeof(AbstractVsTextViewFilter)));

            var workspace = Package.ComponentModel.GetService <VisualStudioWorkspace>();

            // The lifetime of CommandFilter is married to the view
            wpfTextView.GetOrCreateAutoClosingProperty(v =>
                                                       new StandaloneCommandFilter(
                                                           v, Package.ComponentModel).AttachToVsTextView());

            var isMetadataAsSource         = false;
            var collapseAllImplementations = false;

            var openDocument = wpfTextView.TextBuffer.AsTextContainer().GetRelatedDocuments().FirstOrDefault();

            if (openDocument?.Project.Solution.Workspace is MetadataAsSourceWorkspace masWorkspace)
            {
                isMetadataAsSource = true;

                // If the file is metadata as source, and the user has the preference set to collapse them, then
                // always collapse all metadata as source
                var globalOptions = this.Package.ComponentModel.GetService <IGlobalOptionService>();
                var options       = BlockStructureOptionsStorage.GetBlockStructureOptions(globalOptions, openDocument.Project.Language, isMetadataAsSource: masWorkspace is not null);
                collapseAllImplementations = masWorkspace.FileService.ShouldCollapseOnOpen(openDocument.FilePath, options);
            }

            ConditionallyCollapseOutliningRegions(textView, wpfTextView, collapseAllImplementations);

            // If this is a metadata-to-source view, we want to consider the file read-only and prevent
            // it from being re-opened when VS is opened
            if (isMetadataAsSource && ErrorHandler.Succeeded(textView.GetBuffer(out var vsTextLines)))
            {
                Contract.ThrowIfNull(openDocument);

                ErrorHandler.ThrowOnFailure(vsTextLines.GetStateFlags(out var flags));
                flags |= (int)BUFFERSTATEFLAGS.BSF_USER_READONLY;
                ErrorHandler.ThrowOnFailure(vsTextLines.SetStateFlags(flags));

                var runningDocumentTable  = (IVsRunningDocumentTable)SystemServiceProvider.GetService(typeof(SVsRunningDocumentTable));
                var runningDocumentTable4 = (IVsRunningDocumentTable4)runningDocumentTable;

                if (runningDocumentTable4.IsMonikerValid(openDocument.FilePath))
                {
                    var cookie = runningDocumentTable4.GetDocumentCookie(openDocument.FilePath);
                    runningDocumentTable.ModifyDocumentFlags(cookie, (uint)_VSRDTFLAGS.RDT_DontAddToMRU | (uint)_VSRDTFLAGS.RDT_CantSave | (uint)_VSRDTFLAGS.RDT_DontAutoOpen, fSet: 1);
                }
            }
        }
        protected override bool ComputeInitialTagsSynchronously(ITextBuffer subjectBuffer)
        {
            // If we can't find this doc, or outlining is not enabled for it, no need to computed anything synchronously.

            var openDocument = subjectBuffer.AsTextContainer().GetRelatedDocuments().FirstOrDefault();

            if (openDocument == null)
            {
                return(false);
            }

            // If the main Outlining option is turned off, we can just skip computing tags synchronously
            // so when the document first opens, there won't be any tags yet. When the tags do come in
            // the IsDefaultCollapsed property, which controls the initial collapsing, won't have any effect
            // because the document will already be open.
            if (!GlobalOptions.GetOption(FeatureOnOffOptions.Outlining, openDocument.Project.Language))
            {
                return(false);
            }

            var options = BlockStructureOptionsStorage.GetBlockStructureOptions(GlobalOptions, openDocument.Project);

            // If we're a metadata-as-source doc, we need to compute the initial set of tags synchronously
            // so that we can collapse all the .IsImplementation tags to keep the UI clean and condensed.
            if (openDocument.Project.Solution.Workspace is MetadataAsSourceWorkspace masWorkspace &&
                masWorkspace.FileService.ShouldCollapseOnOpen(openDocument.FilePath, options))
            {
                return(true);
            }

            // If the user wants to collapse imports or #regions then we need to compute
            // synchronously, but only if there are imports or #regions in the file. To
            // save some work, we'll look for both in a single pass.
            var collapseRegions = GlobalOptions.GetOption(BlockStructureOptionsStorage.CollapseRegionsWhenFirstOpened, openDocument.Project.Language);
            var collapseImports = GlobalOptions.GetOption(BlockStructureOptionsStorage.CollapseImportsWhenFirstOpened, openDocument.Project.Language);

            if (!collapseRegions && !collapseImports)
            {
                return(false);
            }

            if (ContainsRegionOrImport(subjectBuffer.CurrentSnapshot, collapseRegions, collapseImports, openDocument.Project.Language))
            {
                return(true);
            }

            return(false);
        }