/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/VisualStudio/CSharp/Impl/Options/CSharpVisualStudioCopilotOptionsService.cs
115 строк
6 KB
Maryam Ariyan
Enable Implement with Copilot by default
12 апр 2025, 14:12
12 апр 2025, 14:12
f335aaf
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Composition; using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Copilot; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.Internal.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Utilities.UnifiedSettings; namespace Microsoft.VisualStudio.LanguageServices.CSharp.Options; [ExportLanguageService(typeof(ICopilotOptionsService), LanguageNames.CSharp), Shared] internal sealed class CSharpVisualStudioCopilotOptionsService : ICopilotOptionsService { /// <summary> /// Guid for UI context that is set from Copilot when the package is initialized /// </summary> private const string CopilotHasLoadedGuid = "871c3e1c-e58c-4ce9-b6a7-26600555739a"; /// <summary> /// Guid for UI Context that is set from Copilot when sign in related UI contexts have been set properly. Used to determine when UI context status is final /// for a set of operations. When this UI context is not active, the signed in and entitled contexts values may not be correct. /// </summary> private const string GitHubAccountStatusDetermined = "3049be7e-71ee-4045-a510-f8ee1a967723"; /// <summary> /// Guid for UI context that is set from Copilot when we detect a GitHub account is signed in. /// </summary> private const string GitHubAccountStatusSignedIn = "ef3ebbb7-511d-472c-ae4b-6af1bb44f378"; /// <summary> /// Guid for UI context that is set from VS Identity Service when we detect that a signed in GitHub account is entitled to access Copilot. /// </summary> private const string GitHubAccountStatusIsCopilotEntitled = "3DE3FA6E-91B2-46C1-9E9E-DD04975BB890"; // Default value must reflect their default values in ConversationsOptions in Copilot repo. private readonly CopilotOption _copilotCodeAnalysisOption = new("copilot.featureFlags.editor.enableCSharpCodeAnalysis", false); private readonly CopilotOption _copilotRefineOption = new("copilot.featureFlags.editor.enableCSharpRefineQuickActionSuggestion", false); private readonly CopilotOption _copilotOnTheFlyDocsOption = new("copilot.general.editor.enableOnTheFlyDocs", true); private readonly CopilotOption _copilotGenerateDocumentationCommentOption = new("copilot.general.editor.enableGenerateDocumentationComment", true); private readonly CopilotOption _copilotGenerateMethodImplementationOption = new("copilot.featureFlags.editor.enableCSharpGenerateMethodImplementation", true); private static readonly UIContext s_copilotHasLoadedUIContext = UIContext.FromUIContextGuid(new Guid(CopilotHasLoadedGuid)); private static readonly UIContext s_gitHubAccountStatusDeterminedContext = UIContext.FromUIContextGuid(new Guid(GitHubAccountStatusDetermined)); private static readonly UIContext s_gitHubAccountStatusIsCopilotEntitledUIContext = UIContext.FromUIContextGuid(new Guid(GitHubAccountStatusIsCopilotEntitled)); private static readonly UIContext s_gitHubAccountStatusSignedInUIContext = UIContext.FromUIContextGuid(new Guid(GitHubAccountStatusSignedIn)); private readonly Task<ISettingsManager> _settingsManagerTask; private ISettingsReader? _settingsReader; /// <summary> /// Determines if Copilot is active and the user is signed in and entitled to use Copilot. /// </summary> private static bool IsGithubCopilotLoadedAndSignedIn => s_copilotHasLoadedUIContext.IsActive && s_gitHubAccountStatusDeterminedContext.IsActive && s_gitHubAccountStatusSignedInUIContext.IsActive && s_gitHubAccountStatusIsCopilotEntitledUIContext.IsActive; [method: ImportingConstructor] [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] public CSharpVisualStudioCopilotOptionsService( IVsService<SVsUnifiedSettingsManager, ISettingsManager> settingsManagerService, IThreadingContext threadingContext) { _settingsManagerTask = settingsManagerService.GetValueAsync(threadingContext.DisposalToken); } private async Task<bool> IsCopilotOptionEnabledAsync(CopilotOption option) { if (!IsGithubCopilotLoadedAndSignedIn) return false; if (_settingsReader == null) { var settingsManager = await _settingsManagerTask.ConfigureAwait(false); _settingsReader = settingsManager.GetReader(); } try { if (_settingsReader.GetValue<bool>(option.Name) is { Outcome: SettingRetrievalOutcome.Success } setting) return setting.Value; return option.DefaultValue; } catch { return option.DefaultValue; } } public Task<bool> IsCodeAnalysisOptionEnabledAsync() => IsCopilotOptionEnabledAsync(_copilotCodeAnalysisOption); public Task<bool> IsRefineOptionEnabledAsync() => IsCopilotOptionEnabledAsync(_copilotRefineOption); public Task<bool> IsOnTheFlyDocsOptionEnabledAsync() => IsCopilotOptionEnabledAsync(_copilotOnTheFlyDocsOption); public Task<bool> IsGenerateDocumentationCommentOptionEnabledAsync() => IsCopilotOptionEnabledAsync(_copilotGenerateDocumentationCommentOption); public Task<bool> IsImplementNotImplementedExceptionEnabledAsync() => IsCopilotOptionEnabledAsync(_copilotGenerateMethodImplementationOption); private record struct CopilotOption(string Name, bool DefaultValue); }