// Copyright (C) 2023 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 #include "copilotsettings.h" #include "copilotconstants.h" #include "copilottr.h" #include #include #include using namespace Utils; namespace Copilot { static void initEnableAspect(BoolAspect &enableCopilot) { enableCopilot.setSettingsKey(Constants::ENABLE_COPILOT); enableCopilot.setDisplayName(Tr::tr("Enable Copilot")); enableCopilot.setLabelText(Tr::tr("Enable Copilot")); enableCopilot.setToolTip(Tr::tr("Enables the Copilot integration.")); enableCopilot.setDefaultValue(false); } CopilotSettings &CopilotSettings::instance() { static CopilotSettings settings; return settings; } CopilotSettings::CopilotSettings() { setAutoApply(false); const FilePath nodeFromPath = FilePath("node").searchInPath(); const FilePaths searchDirs = {FilePath::fromUserInput("~/.vim/pack/github/start/copilot.vim/copilot/dist/agent.js"), FilePath::fromUserInput( "~/.config/nvim/pack/github/start/copilot.vim/copilot/dist/agent.js"), FilePath::fromUserInput( "~/vimfiles/pack/github/start/copilot.vim/copilot/dist/agent.js"), FilePath::fromUserInput( "~/AppData/Local/nvim/pack/github/start/copilot.vim/copilot/dist/agent.js")}; const FilePath distFromVim = findOrDefault(searchDirs, &FilePath::exists); nodeJsPath.setExpectedKind(PathChooser::ExistingCommand); nodeJsPath.setDefaultFilePath(nodeFromPath); nodeJsPath.setSettingsKey("Copilot.NodeJsPath"); nodeJsPath.setLabelText(Tr::tr("Node.js path:")); nodeJsPath.setHistoryCompleter("Copilot.NodePath.History"); nodeJsPath.setDisplayName(Tr::tr("Node.js Path")); nodeJsPath.setEnabler(&enableCopilot); nodeJsPath.setToolTip( Tr::tr("Select path to node.js executable. See https://nodejs.org/en/download/" "for installation instructions.")); distPath.setExpectedKind(PathChooser::File); distPath.setDefaultFilePath(distFromVim); distPath.setSettingsKey("Copilot.DistPath"); distPath.setLabelText(Tr::tr("Path to agent.js:")); distPath.setHistoryCompleter("Copilot.DistPath.History"); distPath.setDisplayName(Tr::tr("Agent.js path")); distPath.setEnabler(&enableCopilot); distPath.setToolTip(Tr::tr( "Select path to agent.js in Copilot Neovim plugin. See " "https://github.com/github/copilot.vim#getting-started for installation instructions.")); autoComplete.setDisplayName(Tr::tr("Auto Complete")); autoComplete.setSettingsKey("Copilot.Autocomplete"); autoComplete.setLabelText(Tr::tr("Request completions automatically")); autoComplete.setDefaultValue(true); autoComplete.setEnabler(&enableCopilot); autoComplete.setToolTip(Tr::tr("Automatically request suggestions for the current text cursor " "position after changes to the document.")); initEnableAspect(enableCopilot); } CopilotProjectSettings::CopilotProjectSettings(ProjectExplorer::Project *project, QObject *parent) : AspectContainer(parent) { setAutoApply(true); useGlobalSettings.setSettingsKey(Constants::COPILOT_USE_GLOBAL_SETTINGS); useGlobalSettings.setDefaultValue(true); initEnableAspect(enableCopilot); QVariantMap map = project->namedSettings(Constants::COPILOT_PROJECT_SETTINGS_ID).toMap(); fromMap(map); connect(&enableCopilot, &BaseAspect::changed, this, [this, project] { save(project); }); connect(&useGlobalSettings, &BaseAspect::changed, this, [this, project] { save(project); }); } void CopilotProjectSettings::setUseGlobalSettings(bool useGlobal) { useGlobalSettings.setValue(useGlobal); } bool CopilotProjectSettings::isEnabled() const { if (useGlobalSettings()) return CopilotSettings::instance().enableCopilot(); return enableCopilot(); } void CopilotProjectSettings::save(ProjectExplorer::Project *project) { QVariantMap map; toMap(map); project->setNamedSettings(Constants::COPILOT_PROJECT_SETTINGS_ID, map); // This triggers a restart of the Copilot language server. CopilotSettings::instance().apply(); } } // namespace Copilot