mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-04 08:51:02 +07:00
Auto activate of virtualenv in terminal for projects with Python Virtualenv interpreters (PY-10498)
This commit is contained in:
21
python/python-terminal/python-terminal.iml
Normal file
21
python/python-terminal/python-terminal.iml
Normal file
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module 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$/test" isTestSource="true" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="python-community" />
|
||||
<orderEntry type="module" module-name="terminal" />
|
||||
<orderEntry type="library" scope="TEST" name="JUnit4" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="mockito" level="project" />
|
||||
<orderEntry type="module" module-name="core-api" />
|
||||
<orderEntry type="module" module-name="projectModel-api" />
|
||||
<orderEntry type="library" name="KotlinJavaRuntime" level="project" />
|
||||
<orderEntry type="module" module-name="lang-api" />
|
||||
</component>
|
||||
</module>
|
||||
11
python/python-terminal/resources/META-INF/plugin.xml
Normal file
11
python/python-terminal/resources/META-INF/plugin.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<idea-plugin version="2" xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
<name>Python Terminal</name>
|
||||
<id>org.jetbrains.plugins.python-terminal</id>
|
||||
<version>VERSION</version>
|
||||
<vendor>JetBrains</vendor>
|
||||
|
||||
<depends>com.intellij.modules.python</depends>
|
||||
|
||||
<xi:include href="/META-INF/python-terminal-plugin.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
|
||||
</idea-plugin>
|
||||
@@ -0,0 +1,7 @@
|
||||
<idea-plugin version="2">
|
||||
<extensions defaultExtensionNs="org.jetbrains.plugins.terminal">
|
||||
<localTerminalCustomizer implementation="com.jetbrains.python.sdk.PyVirtualEnvTerminalCustomizer"/>
|
||||
</extensions>
|
||||
|
||||
|
||||
</idea-plugin>
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.
|
||||
*/
|
||||
package com.jetbrains.python.sdk
|
||||
|
||||
import com.intellij.openapi.module.ModuleManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.util.SystemInfo
|
||||
import com.intellij.util.EnvironmentUtil
|
||||
import com.jetbrains.python.sdk.flavors.PythonSdkFlavor
|
||||
import com.jetbrains.python.sdk.flavors.VirtualEnvSdkFlavor
|
||||
import org.jetbrains.plugins.terminal.LocalTerminalCustomizer
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* @author traff
|
||||
*/
|
||||
|
||||
class PyVirtualEnvTerminalCustomizer : LocalTerminalCustomizer() {
|
||||
|
||||
|
||||
override fun customizeCommandAndEnvironment(project: Project,
|
||||
command: Array<out String>,
|
||||
envs: MutableMap<String, String>): Array<out String> {
|
||||
val sdk: Sdk? = findSdk(project)
|
||||
|
||||
if (sdk != null && PythonSdkType.isVirtualEnv(sdk) && SystemInfo.isUnix) {
|
||||
// in case of virtualenv sdk on unix we activate virtualenv
|
||||
val path = sdk.homePath
|
||||
|
||||
if (path != null) {
|
||||
|
||||
val shellPath = command[0]
|
||||
val shellName = File(shellPath).name
|
||||
|
||||
if (shellName == "bash" || shellName == "sh") {
|
||||
//for bash and sh we pass activate script to jediterm shell integration (see jediterm-sh.in)
|
||||
findActivateScript(path, shellPath)?.let { activate -> envs.put("JEDITERM_SOURCE", activate) }
|
||||
}
|
||||
else {
|
||||
//for other shells we read envs from activate script by the default shell and pass it to the process
|
||||
val pyVirtualEnvReader = PyVirtualEnvReader(path)
|
||||
pyVirtualEnvReader.activate?.let { envs.putAll(pyVirtualEnvReader.readShellEnv()) }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// for some reason virtualenv isn't activated in the rcfile for the login shell, so we make it non-login
|
||||
return command.filter { arg -> arg != "--login" }.toTypedArray()
|
||||
}
|
||||
|
||||
|
||||
private fun findSdk(project: Project): Sdk? {
|
||||
for (m in ModuleManager.getInstance(project).modules) {
|
||||
val sdk: Sdk? = PythonSdkType.findPythonSdk(m)
|
||||
if (sdk != null && !PythonSdkType.isRemote(sdk)) {
|
||||
return sdk
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
override fun getDefaultFolder(): String? {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
class PyVirtualEnvReader(virtualEnvSdkPath: String) : EnvironmentUtil.ShellEnvReader() {
|
||||
val activate = findActivateScript(virtualEnvSdkPath, shell)
|
||||
|
||||
override fun getShellProcessCommand(): MutableList<String>? {
|
||||
|
||||
return if (activate != null) mutableListOf(shell, "--rcfile", activate, "-i")
|
||||
else super.getShellProcessCommand()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun findActivateScript(path: String?, shellPath: String): String? {
|
||||
val shellName = File(shellPath).name
|
||||
val activate = if (shellName == "fish" || shellName == "csh") File(File(path).parentFile, "activate." + shellName)
|
||||
else File(File(path).parentFile, "activate")
|
||||
|
||||
return if (activate.exists()) activate.absolutePath else null
|
||||
}
|
||||
Reference in New Issue
Block a user