Clickable links for remote files in console (PY-10224).

This commit is contained in:
Dmitry Trofimov
2014-07-31 19:18:17 +02:00
parent d445ba2acb
commit eb4e0bb7ab
8 changed files with 87 additions and 34 deletions

View File

@@ -19,7 +19,6 @@ import com.intellij.execution.ExecutionException;
import com.intellij.execution.configurations.GeneralCommandLine; import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.configurations.ParametersList; import com.intellij.execution.configurations.ParametersList;
import com.intellij.execution.configurations.ParamsGroup; import com.intellij.execution.configurations.ParamsGroup;
import com.intellij.execution.filters.Filter;
import com.intellij.execution.process.ProcessAdapter; import com.intellij.execution.process.ProcessAdapter;
import com.intellij.execution.process.ProcessEvent; import com.intellij.execution.process.ProcessEvent;
import com.intellij.execution.process.ProcessHandler; import com.intellij.execution.process.ProcessHandler;
@@ -33,7 +32,6 @@ import com.jetbrains.python.run.PythonProcessRunner;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import javax.swing.*; import javax.swing.*;
import java.util.Collections;
/** /**
* User : catherine * User : catherine
@@ -43,7 +41,7 @@ public abstract class RestCommandLineState extends PythonCommandLineState {
public RestCommandLineState(RestRunConfiguration configuration, public RestCommandLineState(RestRunConfiguration configuration,
ExecutionEnvironment env) { ExecutionEnvironment env) {
super(configuration, env, Collections.<Filter>emptyList()); super(configuration, env);
myConfiguration = configuration; myConfiguration = configuration;
} }

View File

@@ -0,0 +1,52 @@
/*
* Copyright 2000-2014 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.run;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.remote.RemoteProcessHandlerBase;
import com.intellij.util.PathMappingSettings;
import org.jetbrains.annotations.Nullable;
/**
* @author traff
*/
public class PyRemoteTracebackFilter extends PythonTracebackFilter {
private final RemoteProcessHandlerBase myHandler;
public PyRemoteTracebackFilter(Project project, RemoteProcessHandlerBase remoteProcessHandler) {
super(project);
myHandler = remoteProcessHandler;
}
@Override
@Nullable
protected VirtualFile findFileByName(String fileName) {
for (PathMappingSettings.PathMapping m : myHandler.getMappingSettings().getPathMappings()) {
if (m.canReplaceRemote(fileName)) {
VirtualFile file = LocalFileSystem.getInstance().findFileByPath(m.mapToLocal(fileName));
if (file != null && file.exists()) {
return file;
}
}
}
return null;
}
}

View File

