Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1229,6 +1229,10 @@ String sshConnectInfo(
@Key("control.terminal.create.description")
String newTerminalDescription();

@Key("control.open.in.terminal")
@DefaultMessage("Open in Terminal")
String openInTerminalAction();

@Key("machine.output.action.title")
String machineOutputActionTitle();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@
import org.eclipse.che.ide.part.explorer.project.TreeResourceRevealer;
import org.eclipse.che.ide.part.explorer.project.synchronize.ProjectConfigSynchronized;
import org.eclipse.che.ide.processes.NewTerminalAction;
import org.eclipse.che.ide.processes.OpenInTerminalAction;
import org.eclipse.che.ide.processes.actions.CloseConsoleAction;
import org.eclipse.che.ide.processes.actions.DisplayMachineOutputAction;
import org.eclipse.che.ide.processes.actions.PreviewSSHAction;
Expand Down Expand Up @@ -201,6 +202,7 @@ public class StandardComponentInitializer {
public static final String SHOW_REFERENCE = "showReference";
public static final String SHOW_COMMANDS_PALETTE = "showCommandsPalette";
public static final String NEW_TERMINAL = "newTerminal";
public static final String OPEN_IN_TERMINAL = "openInTerminal";
public static final String PROJECT_EXPLORER_DISPLAYING_MODE = "projectExplorerDisplayingMode";
public static final String COMMAND_EXPLORER_DISPLAYING_MODE = "commandExplorerDisplayingMode";
public static final String FIND_RESULT_DISPLAYING_MODE = "findResultDisplayingMode";
Expand Down Expand Up @@ -403,6 +405,8 @@ public interface ParserResource extends ClientBundle {

@Inject private MoveCommandAction moveCommandAction;

@Inject private OpenInTerminalAction openInTerminalAction;

@Inject
@Named("XMLFileType")
private FileType xmlFile;
Expand Down Expand Up @@ -744,6 +748,8 @@ public void initialize() {
mainContextMenuGroup.add(newGroup, FIRST);
mainContextMenuGroup.addSeparator();
mainContextMenuGroup.add(resourceOperation);
mainContextMenuGroup.add(openInTerminalAction);
actionManager.registerAction(OPEN_IN_TERMINAL, openInTerminalAction);

DefaultActionGroup partMenuGroup =
(DefaultActionGroup) actionManager.getAction(GROUP_PART_MENU);
Expand Down Expand Up @@ -903,6 +909,9 @@ public void initialize() {
keyBinding
.getGlobal()
.addKey(new KeyBuilder().alt().charCode(KeyCodeMap.F12).build(), NEW_TERMINAL);
keyBinding
.getGlobal()
.addKey(new KeyBuilder().alt().shift().charCode(KeyCodeMap.F12).build(), OPEN_IN_TERMINAL);

keyBinding.getGlobal().addKey(new KeyBuilder().alt().charCode('N').build(), NEW_FILE);
keyBinding.getGlobal().addKey(new KeyBuilder().alt().charCode('x').build(), CREATE_PROJECT);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright (c) 2012-2018 Red Hat, Inc.
* 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
*/
package org.eclipse.che.ide.processes;

import static org.eclipse.che.ide.part.perspectives.project.ProjectPerspective.PROJECT_PERSPECTIVE_ID;

import com.google.gwt.core.client.GWT;
import com.google.gwt.safehtml.client.SafeHtmlTemplates;
import com.google.gwt.safehtml.shared.SafeHtml;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.util.Collections;
import org.eclipse.che.ide.CoreLocalizationConstant;
import org.eclipse.che.ide.api.action.AbstractPerspectiveAction;
import org.eclipse.che.ide.api.action.ActionEvent;
import org.eclipse.che.ide.api.resources.Container;
import org.eclipse.che.ide.api.resources.Resource;
import org.eclipse.che.ide.machine.MachineResources;
import org.eclipse.che.ide.processes.panel.ProcessesPanelPresenter;
import org.eclipse.che.ide.resource.Path;
import org.eclipse.che.ide.terminal.TerminalOptionsJso;

/**
* Action to open new terminal and navigate to selected directory. If on selected folder in Project
* Explorer call this action MUST be opened new terminal with selected working dir.
*
* <p>bash command 'cd {selected-folder}'
*
* @author Vitalii Parfonov
*/
@Singleton
public class OpenInTerminalAction extends AbstractPerspectiveAction {

private CoreLocalizationConstant locale;
private final ProcessesPanelPresenter processesPanelPresenter;

interface Command extends SafeHtmlTemplates {

@Template("cd {0} && clear")
SafeHtml openInTerminalCommand(String path);
}

@Inject
public OpenInTerminalAction(
CoreLocalizationConstant locale,
MachineResources machineResources,
ProcessesPanelPresenter processesPanelPresenter) {
super(
Collections.singletonList(PROJECT_PERSPECTIVE_ID),
locale.openInTerminalAction(),
null,
machineResources.addTerminalIcon());
this.locale = locale;

this.processesPanelPresenter = processesPanelPresenter;
}

@Override
public void updateInPerspective(ActionEvent event) {
event.getPresentation().setEnabled(true);
}

@Override
public void actionPerformed(ActionEvent event) {
Resource resource = appContext.get().getResource();
if (resource.isFile()) {
final Container parent = resource.getParent();
resource = parent;
}
Path path = resource.getLocation().makeRelative();
Command cmdTmpl = GWT.create(Command.class);
String command = cmdTmpl.openInTerminalCommand(path.toString()).asString();
processesPanelPresenter.newTerminal(
TerminalOptionsJso.createDefault().withCommand(command).withFocusOnOpen(true));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ public void onAddTerminal(final String machineId, TerminalOptionsJso options, bo
workspaceAgentProvider.get().setActivePart(this);

newTerminal.setVisible(true);
newTerminal.connect();
newTerminal.connect(options);
newTerminal.setListener(() -> onCloseTerminal(terminalNode));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,27 @@ public static native TerminalOptionsJso createDefault() /*-{
cols: 80,
rows: 24,
screenKeys: true,
focusOnOpen: true
focusOnOpen: true,
command: ""
}
}-*/;

/**
* @param focusOnOpen set true it need to set focus on just opened terminal
* @return
*/
public final native TerminalOptionsJso withFocusOnOpen(boolean focusOnOpen) /*-{
this.focusOnOpen = focusOnOpen;
return this;
}-*/;

/**
* @param command initial command what will be executed immediately after connection to the
* terminal will established
* @return
*/
public final native TerminalOptionsJso withCommand(String command) /*-{
this.command = command;
return this;
}-*/;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import static org.eclipse.che.ide.api.notification.StatusNotification.Status.FAIL;
import static org.eclipse.che.ide.websocket.events.WebSocketClosedEvent.CLOSE_NORMAL;

import com.google.common.base.Strings;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArrayInteger;
import com.google.gwt.user.client.Timer;
Expand All @@ -33,7 +34,6 @@
import org.eclipse.che.ide.collections.Jso;
import org.eclipse.che.ide.core.AgentURLModifier;
import org.eclipse.che.ide.websocket.WebSocket;
import org.eclipse.che.ide.websocket.events.ConnectionErrorHandler;
import org.eclipse.che.requirejs.ModuleHolder;

/**
Expand All @@ -45,10 +45,10 @@ public class TerminalPresenter implements Presenter, TerminalView.ActionDelegate

// event which is performed when user input data into terminal
private static final String DATA_EVENT_NAME = "data";
private static final String TYPE = "type";
private static final int TIME_BETWEEN_CONNECTIONS = 2_000;

private final TerminalView view;
private final TerminalOptionsJso options;
private final NotificationManager notificationManager;
private final CoreLocalizationConstant locale;
private final MachineImpl machine;
Expand All @@ -70,12 +70,10 @@ public TerminalPresenter(
NotificationManager notificationManager,
CoreLocalizationConstant locale,
@NotNull @Assisted MachineImpl machine,
@Assisted TerminalOptionsJso options,
final TerminalInitializePromiseHolder terminalHolder,
final ModuleHolder moduleHolder,
AgentURLModifier agentURLModifier) {
this.view = view;
this.options = options != null ? options : TerminalOptionsJso.createDefault();
this.agentURLModifier = agentURLModifier;
view.setDelegate(this);
this.notificationManager = notificationManager;
Expand All @@ -89,10 +87,27 @@ public TerminalPresenter(
}

/**
* Connects to special WebSocket which allows get information from terminal on server side. The
* terminal is initialized only when the method is called the first time.
* Connects to Terminal Server by WebSocket. Which allows get information from terminal on server
* side. The terminal is initialized only when the method is called the first time.
*/
public void connect() {
connect(TerminalOptionsJso.createDefault());
}

/**
* <pre>
* Connects to Terminal Server by WebSocket. Which allows get information from terminal on server side. The
* terminal is initialized only when the method is called the first time.
*
* @param options with options param can be set some initial states for new terminal like:
* - initial size (number of rows and cols);
* - set focused on open;
* - initial command (like change working dir 'cd directory' and etc)
*
* More details {@link TerminalOptionsJso}
* </pre>
*/
public void connect(TerminalOptionsJso options) {
if (countRetry == 0) {
return;
}
Expand All @@ -111,7 +126,7 @@ public void connect() {
"Machine "
+ machine.getName()
+ " doesn't provide terminal server."));
connectToTerminal(agentURLModifier.modify(terminalServer.getUrl()));
connectToTerminal(agentURLModifier.modify(terminalServer.getUrl()), options);
})
.catchError(
arg -> {
Expand Down Expand Up @@ -139,7 +154,19 @@ public void run() {
}
}

private void connectToTerminal(@NotNull String wsUrl) {
/**
* Give command will be executed
*
* @param command
*/
public void sendCommand(String command) {
Jso jso = Jso.create();
jso.addField(TYPE, DATA_EVENT_NAME);
jso.addField(DATA_EVENT_NAME, command);
socket.send(jso.serialize());
}

private void connectToTerminal(@NotNull String wsUrl, TerminalOptionsJso options) {
countRetry--;

socket = WebSocket.create(wsUrl);
Expand All @@ -166,28 +193,30 @@ private void connectToTerminal(@NotNull String wsUrl) {
DATA_EVENT_NAME,
data -> {
Jso jso = Jso.create();
jso.addField("type", "data");
jso.addField("data", data);
jso.addField(TYPE, DATA_EVENT_NAME);
jso.addField(DATA_EVENT_NAME, data);
socket.send(jso.serialize());
});
String command = options.getStringField("command");
if (!Strings.isNullOrEmpty(command)) {
sendCommand(command);
sendCommand("\r");
}
});

socket.setOnErrorHandler(
new ConnectionErrorHandler() {
@Override
public void onError() {
connected = false;
() -> {
connected = false;

if (countRetry == 0) {
view.showErrorMessage(locale.terminalErrorStart());
notificationManager.notify(
locale.connectionFailedWithTerminal(),
locale.terminalErrorConnection(),
FAIL,
FLOAT_MODE);
} else {
reconnect();
}
if (countRetry == 0) {
view.showErrorMessage(locale.terminalErrorStart());
notificationManager.notify(
locale.connectionFailedWithTerminal(),
locale.terminalErrorConnection(),
FAIL,
FLOAT_MODE);
} else {
reconnect();
}
});
}
Expand All @@ -196,7 +225,7 @@ public void onError() {
public void stopTerminal() {
if (connected) {
Jso jso = Jso.create();
jso.addField("type", "close");
jso.addField(TYPE, "close");
socket.send(jso.serialize());
}
}
Expand Down Expand Up @@ -234,8 +263,8 @@ public void setTerminalSize(int x, int y) {
JsArrayInteger arr = Jso.createArray().cast();
arr.set(0, x);
arr.set(1, y);
jso.addField("type", "resize");
jso.addField("data", arr);
jso.addField(TYPE, "resize");
jso.addField(DATA_EVENT_NAME, arr);
socket.send(jso.serialize());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public enum ContextMenuFirstLevelItems implements ContextMenuItems {
SHOW_REFERENCES("gwt-debug-contextMenu/showReference"),
GO_INTO("gwt-debug-contextMenu/goInto"),
GO_BACK("gwt-debug-contextMenu/goInto"),
OPEN_IN_TERMINAL("gwt-debug-contextMenu/openInTerminal"),
CUT("gwt-debug-contextMenu/cut"),
COPY("gwt-debug-contextMenu/copy"),
PASTE("gwt-debug-contextMenu/paste"),
Expand Down
Loading