diff --git a/python/ide/src/com/jetbrains/python/PyIdeCommonOptionsForm.java b/python/ide/src/com/jetbrains/python/PyIdeCommonOptionsForm.java index 2636aa50c66f..8f633e359038 100644 --- a/python/ide/src/com/jetbrains/python/PyIdeCommonOptionsForm.java +++ b/python/ide/src/com/jetbrains/python/PyIdeCommonOptionsForm.java @@ -224,7 +224,7 @@ public class PyIdeCommonOptionsForm implements AbstractPyCommonOptionsForm { } public void updateSdkList(boolean preserveSelection, PyConfigurableInterpreterList myInterpreterList) { - myPythonSdks = myInterpreterList.getAllPythonSdks(); + myPythonSdks = myInterpreterList.getAllPythonSdks(myProject); Sdk selection = preserveSelection ? (Sdk)myInterpreterComboBox.getSelectedItem() : null; if (!myPythonSdks.contains(selection)) { selection = null; diff --git a/python/ide/src/com/jetbrains/python/configuration/PyActiveSdkConfigurable.java b/python/ide/src/com/jetbrains/python/configuration/PyActiveSdkConfigurable.java index 917dec969476..de63179c64d5 100644 --- a/python/ide/src/com/jetbrains/python/configuration/PyActiveSdkConfigurable.java +++ b/python/ide/src/com/jetbrains/python/configuration/PyActiveSdkConfigurable.java @@ -16,6 +16,7 @@ package com.jetbrains.python.configuration; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.EditorFactory; import com.intellij.openapi.editor.ex.EditorEx; @@ -27,12 +28,14 @@ import com.intellij.openapi.options.UnnamedConfigurable; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.SdkModel; +import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil; import com.intellij.openapi.projectRoots.impl.SdkListCellRenderer; import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.ModuleRootModificationUtil; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel; import com.intellij.openapi.ui.ComboBox; +import com.intellij.openapi.ui.DialogBuilder; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.ui.CollectionComboBoxModel; import com.intellij.ui.awt.RelativePoint; @@ -42,8 +45,7 @@ import com.intellij.webcore.packaging.PackagesNotificationPanel; import com.jetbrains.python.packaging.ui.PyInstalledPackagesPanel; import com.jetbrains.python.packaging.ui.PyPackageManagementService; import com.jetbrains.python.psi.LanguageLevel; -import com.jetbrains.python.sdk.DetailsChooser; -import com.jetbrains.python.sdk.PySdkListCellRenderer; +import com.jetbrains.python.sdk.*; import com.jetbrains.python.sdk.flavors.PythonSdkFlavor; import icons.PythonIcons; import org.jetbrains.annotations.NotNull; @@ -53,6 +55,7 @@ import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.util.ArrayList; import java.util.List; public class PyActiveSdkConfigurable implements UnnamedConfigurable { @@ -66,6 +69,7 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable { private ComboBox mySdkCombo; private PyInstalledPackagesPanel myPackagesPanel; private JButton myDetailsButton; + private static final String SHOW_ALL = "Show All"; public PyActiveSdkConfigurable(@NotNull Project project) { myModule = null; @@ -101,7 +105,7 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable { myDetailsButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - DetailsChooser.show(myProject, myProjectSdksModel.getSdks(), + DetailsChooser.show(myProject, myProjectSdksModel.getSdks(), new PythonSdkConfigurable(myProject).createComponent(), RelativePoint.fromScreen(myDetailsButton.getLocationOnScreen()), true, new NullableConsumer() { @Override @@ -114,8 +118,8 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable { myInterpreterList.setSelectedSdk(sdk); mySdkCombo.getModel().setSelectedItem(sdk); - myPackagesPanel - .updatePackages(new PyPackageManagementService(myProject, sdk)); + myPackagesPanel.updatePackages( + new PyPackageManagementService(myProject, sdk)); } } ); @@ -130,7 +134,22 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable { myPanel = new JPanel(layout); final JLabel label = new JLabel("Project Interpreter:"); final JLabel label1 = new JLabel(" "); - mySdkCombo = new ComboBox(); + mySdkCombo = new ComboBox() { + @Override + public void setSelectedItem(Object item) + { + if (SHOW_ALL.equals(item)) { + DialogBuilder dialog = new DialogBuilder(myProject); + dialog.setTitle("Python Interpreters"); + dialog.setCenterPanel(new PythonSdkConfigurable(myProject).createComponent()); + dialog.show(); + return; + } + if (!PySdkListCellRenderer.SEPARATOR.equals(item.toString())) + super.setSelectedItem(item); + } + }; + mySdkCombo.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE); mySdkCombo.setRenderer(new SdkListCellRenderer("")); PackagesNotificationPanel notificationsArea = new PackagesNotificationPanel(myProject); @@ -199,7 +218,8 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable { @Override public boolean isModified() { final Sdk sdk = getSdk(); - return sdk != myProjectSdksModel.findSdk((Sdk)mySdkCombo.getSelectedItem()); + final Sdk selectedItem = (Sdk)mySdkCombo.getSelectedItem(); + return selectedItem instanceof PyDetectedSdk || sdk != myProjectSdksModel.findSdk(selectedItem); } @Nullable @@ -213,8 +233,18 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable { @Override public void apply() throws ConfigurationException { + final Sdk item = (Sdk)mySdkCombo.getSelectedItem(); + if (item instanceof PyDetectedSdk) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + final Sdk sdk = SdkConfigurationUtil.createAndAddSDK(item.getName(), PythonSdkType.getInstance()); + SdkConfigurationUtil.setDirectoryProjectSdk(myProject, sdk); + } + }, ModalityState.any()); + } myProjectSdksModel.apply(); - final Sdk selectedSdk = myProjectSdksModel.findSdk((Sdk)mySdkCombo.getSelectedItem()); + final Sdk selectedSdk = myProjectSdksModel.findSdk(item); if (myModule == null) { final ProjectRootManager rootManager = ProjectRootManager.getInstance(myProject); ApplicationManager.getApplication().runWriteAction(new Runnable() { @@ -280,7 +310,7 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable { } private void updateSdkList(boolean preserveSelection) { - final List sdkList = myInterpreterList.getAllPythonSdks(); + final List sdkList = myInterpreterList.getAllPythonSdks(myProject); Sdk selection = preserveSelection ? (Sdk)mySdkCombo.getSelectedItem() : null; if (!sdkList.contains(selection)) { selection = null; @@ -290,9 +320,44 @@ public class PyActiveSdkConfigurable implements UnnamedConfigurable { if (selection != null && !sdkList.contains(selection)) { sdkList.add(0, selection); } - sdkList.add(0, null); + List items = new ArrayList(); + items.add(null); + + boolean remoteSeparator = true; + boolean separator = true; + boolean detectedSeparator = true; + boolean hasAssociationsWithDifferentProject = false; + final String projectBasePath = myProject.getBasePath(); + for (Sdk sdk : sdkList) { + if (!PythonSdkType.isVirtualEnv(sdk) && !PythonSdkType.isRemote(sdk) && + !(sdk instanceof PyDetectedSdk) && separator) { + items.add(PySdkListCellRenderer.SEPARATOR); + separator = false; + } + if (PythonSdkType.isRemote(sdk) && remoteSeparator) { + items.add(PySdkListCellRenderer.SEPARATOR); + remoteSeparator = false; + } + if (sdk instanceof PyDetectedSdk && detectedSeparator) { + items.add(PySdkListCellRenderer.SEPARATOR); + detectedSeparator = false; + } + items.add(sdk); + + final PythonSdkAdditionalData data = (PythonSdkAdditionalData)sdk.getSdkAdditionalData(); + if (data != null) { + final String path = data.getAssociatedProjectPath(); + if (path != null && !path.equals(projectBasePath)) hasAssociationsWithDifferentProject = true; + } + } + + if (hasAssociationsWithDifferentProject) { + items.add(PySdkListCellRenderer.SEPARATOR); + items.add(SHOW_ALL); + } + mySdkCombo.setRenderer(new PySdkListCellRenderer()); - mySdkCombo.setModel(new CollectionComboBoxModel(sdkList, selection)); + mySdkCombo.setModel(new CollectionComboBoxModel(items, selection)); } @Override diff --git a/python/ide/src/com/jetbrains/python/configuration/PyConfigurableInterpreterList.java b/python/ide/src/com/jetbrains/python/configuration/PyConfigurableInterpreterList.java index fbe1d0dd8d35..f06d751d3596 100644 --- a/python/ide/src/com/jetbrains/python/configuration/PyConfigurableInterpreterList.java +++ b/python/ide/src/com/jetbrains/python/configuration/PyConfigurableInterpreterList.java @@ -18,15 +18,18 @@ package com.jetbrains.python.configuration; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil; import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectSdksModel; import com.intellij.openapi.util.Comparing; +import com.jetbrains.python.psi.LanguageLevel; +import com.jetbrains.python.sdk.PyDetectedSdk; +import com.jetbrains.python.sdk.PySdkUtil; +import com.jetbrains.python.sdk.PythonSdkAdditionalData; import com.jetbrains.python.sdk.PythonSdkType; +import com.jetbrains.python.sdk.flavors.PythonSdkFlavor; import javax.swing.*; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; +import java.util.*; /** * Manages the SDK model shared between PythonSdkConfigurable and PyActiveSdkConfigurable. @@ -65,19 +68,66 @@ public class PyConfigurableInterpreterList { } } - public List getAllPythonSdks() { + public List getAllPythonSdks(final Project project) { List result = new ArrayList(); for (Sdk sdk : getModel().getSdks()) { if (sdk.getSdkType() instanceof PythonSdkType) { result.add(sdk); } } + Collection sdkHomes = PythonSdkType.getInstance().suggestHomePaths(); + Collections.sort(result, new Comparator() { @Override public int compare(Sdk o1, Sdk o2) { + if (!(o1.getSdkType() instanceof PythonSdkType) || + !(o2.getSdkType() instanceof PythonSdkType)) + return -Comparing.compare(o1.getName(), o2.getName()); + + final boolean isVEnv1 = PythonSdkType.isVirtualEnv(o1); + final boolean isVEnv2 = PythonSdkType.isVirtualEnv(o2); + final boolean isRemote1 = PySdkUtil.isRemote(o1); + final boolean isRemote2 = PySdkUtil.isRemote(o2); + final PythonSdkFlavor flavor1 = PythonSdkFlavor.getFlavor(o1); + final PythonSdkFlavor flavor2 = PythonSdkFlavor.getFlavor(o2); + final LanguageLevel level1 = flavor1 != null ? flavor1.getLanguageLevel(o1) : LanguageLevel.getDefault(); + final LanguageLevel level2 = flavor2 != null ? flavor2.getLanguageLevel(o2) : LanguageLevel.getDefault(); + + if (isVEnv1) { + if (associatedWithCurrent(o1, project)) return -1; + if (isVEnv2) { + final int compare = Comparing.compare(level1, level2); + if (compare != 0) return -compare; + return Comparing.compare(o1.getName(), o2.getName()); + } + return -1; + } + if (isVEnv2) { + return 1; + } + if (isRemote1) return 1; + if (isRemote2) return -1; + + final int compare = Comparing.compare(level1, level2); + if (compare != 0) return -compare; return Comparing.compare(o1.getName(), o2.getName()); } }); + for (String sdkHome : SdkConfigurationUtil.filterExistingPaths(PythonSdkType.getInstance(), sdkHomes, getModel().getSdks())) { + result.add(new PyDetectedSdk(sdkHome, PythonSdkType.getInstance())); + } return result; } + + private static boolean associatedWithCurrent(Sdk o1, Project project) { + final PythonSdkAdditionalData data = (PythonSdkAdditionalData)o1.getSdkAdditionalData(); + if (data != null) { + final String path = data.getAssociatedProjectPath(); + final String projectBasePath = project.getBasePath(); + if (path != null && path.equals(projectBasePath)) { + return true; + } + } + return false; + } } diff --git a/python/ide/src/com/jetbrains/python/configuration/PythonSdkConfigurable.java b/python/ide/src/com/jetbrains/python/configuration/PythonSdkConfigurable.java index 8f5233712aac..baf335dc10fa 100644 --- a/python/ide/src/com/jetbrains/python/configuration/PythonSdkConfigurable.java +++ b/python/ide/src/com/jetbrains/python/configuration/PythonSdkConfigurable.java @@ -247,7 +247,7 @@ public class PythonSdkConfigurable implements Configurable, Configurable.NoScrol addCreatedSdk(sdk, true); } }; - final List allSdks = PyConfigurableInterpreterList.getInstance(myProject).getAllPythonSdks(); + final List allSdks = PyConfigurableInterpreterList.getInstance(myProject).getAllPythonSdks(myProject); final CreateVirtualEnvDialog dialog = new CreateVirtualEnvDialog(myProject, myNewProject, allSdks, sdk); dialog.show(); if (dialog.isOK()) { @@ -335,7 +335,7 @@ public class PythonSdkConfigurable implements Configurable, Configurable.NoScrol } private void refreshSdkList() { - final List pythonSdks = myInterpreterList.getAllPythonSdks(); + final List pythonSdks = myInterpreterList.getAllPythonSdks(myProject); Sdk projectSdk = myProjectSdksModel.getProjectSdk(); if (!myShowOtherProjectVirtualenvs) { VirtualEnvProjectFilter.removeNotMatching(myProject, pythonSdks); @@ -366,7 +366,7 @@ public class PythonSdkConfigurable implements Configurable, Configurable.NoScrol private void addSdk(AnActionButton button) { DetailsChooser - .show(myProject, myProjectSdksModel.getSdks(), button.getPreferredPopupPoint(), false, new NullableConsumer() { + .show(myProject, myProjectSdksModel.getSdks(), new PythonSdkConfigurable(myProject).createComponent(), button.getPreferredPopupPoint(), false, new NullableConsumer() { @Override public void consume(Sdk sdk) { myMakeActiveAdded = false; diff --git a/python/src/com/jetbrains/python/sdk/DetailsChooser.java b/python/src/com/jetbrains/python/sdk/DetailsChooser.java index 46e4adaa8a3c..10dd82f7360f 100644 --- a/python/src/com/jetbrains/python/sdk/DetailsChooser.java +++ b/python/src/com/jetbrains/python/sdk/DetailsChooser.java @@ -22,6 +22,7 @@ import com.intellij.openapi.options.ShowSettingsUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.impl.SdkConfigurationUtil; +import com.intellij.openapi.ui.DialogBuilder; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.popup.*; import com.intellij.openapi.ui.popup.util.BaseListPopupStep; @@ -30,6 +31,7 @@ import com.intellij.util.NullableConsumer; import com.jetbrains.python.remote.PythonRemoteInterpreterManager; import org.jetbrains.annotations.Nullable; +import javax.swing.*; import java.awt.*; import java.util.ArrayList; import java.util.Arrays; @@ -39,6 +41,7 @@ import java.util.List; * @author yole */ public class DetailsChooser extends BaseListPopupStep { + private static JComponent myMore; private final Project myProject; private final Component myOwnerComponent; private final Sdk[] myExistingSdks; @@ -51,9 +54,10 @@ public class DetailsChooser extends BaseListPopupStep { public static void show(final Project project, final Sdk[] existingSdks, - final RelativePoint popupPoint, + JComponent component, final RelativePoint popupPoint, final boolean showMore, final NullableConsumer callback) { + myMore = component; final ListPopupStep sdkHomesStep = new DetailsChooser(project, popupPoint.getComponent(), existingSdks, showMore, callback); final ListPopup popup = JBPopupFactory.getInstance().createListPopup(sdkHomesStep); popup.show(popupPoint); @@ -102,7 +106,10 @@ public class DetailsChooser extends BaseListPopupStep { createVirtualEnvSdk(); } else { - //createSdkFromPath(selectedValue); + DialogBuilder dialog = new DialogBuilder(myProject); + dialog.setTitle("Python Interpreters"); + dialog.setCenterPanel(myMore); + dialog.show(); } } diff --git a/python/src/com/jetbrains/python/sdk/PyDetectedSdk.java b/python/src/com/jetbrains/python/sdk/PyDetectedSdk.java new file mode 100644 index 000000000000..7abc06d68caf --- /dev/null +++ b/python/src/com/jetbrains/python/sdk/PyDetectedSdk.java @@ -0,0 +1,11 @@ +package com.jetbrains.python.sdk; + +import com.intellij.openapi.projectRoots.SdkTypeId; +import com.intellij.openapi.projectRoots.impl.ProjectJdkImpl; + +public class PyDetectedSdk extends ProjectJdkImpl { + public PyDetectedSdk(String name, SdkTypeId sdkType) { + super(name, sdkType); + } + +} diff --git a/python/src/com/jetbrains/python/sdk/PySdkListCellRenderer.java b/python/src/com/jetbrains/python/sdk/PySdkListCellRenderer.java index 9065d371bd94..988622484b97 100644 --- a/python/src/com/jetbrains/python/sdk/PySdkListCellRenderer.java +++ b/python/src/com/jetbrains/python/sdk/PySdkListCellRenderer.java @@ -19,6 +19,7 @@ import com.intellij.icons.AllIcons; import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.SdkModificator; import com.intellij.openapi.projectRoots.SdkType; +import com.intellij.openapi.util.IconLoader; import com.intellij.ui.LayeredIcon; import com.intellij.ui.ListCellRendererWrapper; import com.jetbrains.python.sdk.flavors.PythonSdkFlavor; @@ -27,9 +28,10 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.util.Map; -public class PySdkListCellRenderer extends ListCellRendererWrapper { +public class PySdkListCellRenderer extends ListCellRendererWrapper { private final String myNullText; private final Map mySdkModifiers; + public static final String SEPARATOR = "separator"; public PySdkListCellRenderer() { myNullText = ""; @@ -42,8 +44,9 @@ public class PySdkListCellRenderer extends ListCellRendererWrapper { } @Override - public void customize(JList list, Sdk sdk, int index, boolean selected, boolean hasFocus) { - if (sdk != null) { + public void customize(JList list, Object item, int index, boolean selected, boolean hasFocus) { + if (item instanceof Sdk) { + Sdk sdk = (Sdk)item; final PythonSdkFlavor flavor = PythonSdkFlavor.getPlatformIndependentFlavor(sdk.getHomePath()); final Icon icon = flavor != null ? flavor.getIcon() : ((SdkType)sdk.getSdkType()).getIcon(); @@ -54,7 +57,6 @@ public class PySdkListCellRenderer extends ListCellRendererWrapper { else { name = sdk.getName(); } - if (PythonSdkType.isInvalid(sdk)) { setText("[invalid] " + name); setIcon(wrapIconWithWarningDecorator(icon)); @@ -63,17 +65,22 @@ public class PySdkListCellRenderer extends ListCellRendererWrapper { setText("[incomplete] " + name); setIcon(wrapIconWithWarningDecorator(icon)); } + else if (sdk instanceof PyDetectedSdk){ + setText(name); + setIcon(IconLoader.getTransparentIcon(icon)); + } else { setText(name); setIcon(icon); } } - else { + else if (SEPARATOR.equals(item)) + setSeparator(); + else if (item == null) setText(myNullText); - } } - private LayeredIcon wrapIconWithWarningDecorator(Icon icon) { + private static LayeredIcon wrapIconWithWarningDecorator(Icon icon) { final LayeredIcon layered = new LayeredIcon(2); layered.setIcon(icon, 0); // TODO: Create a separate invalid SDK overlay icon (DSGN-497) diff --git a/python/src/com/jetbrains/python/sdk/PythonSdkType.java b/python/src/com/jetbrains/python/sdk/PythonSdkType.java index d0d910d3b4bb..e3bd6e95927e 100644 --- a/python/src/com/jetbrains/python/sdk/PythonSdkType.java +++ b/python/src/com/jetbrains/python/sdk/PythonSdkType.java @@ -277,7 +277,7 @@ public class PythonSdkType extends SdkType { public void showCustomCreateUI(SdkModel sdkModel, final JComponent parentComponent, final Consumer sdkCreatedCallback) { Project project = CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(parentComponent)); - DetailsChooser.show(project, sdkModel.getSdks(), RelativePoint.getCenterOf(parentComponent), true, new NullableConsumer() { + DetailsChooser.show(project, sdkModel.getSdks(), null, RelativePoint.getCenterOf(parentComponent), true, new NullableConsumer() { @Override public void consume(@Nullable Sdk sdk) { if (sdk != null) { diff --git a/python/src/com/jetbrains/python/sdk/flavors/MacPythonSdkFlavor.java b/python/src/com/jetbrains/python/sdk/flavors/MacPythonSdkFlavor.java index 780effe67dcb..5d241b668166 100644 --- a/python/src/com/jetbrains/python/sdk/flavors/MacPythonSdkFlavor.java +++ b/python/src/com/jetbrains/python/sdk/flavors/MacPythonSdkFlavor.java @@ -16,6 +16,7 @@ package com.jetbrains.python.sdk.flavors; import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VFileProperty; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.newvfs.NewVirtualFile; @@ -57,7 +58,7 @@ public class MacPythonSdkFlavor extends CPythonSdkFlavor { if (binDir != null && binDir.isDirectory()) { for (String name : POSSIBLE_BINARY_NAMES) { final VirtualFile child = binDir.findChild(name); - if (child != null) { + if (child != null && !child.is(VFileProperty.SYMLINK)) { candidates.add(child.getPath()); break; } diff --git a/python/src/com/jetbrains/python/sdk/flavors/UnixPythonSdkFlavor.java b/python/src/com/jetbrains/python/sdk/flavors/UnixPythonSdkFlavor.java index c28587c36ecc..2440661877ff 100644 --- a/python/src/com/jetbrains/python/sdk/flavors/UnixPythonSdkFlavor.java +++ b/python/src/com/jetbrains/python/sdk/flavors/UnixPythonSdkFlavor.java @@ -16,6 +16,7 @@ package com.jetbrains.python.sdk.flavors; import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VFileProperty; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.newvfs.NewVirtualFile; @@ -47,14 +48,15 @@ public class UnixPythonSdkFlavor extends CPythonSdkFlavor { if (rootDir instanceof NewVirtualFile) { ((NewVirtualFile)rootDir).markDirty(); } - rootDir.refresh(false, false); + rootDir.refresh(true, false); VirtualFile[] suspects = rootDir.getChildren(); for (VirtualFile child : suspects) { if (!child.isDirectory()) { final String childName = child.getName(); for (String name : NAMES) { if (childName.startsWith(name)) { - if (!childName.endsWith("-config") && !childName.startsWith("pythonw")) { + if (!childName.endsWith("-config") && !childName.startsWith("pythonw") && + !childName.endsWith("m") && !child.is(VFileProperty.SYMLINK)) { candidates.add(child.getPath()); } break; diff --git a/python/src/com/jetbrains/python/sdk/flavors/VirtualEnvSdkFlavor.java b/python/src/com/jetbrains/python/sdk/flavors/VirtualEnvSdkFlavor.java index 5bdecd7a521c..b9de2e2c9003 100644 --- a/python/src/com/jetbrains/python/sdk/flavors/VirtualEnvSdkFlavor.java +++ b/python/src/com/jetbrains/python/sdk/flavors/VirtualEnvSdkFlavor.java @@ -83,7 +83,7 @@ public class VirtualEnvSdkFlavor extends CPythonSdkFlavor { public static Collection findInDirectory(VirtualFile rootDir) { List candidates = new ArrayList(); if (rootDir != null) { - rootDir.refresh(false, false); + rootDir.refresh(true, false); VirtualFile[] suspects = rootDir.getChildren(); for (VirtualFile child : suspects) { if (child.isDirectory()) {