@@ -47,6 +47,7 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.JarFileSystem; import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.remote.RemoteProcessHandlerBase;
import com.intellij.util.PlatformUtils; import com.intellij.util.PlatformUtils;
import com.intellij.util.containers.HashMap; import com.intellij.util.containers.HashMap;
import com.jetbrains.python.PythonHelpersLocator; import com.jetbrains.python.PythonHelpersLocator;
@@ -80,7 +81,9 @@ public abstract class PythonCommandLineState extends CommandLineState {
public static final String GROUP_DEBUGGER = "Debugger"; public static final String GROUP_DEBUGGER = "Debugger";
public static final String GROUP_SCRIPT = "Script"; public static final String GROUP_SCRIPT = "Script";
private final AbstractPythonRunConfiguration myConfig; private final AbstractPythonRunConfiguration myConfig;
private final List<Filter> myFilters;
private final List<Filter> myFilters = Lists.<Filter>newArrayList(new UrlFilter());
private Boolean myMultiprocessDebug = null; private Boolean myMultiprocessDebug = null;
public boolean isDebug() { public boolean isDebug() {
@@ -99,15 +102,9 @@ public abstract class PythonCommandLineState extends CommandLineState {
return serverSocket; return serverSocket;
} }
public PythonCommandLineState(AbstractPythonRunConfiguration runConfiguration, ExecutionEnvironment env, List<Filter> filters) { public PythonCommandLineState(AbstractPythonRunConfiguration runConfiguration, ExecutionEnvironment env) {
super(env); super(env);
myConfig = runConfiguration; myConfig = runConfiguration;
myFilters = Lists.newArrayList(filters);
addDefaultFilters();
}
protected void addDefaultFilters() {
myFilters.add(new UrlFilter());
} }
@Nullable @Nullable
@@ -134,10 +131,23 @@ public abstract class PythonCommandLineState extends CommandLineState {
protected ConsoleView createAndAttachConsole(Project project, ProcessHandler processHandler, Executor executor) protected ConsoleView createAndAttachConsole(Project project, ProcessHandler processHandler, Executor executor)
throws ExecutionException { throws ExecutionException {
final ConsoleView consoleView = createConsoleBuilder(project).filters(myFilters).getConsole(); final ConsoleView consoleView = createConsoleBuilder(project).filters(myFilters).getConsole();
addTracebackFilter(project, consoleView, processHandler);
consoleView.attachToProcess(processHandler); consoleView.attachToProcess(processHandler);
return consoleView; return consoleView;
} }
protected void addTracebackFilter(Project project, ConsoleView consoleView, ProcessHandler processHandler) {
if (PySdkUtil.isRemote(myConfig.getSdk())) {
assert processHandler instanceof RemoteProcessHandlerBase;
consoleView.addMessageFilter(new PyRemoteTracebackFilter(project, (RemoteProcessHandlerBase) processHandler));
}
else {
consoleView.addMessageFilter(new PythonTracebackFilter(project, myConfig.getWorkingDirectory()));
}
}
private TextConsoleBuilder createConsoleBuilder(Project project) { private TextConsoleBuilder createConsoleBuilder(Project project) {
if (isDebug()) { if (isDebug()) {
return new PyDebugConsoleBuilder(project, PythonSdkType.findSdkByPath(myConfig.getInterpreterPath())); return new PyDebugConsoleBuilder(project, PythonSdkType.findSdkByPath(myConfig.getInterpreterPath()));

View File

@@ -15,11 +15,9 @@
*/ */
package com.jetbrains.python.run; package com.jetbrains.python.run;
import com.google.common.collect.Lists;
import com.intellij.execution.ExecutionException; import com.intellij.execution.ExecutionException;
import com.intellij.execution.Executor; import com.intellij.execution.Executor;
import com.intellij.execution.configurations.*; import com.intellij.execution.configurations.*;
import com.intellij.execution.filters.Filter;
import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.openapi.components.PathMacroManager; import com.intellij.openapi.components.PathMacroManager;
import com.intellij.openapi.options.SettingsEditor; import com.intellij.openapi.options.SettingsEditor;
@@ -40,7 +38,6 @@ import org.jdom.Element;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.io.File; import java.io.File;
import java.util.List;
/** /**
* @author yole * @author yole
@@ -64,10 +61,7 @@ public class PythonRunConfiguration extends AbstractPythonRunConfiguration
} }
public RunProfileState getState(@NotNull final Executor executor, @NotNull final ExecutionEnvironment env) throws ExecutionException { public RunProfileState getState(@NotNull final Executor executor, @NotNull final ExecutionEnvironment env) throws ExecutionException {
List<Filter> filters = Lists.newArrayList(); return new PythonScriptCommandLineState(this, env);
filters.add(new PythonTracebackFilter(getProject(), getWorkingDirectory()));
return new PythonScriptCommandLineState(this, env, filters);
} }
public void checkConfiguration() throws RuntimeConfigurationException { public void checkConfiguration() throws RuntimeConfigurationException {

View File

@@ -18,20 +18,17 @@ package com.jetbrains.python.run;
import com.intellij.execution.configurations.GeneralCommandLine; import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.configurations.ParametersList; import com.intellij.execution.configurations.ParametersList;
import com.intellij.execution.configurations.ParamsGroup; import com.intellij.execution.configurations.ParamsGroup;
import com.intellij.execution.filters.Filter;
import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.util.text.StringUtil;
import java.util.List;
/** /**
* @author yole * @author yole
*/ */
public class PythonScriptCommandLineState extends PythonCommandLineState { public class PythonScriptCommandLineState extends PythonCommandLineState {
private final PythonRunConfiguration myConfig; private final PythonRunConfiguration myConfig;
public PythonScriptCommandLineState(PythonRunConfiguration runConfiguration, ExecutionEnvironment env, List<Filter> filters) { public PythonScriptCommandLineState(PythonRunConfiguration runConfiguration, ExecutionEnvironment env) {
super(runConfiguration, env, filters); super(runConfiguration, env);
myConfig = runConfiguration; myConfig = runConfiguration;
} }

View File

@@ -51,10 +51,7 @@ public class PythonTracebackFilter implements Filter {
if (matcher.find()) { if (matcher.find()) {
String fileName = matcher.group(1).replace('\\', '/'); String fileName = matcher.group(1).replace('\\', '/');
int lineNumber = Integer.parseInt(matcher.group(2)); int lineNumber = Integer.parseInt(matcher.group(2));
VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fileName); VirtualFile vFile = findFileByName(fileName);
if (vFile == null && !StringUtil.isEmptyOrSpaces(myWorkingDirectory)) {
vFile = LocalFileSystem.getInstance().findFileByIoFile(new File(myWorkingDirectory, fileName));
}
if (vFile != null) { if (vFile != null) {
OpenFileHyperlinkInfo hyperlink = new OpenFileHyperlinkInfo(myProject, vFile, lineNumber - 1); OpenFileHyperlinkInfo hyperlink = new OpenFileHyperlinkInfo(myProject, vFile, lineNumber - 1);
@@ -66,4 +63,13 @@ public class PythonTracebackFilter implements Filter {
} }
return null; return null;
} }
@Nullable
protected VirtualFile findFileByName(String fileName) {
VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fileName);
if (vFile == null && !StringUtil.isEmptyOrSpaces(myWorkingDirectory)) {
vFile = LocalFileSystem.getInstance().findFileByIoFile(new File(myWorkingDirectory, fileName));
}
return vFile;
}
} }

View File

@@ -22,7 +22,6 @@ import com.intellij.execution.ExecutionResult;
import com.intellij.execution.Executor; import com.intellij.execution.Executor;
import com.intellij.execution.configurations.GeneralCommandLine; import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.execution.configurations.ParamsGroup; import com.intellij.execution.configurations.ParamsGroup;
import com.intellij.execution.filters.Filter;
import com.intellij.execution.process.ProcessHandler; import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.testframework.TestFrameworkRunningModel; import com.intellij.execution.testframework.TestFrameworkRunningModel;
@@ -42,12 +41,10 @@ import com.jetbrains.python.console.PythonDebugLanguageConsoleView;
import com.jetbrains.python.run.AbstractPythonRunConfiguration; import com.jetbrains.python.run.AbstractPythonRunConfiguration;
import com.jetbrains.python.run.CommandLinePatcher; import com.jetbrains.python.run.CommandLinePatcher;
import com.jetbrains.python.run.PythonCommandLineState; import com.jetbrains.python.run.PythonCommandLineState;
import com.jetbrains.python.run.PythonTracebackFilter;
import com.jetbrains.python.sdk.PythonSdkType; import com.jetbrains.python.sdk.PythonSdkType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.io.File; import java.io.File;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -62,7 +59,7 @@ public abstract class PythonTestCommandLineStateBase extends PythonCommandLineSt
} }
public PythonTestCommandLineStateBase(AbstractPythonRunConfiguration configuration, ExecutionEnvironment env) { public PythonTestCommandLineStateBase(AbstractPythonRunConfiguration configuration, ExecutionEnvironment env) {
super(configuration, env, Collections.<Filter>emptyList()); super(configuration, env);
myConfiguration = configuration; myConfiguration = configuration;
} }
@@ -77,7 +74,6 @@ public abstract class PythonTestCommandLineStateBase extends PythonCommandLineSt
consoleProperties, consoleProperties,
getEnvironment()); getEnvironment());
final ConsoleView consoleView = new PythonDebugLanguageConsoleView(project, PythonSdkType.findSdkByPath(myConfiguration.getInterpreterPath()), testsOutputConsoleView); final ConsoleView consoleView = new PythonDebugLanguageConsoleView(project, PythonSdkType.findSdkByPath(myConfiguration.getInterpreterPath()), testsOutputConsoleView);
consoleView.addMessageFilter(new PythonTracebackFilter(project, myConfiguration.getWorkingDirectory()));
consoleView.attachToProcess(processHandler); consoleView.attachToProcess(processHandler);
return consoleView; return consoleView;
} }
@@ -85,7 +81,7 @@ public abstract class PythonTestCommandLineStateBase extends PythonCommandLineSt
processHandler, processHandler,
consoleProperties, consoleProperties,
getEnvironment()); getEnvironment());
consoleView.addMessageFilter(new PythonTracebackFilter(project, myConfiguration.getWorkingDirectory())); addTracebackFilter(project, consoleView, processHandler);
return consoleView; return consoleView;
} }

View File

@@ -81,7 +81,7 @@ public class PyTestCommandLineState extends PythonTestCommandLineStateBase {
protected ConsoleView createAndAttachConsole(Project project, ProcessHandler processHandler, Executor executor) protected ConsoleView createAndAttachConsole(Project project, ProcessHandler processHandler, Executor executor)
throws ExecutionException { throws ExecutionException {
final ConsoleView consoleView = super.createAndAttachConsole(project, processHandler, executor); final ConsoleView consoleView = super.createAndAttachConsole(project, processHandler, executor);
consoleView.addMessageFilter(new PyTestTracebackFilter(project, myConfiguration.getWorkingDirectory())); addTracebackFilter(project, consoleView, processHandler);
return consoleView; return consoleView;
} }
} }