Merge branch 'terminalProjectEnv' of https://github.com/sblundy/intellij-community...
authorDmitry Trofimov <dmitry.trofimov@jetbrains.com>
Mon, 22 Oct 2018 15:44:48 +0000 (17:44 +0200)
committerDmitry Trofimov <dmitry.trofimov@jetbrains.com>
Mon, 22 Oct 2018 15:44:48 +0000 (17:44 +0200)
1  2 
plugins/terminal/intellij.terminal.iml
plugins/terminal/src/org/jetbrains/plugins/terminal/LocalTerminalDirectRunner.java
plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalOptionsProvider.kt
plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalSettingsPanel.form
plugins/terminal/src/org/jetbrains/plugins/terminal/TerminalSettingsPanel.java

index 1b92168b4abedb1996827c3f5f8419463e49ed99,0000000000000000000000000000000000000000..0419813133a2f3adc3a15464b0c746686a154978
mode 100644,000000..100644
--- /dev/null
@@@ -1,23 -1,0 +1,24 @@@
 +<?xml version="1.0" encoding="UTF-8"?>
 +<module relativePaths="true" type="JAVA_MODULE" version="4">
 +  <component name="NewModuleRootManager" inherit-compiler-output="true">
 +    <exclude-output />
 +    <content url="file://$MODULE_DIR$">
 +      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
 +      <sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
 +      <sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
 +    </content>
 +    <orderEntry type="inheritedJdk" />
 +    <orderEntry type="sourceFolder" forTests="false" />
 +    <orderEntry type="module" module-name="intellij.platform.lang" />
 +    <orderEntry type="module" module-name="intellij.platform.ide.impl" />
 +    <orderEntry type="library" name="Guava" level="project" />
 +    <orderEntry type="library" name="pty4j" level="project" />
 +    <orderEntry type="library" name="jna" level="project" />
 +    <orderEntry type="module" module-name="intellij.platform.remoteServers" />
 +    <orderEntry type="module" module-name="intellij.platform.remoteServers.impl" />
 +    <orderEntry type="library" scope="TEST" name="JUnit4" level="project" />
 +    <orderEntry type="module" module-name="intellij.platform.testFramework" scope="TEST" />
 +    <orderEntry type="library" name="jediterm-pty" level="project" />
++    <orderEntry type="module" module-name="intellij.platform.lang.impl" />
 +  </component>
 +</module>
index befb825900cb57f9c18f613e71b6696972b54639,590ff144364988fa04b9b85c2fa535e13f3898cb..572384fde0b0f2bbc87ba43ae8b4be761ee0bf71
   */
  package org.jetbrains.plugins.terminal;
  
 +import com.google.common.collect.Lists;
  import com.intellij.execution.TaskExecutor;
++
 +import com.intellij.execution.process.ProcessAdapter;
 +import com.intellij.execution.process.ProcessEvent;
 +import com.intellij.execution.process.ProcessHandler;
 +import com.intellij.execution.process.ProcessWaitFor;
 +import com.intellij.internal.statistic.service.fus.collectors.FUSUsageContext;
+ import com.intellij.execution.configurations.EncodingEnvironmentUtil;
+ import com.intellij.execution.process.*;
+ import com.intellij.openapi.application.Application;
+ import com.intellij.openapi.application.ApplicationManager;
+ import com.intellij.openapi.components.PathMacroManager;
  import com.intellij.openapi.diagnostic.Logger;
  import com.intellij.openapi.project.Project;
 -import com.intellij.openapi.roots.ProjectRootManager;
  import com.intellij.openapi.util.SystemInfo;
 +import com.intellij.openapi.util.io.FileUtil;
 +import com.intellij.openapi.util.text.StringUtil;
  import com.intellij.openapi.vfs.CharsetToolkit;
 -import com.intellij.openapi.vfs.VirtualFile;
 -import com.intellij.util.Consumer;
 -import com.intellij.util.containers.HashMap;
 +import com.intellij.util.ArrayUtil;
 +import com.intellij.util.EnvironmentUtil;
 +import com.intellij.util.concurrency.AppExecutorUtil;
 +import com.intellij.util.containers.ContainerUtil;
 +import com.intellij.util.text.CaseInsensitiveStringHashingStrategy;
  import com.jediterm.pty.PtyProcessTtyConnector;
  import com.jediterm.terminal.TtyConnector;
  import com.pty4j.PtyProcess;
