2 * Copyright 2000-2016 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.jetbrains.python.sdk
18 import com.intellij.openapi.module.ModuleManager
19 import com.intellij.openapi.project.Project
20 import com.intellij.openapi.projectRoots.Sdk
21 import com.intellij.openapi.util.SystemInfo
22 import com.jetbrains.python.run.PyVirtualEnvReader
23 import com.jetbrains.python.run.findActivateScript
24 import org.jetbrains.plugins.terminal.LocalTerminalCustomizer
31 class PyVirtualEnvTerminalCustomizer : LocalTerminalCustomizer() {
34 override fun customizeCommandAndEnvironment(project: Project,
35 command: Array<out String>,
36 envs: MutableMap<String, String>): Array<out String> {
37 val sdk: Sdk? = findSdk(project)
39 if (sdk != null && PythonSdkType.isVirtualEnv(sdk)) {
40 // in case of virtualenv sdk on unix we activate virtualenv
41 val path = sdk.homePath
45 val shellPath = command[0]
46 val shellName = File(shellPath).name
48 if (shellName == "bash" || (SystemInfo.isMac && shellName == "sh") || (shellName == "zsh")) {
49 //for bash we pass activate script to jediterm shell integration (see jediterm-bash.in) to source it there
50 findActivateScript(path, shellPath)?.let { activate -> envs.put("JEDITERM_SOURCE", activate) }
53 //for other shells we read envs from activate script by the default shell and pass them to the process
54 val reader = PyVirtualEnvReader(path)
55 reader.activate?.let {
56 envs.putAll(reader.readShellEnv().filterKeys { k -> k in arrayOf("PATH", "PS1", "VIRTUAL_ENV", "PYTHONHOME") })
63 // for some reason virtualenv isn't activated in the rcfile for the login shell, so we make it non-login
64 return command.filter { arg -> arg != "--login" && arg != "-l"}.toTypedArray()
68 private fun findSdk(project: Project): Sdk? {
69 for (m in ModuleManager.getInstance(project).modules) {
70 val sdk: Sdk? = PythonSdkType.findPythonSdk(m)
71 if (sdk != null && !PythonSdkType.isRemote(sdk)) {
80 override fun getDefaultFolder(): String? {