/// <summary> /// Initializes the singleton instance of the command. /// </summary> /// <param name="package">Owner package, not null.</param> /// <returns>An awaitable task.</returns> public static async Task InitializeAsync(AsyncPackage package) { // Execute this method on the UI thread. await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); // Instantiate the command. OleMenuCommandService commandService = await package.GetServiceAsync(typeof(IMenuCommandService)) as OleMenuCommandService; SetModuleHeaderCommand.instance = new SetModuleHeaderCommand(package, commandService); }
/// <summary> /// This function is the callback used to execute the command when the menu item is clicked. /// See the constructor to see how the menu item is associated with this function using /// OleMenuCommandService service and MenuCommand class. /// </summary> /// <param name="sender">Event sender.</param> /// <param name="e">Event args.</param> private void Execute(object sender, EventArgs e) { // Verify the current thread is the UI thread. ThreadHelper.ThrowIfNotOnUIThread(); // Make sure that the user has set the (or accepted the default) value for a wrap margin. if (!Settings.Default.IsHeadingSet) { SetModuleHeaderCommand.SetHeader(); } // We can only execute this command when an active document is present. if (InsertModuleHeaderCommand.environment.ActiveDocument != null) { // Get the selected text from the environment. TextSelection selection = InsertModuleHeaderCommand.environment.ActiveDocument.Selection as TextSelection; // This command will place a copyright notice in the first block of comments it finds. This is generally the block that describes // the class found in the file. The general idea here is to move the cursor to the start of the file and then search for the first // set of block comments. Once that is found, we'll continue to read until there are no more comments in the block and place the // copyright notice there. This is likely a 95% solution. The alternative was to place the copyright notice on the same line as the // cursor, but that would involve guessing at the indentation and the exact format of the comment prefix. EditPoint startPoint = selection.AnchorPoint.CreateEditPoint(); startPoint.StartOfDocument(); // The active document's full name is normalized to lower case (so why does StyleCop force us to normalize in upper case?). So we'd // have a problem if we tried to use the name of the module found in this structure: since the analyzers check the case-sensitive // name of the file against the name of the module in the header, a name that is normalized to lower case will fail. So we need to // go the long way around to find a function that returns the non-normalized name of the file. string directoryPath = Path.GetDirectoryName(InsertModuleHeaderCommand.environment.ActiveDocument.FullName); string[] files = Directory.GetFiles(directoryPath, Path.GetFileName(InsertModuleHeaderCommand.environment.ActiveDocument.Name)); string moduleName = Path.GetFileName(files[0]); // This inserts the boilerplate header at the start of the module. startPoint.Insert( string.Format( CultureInfo.InvariantCulture, Resources.ModuleHeaderTemplate, "// ", moduleName, Settings.Default.Company, Settings.Default.CopyrightNotice, Settings.Default.Author)); } }
/// <summary> /// Initialization of the package; this method is called right after the package is sited, so this is the place /// where you can put all the initialization code that rely on services provided by VisualStudio. /// </summary> /// <param name="cancellationToken">A cancellation token to monitor for initialization cancellation, which can occur when VS is shutting down.</param> /// <param name="progress">A provider for progress updates.</param> /// <returns>A task representing the async work of package initialization, or an already completed task if there is none. Do not return null from this method.</returns> protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress <ServiceProgressData> progress) { // When initialized asynchronously, the current thread may be a background thread at this point. // Do any initialization that requires the UI thread after switching to the UI thread. await this.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); await FormatCommentCommand.InitializeAsync(this); await FormatXmlCommand.InitializeAsync(this); await InsertModuleHeaderCommand.InitializeAsync(this); await InsertConstructorHeaderCommand.InitializeAsync(this); await SetModuleHeaderCommand.InitializeAsync(this); await SetWrapMarginCommand.InitializeAsync(this); await ScrubXsdCommand.InitializeAsync(this); }
/// <summary> /// This function is the callback used to execute the command when the menu item is clicked. /// See the constructor to see how the menu item is associated with this function using /// OleMenuCommandService service and MenuCommand class. /// </summary> /// <param name="sender">Event sender.</param> /// <param name="e">Event args.</param> private void Execute(object sender, EventArgs e) { // This does the actal work of prompting the user for the header values. SetModuleHeaderCommand.SetHeader(); }