From 94fbeea5cc8ae9e57a1c8a866ddf09f479e4c178 Mon Sep 17 00:00:00 2001 From: Martin Oberhuber < martin.oberhuber@windriver.com> Date: Thu, 27 May 2010 09:17:59 +0000 Subject: [PATCH] Bug 314195 - [terminal][local] vi editor unusable in tcsh local terminal on Linux RHEL4 --- .../org.eclipse.rse.build/maps/terminal.map | 2 +- .../local/LocalTerminalConnector.java | 30 ++++++++++++++++--- .../local/LocalTerminalMessages.properties | 2 +- .../launch/LocalTerminalLaunchDelegate.java | 11 +++++-- .../launch/LocalTerminalLaunchUtilities.java | 17 +++++++++-- .../local/process/LocalTerminalProcess.java | 26 ++++++++++++++-- 6 files changed, 76 insertions(+), 12 deletions(-) diff --git a/releng/org.eclipse.rse.build/maps/terminal.map b/releng/org.eclipse.rse.build/maps/terminal.map index 1895c3ed3da..8f1916985cc 100644 --- a/releng/org.eclipse.rse.build/maps/terminal.map +++ b/releng/org.eclipse.rse.build/maps/terminal.map @@ -7,7 +7,7 @@ feature@org.eclipse.tm.terminal.telnet=v201005032000,:pserver:anonymous:none@dev feature@org.eclipse.tm.terminal.test=v200905272300,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.core/terminal/org.eclipse.tm.terminal.test-feature feature@org.eclipse.tm.terminal.view=v201005032000,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.core/terminal/org.eclipse.tm.terminal.view-feature plugin@org.eclipse.tm.terminal=v201005261000,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.core/terminal/org.eclipse.tm.terminal -plugin@org.eclipse.tm.terminal.local=v201005240710,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.core/terminal/org.eclipse.tm.terminal.local +plugin@org.eclipse.tm.terminal.local=v201005270915,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.core/terminal/org.eclipse.tm.terminal.local plugin@org.eclipse.tm.terminal.serial=v200905272300,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.core/terminal/org.eclipse.tm.terminal.serial plugin@org.eclipse.tm.terminal.ssh=v200905272300,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.core/terminal/org.eclipse.tm.terminal.ssh plugin@org.eclipse.tm.terminal.telnet=v200909160005,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.core/terminal/org.eclipse.tm.terminal.telnet diff --git a/terminal/org.eclipse.tm.terminal.local/src/org/eclipse/tm/internal/terminal/local/LocalTerminalConnector.java b/terminal/org.eclipse.tm.terminal.local/src/org/eclipse/tm/internal/terminal/local/LocalTerminalConnector.java index 4ffd8b504ac..301ad7f85a8 100644 --- a/terminal/org.eclipse.tm.terminal.local/src/org/eclipse/tm/internal/terminal/local/LocalTerminalConnector.java +++ b/terminal/org.eclipse.tm.terminal.local/src/org/eclipse/tm/internal/terminal/local/LocalTerminalConnector.java @@ -15,7 +15,7 @@ package org.eclipse.tm.internal.terminal.local; import java.io.OutputStream; import java.text.Format; import java.text.MessageFormat; - +import org.eclipse.cdt.utils.pty.PTY; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; @@ -27,7 +27,6 @@ import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; import org.eclipse.debug.core.ILaunchManager; -import org.eclipse.debug.core.model.IProcess; import org.eclipse.debug.core.model.IStreamMonitor; import org.eclipse.debug.core.model.IStreamsProxy; import org.eclipse.debug.ui.IDebugUIConstants; @@ -35,6 +34,7 @@ import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.tm.internal.terminal.local.launch.LocalTerminalLaunchUtilities; +import org.eclipse.tm.internal.terminal.local.process.LocalTerminalProcess; import org.eclipse.tm.internal.terminal.local.process.LocalTerminalProcessFactory; import org.eclipse.tm.internal.terminal.local.process.LocalTerminalProcessRegistry; import org.eclipse.tm.internal.terminal.provisional.api.ISettingsPage; @@ -50,7 +50,7 @@ import org.eclipse.tm.internal.terminal.provisional.api.provider.TerminalConnect * vi editor). * * @author Mirko Raner - * @version $Revision: 1.3 $ + * @version $Revision: 1.4 $ */ public class LocalTerminalConnector extends TerminalConnectorImpl implements IDebugEventSetListener { @@ -67,8 +67,10 @@ implements IDebugEventSetListener { private ILocalTerminalSettings settings; private IStreamMonitor outputMonitor; private IStreamMonitor errorMonitor; - private IProcess process; + private LocalTerminalProcess process; private ILaunch launch; + private int lastHeight; + private int lastWidth; /** * Creates a new {@link LocalTerminalConnector}. This constructor is invoked by the framework. @@ -310,6 +312,26 @@ implements IDebugEventSetListener { } } + /** + * Notifies the {@link PTY pty} that the size of the terminal has changed. + * This method gets called rather frequently, even if the terminal size has actually not + * changed. The method stores the last known width and height and will only call + * {@link PTY#setTerminalSize(int, int)} if it was different. + * + * @param width the new terminal width (in columns) + * @param height the new terminal height (in lines) + */ + public void setTerminalSize(int width, int height) { + + PTY pty = process.getPTY(); + if (pty != null && (width != lastWidth || height != lastHeight)) { + + pty.setTerminalSize(width, height); + lastWidth = width; + lastHeight = height; + } + } + /** * Listens for self-induced termination of the launched process. For example, this method will * be notified if a launched shell is terminated by pressing Control-D or by calling diff --git a/terminal/org.eclipse.tm.terminal.local/src/org/eclipse/tm/internal/terminal/local/LocalTerminalMessages.properties b/terminal/org.eclipse.tm.terminal.local/src/org/eclipse/tm/internal/terminal/local/LocalTerminalMessages.properties index 172f6e7de27..942ad35612a 100644 --- a/terminal/org.eclipse.tm.terminal.local/src/org/eclipse/tm/internal/terminal/local/LocalTerminalMessages.properties +++ b/terminal/org.eclipse.tm.terminal.local/src/org/eclipse/tm/internal/terminal/local/LocalTerminalMessages.properties @@ -21,7 +21,7 @@ labelEdit=Edit... labelDelete=Delete terminalTabName=Terminal terminalSettings=Terminal settings\: -newTerminalLaunchName=New Terminal Launch +newTerminalLaunchName=Terminal ({0}) noSuchLaunchConfiguration=A launch configuration called ''{0}'' does not exist launchingConfiguration=Launching {0}... couldNotCreateIProcess=The IProcess could not be created diff --git a/terminal/org.eclipse.tm.terminal.local/src/org/eclipse/tm/internal/terminal/local/launch/LocalTerminalLaunchDelegate.java b/terminal/org.eclipse.tm.terminal.local/src/org/eclipse/tm/internal/terminal/local/launch/LocalTerminalLaunchDelegate.java index 6250f91ee2a..bbcca6d2762 100644 --- a/terminal/org.eclipse.tm.terminal.local/src/org/eclipse/tm/internal/terminal/local/launch/LocalTerminalLaunchDelegate.java +++ b/terminal/org.eclipse.tm.terminal.local/src/org/eclipse/tm/internal/terminal/local/launch/LocalTerminalLaunchDelegate.java @@ -32,6 +32,7 @@ import org.eclipse.osgi.util.NLS; import org.eclipse.tm.internal.terminal.local.LocalTerminalActivator; import org.eclipse.tm.internal.terminal.local.LocalTerminalMessages; import org.eclipse.tm.internal.terminal.local.LocalTerminalUtilities; +import org.eclipse.tm.internal.terminal.local.process.LocalTerminalProcess; import org.eclipse.tm.internal.terminal.local.process.LocalTerminalProcessFactory; import org.eclipse.tm.internal.terminal.provisional.api.Logger; import org.eclipse.ui.PlatformUI; @@ -44,7 +45,7 @@ import org.eclipse.ui.PlatformUI; * {@link ProcessFactory}, which allows the process to run with a pseudo-terminal ({@link PTY}). * * @author Mirko Raner and others - * @version $Revision: 1.3 $ + * @version $Revision: 1.4 $ */ public class LocalTerminalLaunchDelegate extends LaunchConfigurationDelegate { @@ -154,12 +155,14 @@ public class LocalTerminalLaunchDelegate extends LaunchConfigurationDelegate { // Create the low-level Process object: // Process spawner; + PTY pty = null; try { ProcessFactory factory = ProcessFactory.getFactory(); if (PTY.isSupported()) { - spawner = factory.exec(commandLine, environment, workingDirectoryAsFile, new PTY(false)); + pty = new PTY(false); + spawner = factory.exec(commandLine, environment, workingDirectoryAsFile, pty); } else { @@ -206,6 +209,10 @@ public class LocalTerminalLaunchDelegate extends LaunchConfigurationDelegate { Status error = new Status(IStatus.ERROR, pluginID, IStatus.ERROR, errorMessage, null); throw new CoreException(error); } + if (process instanceof LocalTerminalProcess) { + + ((LocalTerminalProcess)process).setPTY(pty); + } process.setAttribute(IProcess.ATTR_CMDLINE, generateCommandLine(commandLine)); // Wait for process termination if necessary (though probably highly unusual for terminal diff --git a/terminal/org.eclipse.tm.terminal.local/src/org/eclipse/tm/internal/terminal/local/launch/LocalTerminalLaunchUtilities.java b/terminal/org.eclipse.tm.terminal.local/src/org/eclipse/tm/internal/terminal/local/launch/LocalTerminalLaunchUtilities.java index 3fd900440c2..26105e58220 100644 --- a/terminal/org.eclipse.tm.terminal.local/src/org/eclipse/tm/internal/terminal/local/launch/LocalTerminalLaunchUtilities.java +++ b/terminal/org.eclipse.tm.terminal.local/src/org/eclipse/tm/internal/terminal/local/launch/LocalTerminalLaunchUtilities.java @@ -7,11 +7,17 @@ * * Contributors: * Mirko Raner - [196337] Adapted from org.eclipse.ui.externaltools/ExternalToolsUtil + * Mirko Raner - [314195] vi editor unusable in tcsh local terminal on Linux RHEL4 **************************************************************************************************/ package org.eclipse.tm.internal.terminal.local.launch; import java.io.File; +import java.text.Format; +import java.text.MessageFormat; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; @@ -39,7 +45,7 @@ import org.eclipse.tm.internal.terminal.provisional.api.Logger; * because the original class is not part of the public API of its plug-in. * * @author Mirko Raner and others - * @version $Revision: 1.3 $ + * @version $Revision: 1.4 $ */ public class LocalTerminalLaunchUtilities { @@ -57,6 +63,9 @@ public class LocalTerminalLaunchUtilities { private final static String[] EMPTY = {}; private final static String STRING = null; + private final static String TERM = "TERM"; //$NON-NLS-1$ + private final static String ANSI = "ansi"; //$NON-NLS-1$ + private final static Map TERM_ANSI = Collections.singletonMap(TERM, ANSI); // These constants were copied from IExternalToolConstants to avoid references to internal API: // @@ -228,8 +237,12 @@ public class LocalTerminalLaunchUtilities { String userHome = System.getProperty("user.home", "/"); //$NON-NLS-1$//$NON-NLS-2$ String defaultShell = getDefaultShell().getAbsolutePath(); String name = defaultShell.substring(defaultShell.lastIndexOf(File.separator) + 1); - name = manager.generateLaunchConfigurationName("Terminal (" + name + ')'); //$NON-NLS-1$ + Format terminalLaunchName = new MessageFormat(LocalTerminalMessages.newTerminalLaunchName); + name = terminalLaunchName.format(new Object[] {name}); + name = manager.generateLaunchConfigurationName(name); workingCopy = LocalTerminalUtilities.TERMINAL_LAUNCH_TYPE.newInstance(null, name); + workingCopy.setAttribute(ILaunchManager.ATTR_ENVIRONMENT_VARIABLES, new HashMap(TERM_ANSI)); + workingCopy.setAttribute(ILaunchManager.ATTR_APPEND_ENVIRONMENT_VARIABLES, true); workingCopy.setAttribute(ATTR_LOCATION, defaultShell); workingCopy.setAttribute(ATTR_WORKING_DIRECTORY, userHome); workingCopy.setAttribute(ATTR_LOCAL_ECHO, runningOnWindows()); diff --git a/terminal/org.eclipse.tm.terminal.local/src/org/eclipse/tm/internal/terminal/local/process/LocalTerminalProcess.java b/terminal/org.eclipse.tm.terminal.local/src/org/eclipse/tm/internal/terminal/local/process/LocalTerminalProcess.java index 76e89302180..458851cdf69 100644 --- a/terminal/org.eclipse.tm.terminal.local/src/org/eclipse/tm/internal/terminal/local/process/LocalTerminalProcess.java +++ b/terminal/org.eclipse.tm.terminal.local/src/org/eclipse/tm/internal/terminal/local/process/LocalTerminalProcess.java @@ -1,5 +1,5 @@ /*************************************************************************************************** - * Copyright (c) 2008 Mirko Raner. + * Copyright (c) 2008, 2010 Mirko Raner. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -13,6 +13,7 @@ package org.eclipse.tm.internal.terminal.local.process; import java.util.HashMap; import java.util.Map; +import org.eclipse.cdt.utils.pty.PTY; import org.eclipse.cdt.utils.spawner.Spawner; import org.eclipse.debug.core.ILaunch; import org.eclipse.debug.core.model.IProcess; @@ -56,7 +57,7 @@ import org.eclipse.debug.core.model.RuntimeProcess; * extension point as proposed in bug 242373 (https://bugs.eclipse.org/bugs/show_bug.cgi?id=242373). * * @author Mirko Raner - * @version $Revision: 1.3 $ + * @version $Revision: 1.1 $ */ public final class LocalTerminalProcess extends RuntimeProcess { @@ -66,6 +67,7 @@ public final class LocalTerminalProcess extends RuntimeProcess { public final static String PROCESS_TYPE = "org.eclipse.tm.terminal.localProcess"; //$NON-NLS-1$ private boolean resetStreamsProxy; + private PTY pty; /** * Creates a new {@link LocalTerminalProcess}. @@ -124,6 +126,26 @@ public final class LocalTerminalProcess extends RuntimeProcess { resetStreamsProxy = true; } + /** + * Sets the pseudo-terminal associated with this process. + * + * @param pty the {@link PTY} + */ + public void setPTY(PTY pty) { + + this.pty = pty; + } + + /** + * Gets the pseudo-terminal associated with this process. + * + * @return the {@link PTY} + */ + public PTY getPTY() { + + return pty; + } + /** * Re-attaches the process to its launch and completes termination of the process. This ensures * that the launch can properly terminate.