@@@ -44,9 -39,7 +50,10 @@@ import org.jetbrains.annotations.Nullab
  import java.io.File;
  import java.io.IOException;
  import java.io.OutputStream;
 +import java.net.URL;
  import java.nio.charset.Charset;
++import java.util.HashMap;
 +import java.util.List;
  import java.util.Map;
  import java.util.concurrent.ExecutionException;
  import java.util.concurrent.Future;
@@@ -117,43 -86,43 +124,58 @@@ public class LocalTerminalDirectRunner 
      return new LocalTerminalDirectRunner(project);
    }
  
 -  @Override
 -  protected PtyProcess createProcess(@Nullable String directory) throws ExecutionException {
 -    Map<String, String> envs = getTerminalEnvironment();
 -    try {
 -      return PtyProcess.exec(getCommand(), envs, directory != null ? directory : currentProjectFolder());
 -    }
 -    catch (IOException e) {
 -      throw new ExecutionException(e);
 -    }
 -  }
+   private Map<String, String> getTerminalEnvironment() {
++
++
+     Map<String, String> envs = new HashMap<String, String>();
 -    if (TerminalOptionsProvider.getInstance().passParentEnvs()) {
++    if (TerminalOptionsProvider.Companion.getInstance().passParentEnvs()) {
+       envs.putAll(System.getenv());
+     }
+     envs.put("TERM", "xterm-256color");
+     EncodingEnvironmentUtil.setLocaleEnvironmentIfMac(envs, myDefaultCharset);
+     PathMacroManager macroManager = PathMacroManager.getInstance(myProject);
 -    for (Map.Entry<String, String> env : TerminalOptionsProvider.getInstance().getUserSpecifiedEnvs().entrySet()) {
++    for (Map.Entry<String, String> env : TerminalOptionsProvider.Companion.getInstance().getUserSpecifiedEnvs().entrySet()) {
+       envs.put(env.getKey(), macroManager.expandPath(env.getValue()));
+     }
+     return envs;
+   }
 -  private String currentProjectFolder() {
 -    final ProjectRootManager projectRootManager = ProjectRootManager.getInstance(myProject);
 +  @Override
 +  protected PtyProcess createProcess(@Nullable String directory) throws ExecutionException {
-     Map<String, String> envs = new THashMap<>(SystemInfo.isWindows ? CaseInsensitiveStringHashingStrategy.INSTANCE
-                                                                    : ContainerUtil.canonicalStrategy());
-     envs.putAll(System.getenv());
-     if (!SystemInfo.isWindows) {
-       envs.put("TERM", "xterm-256color");
-     }
++    Map<String, String> envs = getTerminalEnvironment();
  
 -    final VirtualFile[] roots = projectRootManager.getContentRoots();
 -    if (roots.length == 1) {
 -      roots[0].getCanonicalPath();
 +    if (SystemInfo.isMac) {
 +      EnvironmentUtil.setLocaleEnv(envs, myDefaultCharset);
 +    }
 +
 +    String[] command = getCommand(envs);
 +
 +    for (LocalTerminalCustomizer customizer : LocalTerminalCustomizer.EP_NAME.getExtensions()) {
 +      try {
 +        command = customizer.customizeCommandAndEnvironment(myProject, command, envs);
 +
 +        if (directory == null) {
 +          directory = customizer.getDefaultFolder(myProject);
 +        }
 +      }
 +      catch (Exception e) {
 +        LOG.error("Exception during customization of the terminal session", e);
 +      }
 +    }
 +
 +    try {
 +      TerminalUsageTriggerCollector.Companion.trigger(myProject, "local.exec", FUSUsageContext.create(FUSUsageContext.getOSNameContextData(), SystemInfo.getOsNameAndVersion(), getShellName(command[0])));
 +      return PtyProcess.exec(command, envs, directory != null
 +                                            ? directory
 +                                            : TerminalProjectOptionsProvider.Companion.getInstance(myProject).getStartingDirectory());
 +    }
 +    catch (IOException e) {
 +      throw new ExecutionException(e);
      }
 -    final VirtualFile baseDir = myProject.getBaseDir();
 -    return baseDir == null ? null : baseDir.getCanonicalPath();
    }
  
    @Override
index 7d8fba476ffaf89847ac34899b82de8e7366b31e,0000000000000000000000000000000000000000..25003f19e44d7ddd4f3dbdb45f71b443bd2d5dff
mode 100644,000000..100644
--- /dev/null
@@@ -1,151 -1,0 +1,170 @@@
 +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
 +package org.jetbrains.plugins.terminal
 +
 +import com.intellij.openapi.components.PersistentStateComponent
 +import com.intellij.openapi.components.ServiceManager
 +import com.intellij.openapi.components.State
 +import com.intellij.openapi.components.Storage
 +import com.intellij.openapi.util.SystemInfo
 +import java.io.File
++import java.util.HashMap
 +
 +/**
 + * @author traff
 + */
 +
 +@State(name = "TerminalOptionsProvider", storages = [(Storage("terminal.xml"))])
 +class TerminalOptionsProvider : PersistentStateComponent<TerminalOptionsProvider.State> {
 +  private val myState = State()
 +
 +  var shellPath: String? by ValueWithDefault(State::myShellPath, myState) { defaultShellPath }
 +
 +  override fun getState(): State? {
 +    return myState
 +  }
 +
 +  override fun loadState(state: State) {
 +    myState.myCloseSessionOnLogout = state.myCloseSessionOnLogout
 +    myState.myReportMouse = state.myReportMouse
 +    myState.mySoundBell = state.mySoundBell
 +    myState.myTabName = state.myTabName
 +    myState.myCopyOnSelection = state.myCopyOnSelection
 +    myState.myPasteOnMiddleMouseButton = state.myPasteOnMiddleMouseButton
 +    myState.myOverrideIdeShortcuts = state.myOverrideIdeShortcuts
 +    myState.myShellIntegration = state.myShellIntegration
 +    myState.myShellPath = state.myShellPath
 +    myState.myHighlightHyperlinks = state.myHighlightHyperlinks
 +  }
 +
 +  fun closeSessionOnLogout(): Boolean {
 +    return myState.myCloseSessionOnLogout
 +  }
 +
 +  fun enableMouseReporting(): Boolean {
 +    return myState.myReportMouse
 +  }
 +
 +  fun audibleBell(): Boolean {
 +    return myState.mySoundBell
 +  }
 +
 +  var tabName: String
 +    get() = myState.myTabName
 +    set(tabName) {
 +      myState.myTabName = tabName
 +    }
 +
 +  fun overrideIdeShortcuts(): Boolean {
 +    return myState.myOverrideIdeShortcuts
 +  }
 +
 +  fun setOverrideIdeShortcuts(overrideIdeShortcuts: Boolean) {
 +    myState.myOverrideIdeShortcuts = overrideIdeShortcuts
 +  }
 +
 +  fun shellIntegration(): Boolean {
 +    return myState.myShellIntegration
 +  }
 +
 +  fun setShellIntegration(shellIntegration: Boolean) {
 +    myState.myShellIntegration = shellIntegration
 +  }
 +
 +  class State {
 +    var myShellPath: String? = null
 +    var myTabName: String = "Local"
 +    var myCloseSessionOnLogout: Boolean = true
 +    var myReportMouse: Boolean = true
 +    var mySoundBell: Boolean = true
 +    var myCopyOnSelection: Boolean = true
 +    var myPasteOnMiddleMouseButton: Boolean = true
 +    var myOverrideIdeShortcuts: Boolean = true
 +    var myShellIntegration: Boolean = true
 +    var myHighlightHyperlinks: Boolean = true
++    var myUserSpecifiedEnvs: Map<String, String> = hashMapOf("PROJECT_DIR" to "\$PROJECT_DIR$")
++    var myPassParentEnvs = true
 +  }
 +
 +  fun setCloseSessionOnLogout(closeSessionOnLogout: Boolean) {
 +    myState.myCloseSessionOnLogout = closeSessionOnLogout
 +  }
 +
 +  fun setReportMouse(reportMouse: Boolean) {
 +    myState.myReportMouse = reportMouse
 +  }
 +
 +  fun setSoundBell(soundBell: Boolean) {
 +    myState.mySoundBell = soundBell
 +  }
 +
 +  fun copyOnSelection(): Boolean {
 +    return myState.myCopyOnSelection
 +  }
 +
 +  fun setCopyOnSelection(copyOnSelection: Boolean) {
 +    myState.myCopyOnSelection = copyOnSelection
 +  }
 +
 +  fun pasteOnMiddleMouseButton(): Boolean {
 +    return myState.myPasteOnMiddleMouseButton
 +  }
 +
 +  fun setPasteOnMiddleMouseButton(pasteOnMiddleMouseButton: Boolean) {
 +    myState.myPasteOnMiddleMouseButton = pasteOnMiddleMouseButton
 +  }
 +
 +  fun highlightHyperlinks(): Boolean {
 +    return myState.myHighlightHyperlinks
 +  }
 +
 +  fun setHighlightHyperlinks(highlight: Boolean) {
 +    myState.myHighlightHyperlinks = highlight
 +  }
 +
++  fun getUserSpecifiedEnvs(): Map<String, String> {
++    return myState.myUserSpecifiedEnvs
++  }
++
++  fun setUserSpecifiedEnvs(userSpecifiedEnvs: Map<String, String>) {
++    myState.myUserSpecifiedEnvs = userSpecifiedEnvs
++  }
++
++  fun setPassParentEnvs(passParentEnvs: Boolean) {
++    myState.myPassParentEnvs = passParentEnvs
++  }
++
++  fun passParentEnvs(): Boolean {
++    return myState.myPassParentEnvs
++  }
++
 +  val defaultShellPath: String
 +    get() {
 +      val shell = System.getenv("SHELL")
 +
 +      if (shell != null && File(shell).canExecute()) {
 +        return shell
 +      }
 +
 +      if (SystemInfo.isUnix) {
 +        if (File("/bin/bash").exists()) {
 +          return "/bin/bash"
 +        }
 +        else {
 +          return "/bin/sh"
 +        }
 +      }
 +      else {
 +        return "cmd.exe"
 +      }
 +    }
 +
 +  companion object {
 +    val instance: TerminalOptionsProvider
 +      get() = ServiceManager.getService(TerminalOptionsProvider::class.java)
 +  }
 +}
 +
 +
 +
 +
 +
index 8d12d38cecff65511d47cc510fbf3a9517be645b,4e998f174340253417664d0672942e812cd4b1a6..529c5864fb3e2c89b6c3be615c473f3b83ab1e44
            <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
          </constraints>
          <properties/>
-         <clientProperties>
-           <BorderFactoryClass class="java.lang.String" value=""/>
-         </clientProperties>
          <border type="none"/>
          <children>
 -          <grid id="57ec0" layout-manager="GridLayoutManager" row-count="3" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
 +          <vspacer id="d777c">
 +            <constraints>
 +              <grid row="2" column="0" row-span="7" col-span="4" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
 +            </constraints>
 +          </vspacer>
-           <grid id="871ca" binding="myProjectSettingsPanel" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
++          <grid id="871ca" binding="myProjectSettingsPanel" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
              <margin top="0" left="0" bottom="0" right="0"/>
              <constraints>
 -              <grid row="0" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
 +              <grid row="0" column="0" row-span="1" col-span="4" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
              </constraints>
              <properties/>
              <border type="none"/>
                  </constraints>
                  <properties/>
                </component>
 -                  <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+               <component id="a7470" class="javax.swing.JLabel">
+                 <constraints>
 -                  <grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
++                  <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                 </constraints>
+                 <properties>
+                   <text value="Environment Variables"/>
+                 </properties>
+               </component>
+               <component id="9454c" class="com.intellij.execution.configuration.EnvironmentVariablesTextFieldWithBrowseButton" binding="myEnvVarField">
+                 <constraints>
++                  <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+                 </constraints>
+                 <properties>
+                   <text value=""/>
+                 </properties>
+               </component>
              </children>
            </grid>
 -          <vspacer id="d777c">
 -            <constraints>
 -              <grid row="6" column="0" row-span="1" col-span="3" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
 -            </constraints>
 -          </vspacer>
 -          <grid id="caa1d" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
 +          <grid id="5c27f" binding="myGlobalSettingsPanel" layout-manager="GridLayoutManager" row-count="10" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
              <margin top="0" left="0" bottom="0" right="0"/>
              <constraints>
 -              <grid row="1" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
 +              <grid row="1" column="0" row-span="1" col-span="4" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
              </constraints>
              <properties/>
              <border type="none"/>
index afd955d0894314445bad5332ea29c0aee0a5406d,4275697e1579f1bac03357732e446bd2f56f0972..353474d937210512393d76729eeb47b950aaadb7
@@@ -1,10 -1,22 +1,11 @@@
 -/*
 - * Copyright 2000-2013 JetBrains s.r.o.
 - *
 - * Licensed under the Apache License, Version 2.0 (the "License");
 - * you may not use this file except in compliance with the License.
 - * You may obtain a copy of the License at
 - *
 - * http://www.apache.org/licenses/LICENSE-2.0
 - *
 - * Unless required by applicable law or agreed to in writing, software
 - * distributed under the License is distributed on an "AS IS" BASIS,
 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 - * See the License for the specific language governing permissions and
 - * limitations under the License.
 - */
 +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
  package org.jetbrains.plugins.terminal;
  
 +import com.google.common.collect.Lists;
+ import com.intellij.execution.configuration.EnvironmentVariablesTextFieldWithBrowseButton;
  import com.intellij.openapi.fileChooser.FileChooserDescriptor;
 +import com.intellij.openapi.options.ConfigurationException;
 +import com.intellij.openapi.options.UnnamedConfigurable;
  import com.intellij.openapi.ui.TextComponentAccessor;
  import com.intellij.openapi.ui.TextFieldWithBrowseButton;
  import com.intellij.openapi.util.Comparing;
@@@ -32,23 -38,11 +33,27 @@@ public class TerminalSettingsPanel 
    private JBCheckBox myPasteOnMiddleButtonCheckBox;
    private JBCheckBox myCopyOnSelectionCheckBox;
    private JBCheckBox myOverrideIdeShortcuts;
++
 +  private JBCheckBox myShellIntegration;
 +  private TextFieldWithBrowseButton myStartDirectoryField;
 +  private JPanel myProjectSettingsPanel;
 +  private JPanel myGlobalSettingsPanel;
 +  private JPanel myConfigurablesPanel;
 +  private JBCheckBox myHighlightHyperlinks;
++
+   private EnvironmentVariablesTextFieldWithBrowseButton myEnvVarField;
++
    private TerminalOptionsProvider myOptionsProvider;
 +  private TerminalProjectOptionsProvider myProjectOptionsProvider;
 +
 +  private final java.util.List<UnnamedConfigurable> myConfigurables = Lists.newArrayList();
  
 -  public JComponent createPanel(@NotNull TerminalOptionsProvider provider) {
 +  public JComponent createPanel(@NotNull TerminalOptionsProvider provider, @NotNull TerminalProjectOptionsProvider projectOptionsProvider) {
      myOptionsProvider = provider;
 +    myProjectOptionsProvider = projectOptionsProvider;
 +
 +    myProjectSettingsPanel.setBorder(IdeBorderFactory.createTitledBorder("Project settings"));
 +    myGlobalSettingsPanel.setBorder(IdeBorderFactory.createTitledBorder("Application settings"));
  
      FileChooserDescriptor fileChooserDescriptor = new FileChooserDescriptor(true, false, false, false, false, false);
  
             || (myCopyOnSelectionCheckBox.isSelected() != myOptionsProvider.copyOnSelection())
             || (myPasteOnMiddleButtonCheckBox.isSelected() != myOptionsProvider.pasteOnMiddleMouseButton())
             || (myOverrideIdeShortcuts.isSelected() != myOptionsProvider.overrideIdeShortcuts())
-            myConfigurables.stream().anyMatch(c -> c.isModified());
 +           || (myShellIntegration.isSelected() != myOptionsProvider.shellIntegration())
 +           || (myHighlightHyperlinks.isSelected() != myOptionsProvider.highlightHyperlinks()) ||
 -           || (myEnvVarField.isPassParentEnvs() != myOptionsProvider.passParentEnvs())
 -      ;
++           myConfigurables.stream().anyMatch(c -> c.isModified())
+            || !Comparing.equal(myEnvVarField.getEnvs(), myOptionsProvider.getUserSpecifiedEnvs())
++           || (myEnvVarField.isPassParentEnvs() != myOptionsProvider.passParentEnvs());
    }
  
    public void apply() {
      myOptionsProvider.setCopyOnSelection(myCopyOnSelectionCheckBox.isSelected());
      myOptionsProvider.setPasteOnMiddleMouseButton(myPasteOnMiddleButtonCheckBox.isSelected());
      myOptionsProvider.setOverrideIdeShortcuts(myOverrideIdeShortcuts.isSelected());
 +    myOptionsProvider.setShellIntegration(myShellIntegration.isSelected());
 +    myOptionsProvider.setHighlightHyperlinks(myHighlightHyperlinks.isSelected());
 +    myConfigurables.forEach(c -> {
 +      try {
 +        c.apply();
 +      }
 +      catch (ConfigurationException e) {
 +        //pass
 +      }
 +    });
+     myOptionsProvider.setUserSpecifiedEnvs(myEnvVarField.getEnvs());
+     myOptionsProvider.setPassParentEnvs(myEnvVarField.isPassParentEnvs());
    }
  
    public void reset() {
      myCopyOnSelectionCheckBox.setSelected(myOptionsProvider.copyOnSelection());
      myPasteOnMiddleButtonCheckBox.setSelected(myOptionsProvider.pasteOnMiddleMouseButton());
      myOverrideIdeShortcuts.setSelected(myOptionsProvider.overrideIdeShortcuts());
 +    myShellIntegration.setSelected(myOptionsProvider.shellIntegration());
 +    myHighlightHyperlinks.setSelected(myOptionsProvider.highlightHyperlinks());
 +    myConfigurables.forEach(c -> c.reset());
+     myEnvVarField.setEnvs(myOptionsProvider.getUserSpecifiedEnvs());
+     myEnvVarField.setPassParentEnvs(myOptionsProvider.passParentEnvs());
    }
 +
 +  public Color getDefaultValueColor() {
 +    return findColorByKey("TextField.inactiveForeground", "nimbusDisabledText");
 +  }
 +
 +  @NotNull
 +  private static Color findColorByKey(String... colorKeys) {
 +    Color c = null;
 +    for (String key : colorKeys) {
 +      c = UIManager.getColor(key);
 +      if (c != null) {
 +        break;
 +      }
 +    }
 +
 +    assert c != null : "Can't find color for keys " + Arrays.toString(colorKeys);
 +    return c;
 +  }
 +
 +  public Color getChangedValueColor() {
 +    return findColorByKey("TextField.foreground");
 +  }
  }