Terminal: move jediterm library to platform and provide open url in browser action (IDEA-136672)

This commit is contained in:
Dmitry Trofimov
2017-01-14 20:39:15 +01:00
parent 5e3f4dc97a
commit 8ec4c0f46c
16 changed files with 790 additions and 554 deletions
+11
View File
@@ -0,0 +1,11 @@
<component name="libraryTable">
<library name="jediterm-pty">
<CLASSES>
<root url="jar://$PROJECT_DIR$/lib/jediterm-pty-2.5.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/lib/src/jediterm-pty-2.5-src.jar!/" />
</SOURCES>
</library>
</component>
Binary file not shown.
+1
View File
@@ -48,5 +48,6 @@
<orderEntry type="library" name="pty4j" level="project" />
<orderEntry type="module" module-name="credential-store" scope="RUNTIME" />
<orderEntry type="library" exported="" name="StreamEx" level="project" />
<orderEntry type="library" name="jediterm-pty" level="project" />
</component>
</module>
@@ -0,0 +1,92 @@
/*
* 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.intellij.terminal;
import com.jediterm.terminal.TerminalDataStream;
import java.io.IOException;
import java.util.concurrent.LinkedBlockingDeque;
/**
* @author traff
*/
public class AppendableTerminalDataStream implements TerminalDataStream, Appendable {
private LinkedBlockingDeque<Character> myQueue = new LinkedBlockingDeque<>(10000000);
@Override
public char getChar() throws IOException {
try {
return myQueue.take();
}
catch (InterruptedException e) {
throw new IOException(e);
}
}
@Override
public void pushChar(char c) throws IOException {
myQueue.push(c);
}
@Override
public String readNonControlCharacters(int maxLength) throws IOException {
StringBuilder sb = new StringBuilder();
while (sb.length() < maxLength) {
Character c = myQueue.peek();
if (c == null || c.charValue() < 32) {
break;
}
sb.append(myQueue.poll());
}
return sb.toString();
}
@Override
public void pushBackBuffer(char[] chars, int length) throws IOException {
for (int i = 0; i < length; i++) {
myQueue.addFirst(chars[length - i - i]);
}
}
@Override
public Appendable append(CharSequence csq) throws IOException {
for (int i = 0; i<csq.length(); i++) {
append(csq.charAt(i));
}
return this;
}
@Override
public Appendable append(CharSequence csq, int start, int end) throws IOException {
for (int i = start; i<end; i++) {
append(csq.charAt(i));
}
return this;
}
@Override
public Appendable append(char c) throws IOException {
try {
myQueue.put(c);
}
catch (InterruptedException e) {
throw new IOException(e);
}
return this;
}
}
@@ -17,9 +17,8 @@
/* -*-mode:java; c-basic-offset:2; -*- */
package org.jetbrains.plugins.terminal;
package com.intellij.terminal;
import com.google.common.base.Predicate;
import com.google.common.collect.Lists;
import com.intellij.ide.GeneralSettings;
import com.intellij.ide.IdeEventQueue;
@@ -32,6 +31,7 @@ import com.intellij.openapi.editor.impl.FontInfo;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.util.JBHiDPIScaledImage;
import com.intellij.util.RetinaImage;
import com.intellij.util.ui.UIUtil;
@@ -90,25 +90,17 @@ public class JBTerminalPanel extends TerminalPanel implements FocusListener, Ter
"Switcher"
};
private final JBTerminalSystemSettingsProvider mySettingsProvider;
private final JBTerminalSystemSettingsProviderBase mySettingsProvider;
private List<AnAction> myActionsToSkip;
public JBTerminalPanel(@NotNull JBTerminalSystemSettingsProvider settingsProvider,
public JBTerminalPanel(@NotNull JBTerminalSystemSettingsProviderBase settingsProvider,
@NotNull TerminalTextBuffer backBuffer,
@NotNull StyleState styleState) {
super(settingsProvider, backBuffer, styleState);
mySettingsProvider = settingsProvider;
JBTabbedTerminalWidget.convertActions(this, getActions(), new Predicate<KeyEvent>() {
@Override
public boolean apply(KeyEvent input) {
JBTerminalPanel.this.handleKeyEvent(input);
return true;
}
});
registerKeymapActions(this);
addFocusListener(this);
@@ -255,7 +247,7 @@ public class JBTerminalPanel extends TerminalPanel implements FocusListener, Ter
}
private void installKeyDispatcher() {
if (TerminalOptionsProvider.Companion.getInstance().overrideIdeShortcuts()) {
if (mySettingsProvider.overrideIdeShortcuts()) {
myActionsToSkip = setupActionsToSkip();
IdeEventQueue.getInstance().addDispatcher(this, this);
}
@@ -283,7 +275,7 @@ public class JBTerminalPanel extends TerminalPanel implements FocusListener, Ter
IdeEventQueue.getInstance().removeDispatcher(this);
}
JBTerminalStarter.refreshAfterExecution();
refreshAfterExecution();
}
@Override
@@ -307,5 +299,12 @@ public class JBTerminalPanel extends TerminalPanel implements FocusListener, Ter
super.dispose();
mySettingsProvider.removeListener(this);
}
public static void refreshAfterExecution() {
if (GeneralSettings.getInstance().isSyncOnFrameActivation()) {
//we need to refresh local file system after a command has been executed in the terminal
LocalFileSystem.getInstance().refresh(true);
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* 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.
@@ -13,14 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.terminal;
package com.intellij.terminal;
import com.intellij.execution.process.ColoredOutputTypeRegistry;
import com.intellij.execution.process.ConsoleHighlighter;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.jediterm.terminal.emulator.ColorPalette;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
@@ -0,0 +1,43 @@
/*
* 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.intellij.terminal;
import com.jediterm.terminal.*;
import com.jediterm.terminal.emulator.JediEmulator;
/**
* @author traff
*/
public class JBTerminalStarter extends TerminalStarter {
public JBTerminalStarter(Terminal terminal, TtyConnector ttyConnector) {
super(terminal, ttyConnector, new TtyBasedArrayDataStream(ttyConnector));
}
@Override
protected JediEmulator createEmulator(TerminalDataStream dataStream, Terminal terminal) {
return new JediEmulator(dataStream, terminal) {
@Override
protected void unsupported(char... sequenceChars) {
if (sequenceChars[0] == 7) { //ESC BEL
JBTerminalPanel.refreshAfterExecution();
}
else {
super.unsupported();
}
}
};
}
}
@@ -0,0 +1,482 @@
/*
* 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.intellij.terminal;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.ide.ui.UISettings;
import com.intellij.ide.ui.UISettingsListener;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.KeyboardShortcut;
import com.intellij.openapi.actionSystem.Shortcut;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.colors.*;
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.keymap.KeymapManager;
import com.intellij.openapi.options.FontSize;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.util.containers.HashMap;
import com.intellij.util.containers.HashSet;
import com.intellij.util.messages.MessageBusConnection;
import com.jediterm.terminal.TerminalColor;
import com.jediterm.terminal.TextStyle;
import com.jediterm.terminal.emulator.ColorPalette;
import com.jediterm.terminal.ui.settings.DefaultTabbedSettingsProvider;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.util.*;
import java.util.List;
/**
* @author traff
*/
public class JBTerminalSystemSettingsProviderBase extends DefaultTabbedSettingsProvider implements Disposable {
protected final MyColorSchemeDelegate myColorScheme;
public JBTerminalSystemSettingsProviderBase() {
myColorScheme = createBoundColorSchemeDelegate(null);
MessageBusConnection connection = ApplicationManager.getApplication().getMessageBus().connect(this);
connection.subscribe(UISettingsListener.TOPIC, new UISettingsListener() {
@Override
public void uiSettingsChanged(UISettings uiSettings) {
int size = consoleFontSize(JBTerminalSystemSettingsProviderBase.this.myColorScheme);
if (myColorScheme.getConsoleFontSize() != size) {
myColorScheme.setConsoleFontSize(size);
fireFontChanged();
}
}
});
connection.subscribe(EditorColorsManager.TOPIC, new EditorColorsListener() {
@Override
public void globalSchemeChange(EditorColorsScheme scheme) {
myColorScheme.updateGlobalScheme(scheme);
fireFontChanged();
}
});
}
private Set<TerminalSettingsListener> myListeners = new HashSet<>();
@Override
public KeyStroke[] getCopyKeyStrokes() {
return getKeyStrokesByActionId("$Copy");
}
@Override
public KeyStroke[] getPasteKeyStrokes() {
return getKeyStrokesByActionId("$Paste");
}
@Override
public KeyStroke[] getNextTabKeyStrokes() {
return getKeyStrokesByActionId("NextTab");
}
@Override
public KeyStroke[] getPreviousTabKeyStrokes() {
return getKeyStrokesByActionId("PreviousTab");
}
@Override
public KeyStroke[] getFindKeyStrokes() {
return getKeyStrokesByActionId("Find");
}
@Override
public ColorPalette getTerminalColorPalette() {
return new JBTerminalSchemeColorPalette(myColorScheme);
}
private KeyStroke[] getKeyStrokesByActionId(String actionId) {
java.util.List<KeyStroke> keyStrokes = new ArrayList<>();
Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts(actionId);
for (Shortcut sc : shortcuts) {
if (sc instanceof KeyboardShortcut) {
KeyStroke ks = ((KeyboardShortcut)sc).getFirstKeyStroke();
keyStrokes.add(ks);
}
}
return keyStrokes.toArray(new KeyStroke[keyStrokes.size()]);
}
@Override
public void dispose() {
}
public void addListener(TerminalSettingsListener listener) {
myListeners.add(listener);
}
public void removeListener(TerminalSettingsListener listener) {
myListeners.remove(listener);
}
public void fireFontChanged() {
for (TerminalSettingsListener l : myListeners) {
l.fontChanged();
}
}
protected static int consoleFontSize(MyColorSchemeDelegate colorScheme) {
int size;
if (UISettings.getInstance().PRESENTATION_MODE) {
size = UISettings.getInstance().PRESENTATION_MODE_FONT_SIZE;
}
else {
size = colorScheme.getGlobal().getConsoleFontSize();
}
return size;
}
protected static class MyColorSchemeDelegate implements EditorColorsScheme {
private final FontPreferences myFontPreferences = new FontPreferences();
private final HashMap<TextAttributesKey, TextAttributes> myOwnAttributes = new HashMap<>();
private final HashMap<ColorKey, Color> myOwnColors = new HashMap<>();
private Map<EditorFontType, Font> myFontsMap = null;
private String myFaceName = null;
private EditorColorsScheme myGlobalScheme;
private int myConsoleFontSize;
protected MyColorSchemeDelegate(@Nullable final EditorColorsScheme globalScheme) {
updateGlobalScheme(globalScheme);
myConsoleFontSize = consoleFontSize(this);
initFonts();
}
private EditorColorsScheme getGlobal() {
return myGlobalScheme;
}
@NotNull
@Override
public String getName() {
return getGlobal().getName();
}
protected void initFonts() {
String consoleFontName = getConsoleFontName();
int consoleFontSize = getConsoleFontSize();
myFontPreferences.clear();
myFontPreferences.register(consoleFontName, consoleFontSize);
myFontsMap = new EnumMap<>(EditorFontType.class);
Font plainFont = new Font(consoleFontName, Font.PLAIN, consoleFontSize);
Font boldFont = new Font(consoleFontName, Font.BOLD, consoleFontSize);
Font italicFont = new Font(consoleFontName, Font.ITALIC, consoleFontSize);
Font boldItalicFont = new Font(consoleFontName, Font.BOLD | Font.ITALIC, consoleFontSize);
myFontsMap.put(EditorFontType.PLAIN, plainFont);
myFontsMap.put(EditorFontType.BOLD, boldFont);
myFontsMap.put(EditorFontType.ITALIC, italicFont);
myFontsMap.put(EditorFontType.BOLD_ITALIC, boldItalicFont);
}
@Override
public void setName(String name) {
getGlobal().setName(name);
}
@Override
public TextAttributes getAttributes(TextAttributesKey key) {
if (myOwnAttributes.containsKey(key)) return myOwnAttributes.get(key);
return getGlobal().getAttributes(key);
}
@Override
public void setAttributes(@NotNull TextAttributesKey key, TextAttributes attributes) {
myOwnAttributes.put(key, attributes);
}
@NotNull
@Override
public Color getDefaultBackground() {
Color color = getGlobal().getColor(ConsoleViewContentType.CONSOLE_BACKGROUND_KEY);
return color != null ? color : getGlobal().getDefaultBackground();
}
@NotNull
@Override
public Color getDefaultForeground() {
Color foregroundColor = getGlobal().getAttributes(ConsoleViewContentType.NORMAL_OUTPUT_KEY).getForegroundColor();
return foregroundColor != null ? foregroundColor : getGlobal().getDefaultForeground();
}
@Override
public Color getColor(ColorKey key) {
if (myOwnColors.containsKey(key)) return myOwnColors.get(key);
return getGlobal().getColor(key);
}
@Override
public void setColor(ColorKey key, Color color) {
myOwnColors.put(key, color);
}
@NotNull
@Override
public FontPreferences getFontPreferences() {
return myGlobalScheme.getFontPreferences();
}
@Override
public void setFontPreferences(@NotNull FontPreferences preferences) {
throw new IllegalStateException();
}
@Override
public int getEditorFontSize() {
return getGlobal().getEditorFontSize();
}
@Override
public void setEditorFontSize(int fontSize) {
}
@Override
public FontSize getQuickDocFontSize() {
return myGlobalScheme.getQuickDocFontSize();
}
@Override
public void setQuickDocFontSize(@NotNull FontSize fontSize) {
myGlobalScheme.setQuickDocFontSize(fontSize);
}
@Override
public String getEditorFontName() {
return getGlobal().getEditorFontName();
}
@Override
public void setEditorFontName(String fontName) {
throw new IllegalStateException();
}
@Override
public Font getFont(EditorFontType key) {
if (myFontsMap != null) {
Font font = myFontsMap.get(key);
if (font != null) return font;
}
return getGlobal().getFont(key);
}
@Override
public void setFont(EditorFontType key, Font font) {
if (myFontsMap == null) {
initFonts();
}
myFontsMap.put(key, font);
}
@Override
public float getLineSpacing() {
return getGlobal().getLineSpacing();
}
@Override
public void setLineSpacing(float lineSpacing) {
getGlobal().setLineSpacing(lineSpacing);
}
@Override
@Nullable
public Object clone() {
return null;
}
@Override
public void readExternal(Element element) {
}
public void updateGlobalScheme(EditorColorsScheme scheme) {
myFontsMap = null;
myGlobalScheme = scheme == null ? EditorColorsManager.getInstance().getGlobalScheme() : scheme;
}
@NotNull
@Override
public FontPreferences getConsoleFontPreferences() {
return myFontPreferences;
}
@Override
public void setConsoleFontPreferences(@NotNull FontPreferences preferences) {
preferences.copyTo(myFontPreferences);
initFonts();
}
@Override
public String getConsoleFontName() {
if (myFaceName == null) {
return getGlobal().getConsoleFontName();
}
else {
return myFaceName;
}
}
@Override
public void setConsoleFontName(String fontName) {
myFaceName = fontName;
initFonts();
}
@Override
public int getConsoleFontSize() {
if (myConsoleFontSize == -1) {
return getGlobal().getConsoleFontSize();
}
else {
return myConsoleFontSize;
}
}
@Override
public void setConsoleFontSize(int fontSize) {
myConsoleFontSize = fontSize;
initFonts();
}
@Override
public float getConsoleLineSpacing() {
return getGlobal().getConsoleLineSpacing();
}
@Override
public void setConsoleLineSpacing(float lineSpacing) {
getGlobal().setConsoleLineSpacing(lineSpacing);
}
@NotNull
@Override
public Properties getMetaProperties() {
return myGlobalScheme.getMetaProperties();
}
}
@NotNull
private static MyColorSchemeDelegate createBoundColorSchemeDelegate(@Nullable final EditorColorsScheme customGlobalScheme) {
return new MyColorSchemeDelegate(customGlobalScheme);
}
public EditorColorsScheme getColorScheme() {
return myColorScheme;
}
@Override
public float getLineSpace() {
return myColorScheme.getConsoleLineSpacing();
}
@Override
public TextStyle getSelectionColor() {
return new TextStyle(TerminalColor.awt(myColorScheme.getColor(EditorColors.SELECTION_FOREGROUND_COLOR)),
TerminalColor.awt(myColorScheme.getColor(EditorColors.SELECTION_BACKGROUND_COLOR)));
}
@Override
public TextStyle getFoundPatternColor() {
return new TextStyle(TerminalColor.awt(myColorScheme.getAttributes(EditorColors.TEXT_SEARCH_RESULT_ATTRIBUTES).getForegroundColor()),
TerminalColor.awt(myColorScheme.getAttributes(EditorColors.TEXT_SEARCH_RESULT_ATTRIBUTES).getBackgroundColor()));
}
@Override
public TextStyle getHyperlinkColor() {
return new TextStyle(TerminalColor.awt(myColorScheme.getAttributes(EditorColors.REFERENCE_HYPERLINK_COLOR).getForegroundColor()),
TerminalColor.awt(myColorScheme.getAttributes(EditorColors.REFERENCE_HYPERLINK_COLOR).getBackgroundColor()));
}
@Override
public TextStyle getDefaultStyle() {
return new TextStyle(TerminalColor.awt(myColorScheme.getDefaultForeground()), TerminalColor.awt(
myColorScheme.getDefaultBackground()));
}
@Override
public Font getTerminalFont() {
Font normalFont = Font.decode(getFontName());
if (normalFont == null) {
normalFont = super.getTerminalFont();
}
normalFont = normalFont.deriveFont(getTerminalFontSize());
return normalFont;
}
public String getFontName() {
List<String> fonts = myColorScheme.getConsoleFontPreferences().getEffectiveFontFamilies();
if (fonts.size() > 0) {
return fonts.get(0);
}
return "Monospaced-14";
}
@Override
public float getTerminalFontSize() {
return (float)myColorScheme.getConsoleFontSize();
}
@Override
public boolean useAntialiasing() {
return true; // we return true here because all the settings are checked again in UiSettings.setupAntialiasing
}
@Override
public int caretBlinkingMs() {
if (!EditorSettingsExternalizable.getInstance().isBlinkCaret()) {
return 0;
}
return EditorSettingsExternalizable.getInstance().getBlinkPeriod();
}
@Override
public int getBufferMaxLinesCount() {
final int linesCount = Registry.get("terminal.buffer.max.lines.count").asInteger();
if (linesCount > 0) {
return linesCount;
}
else {
return super.getBufferMaxLinesCount();
}
}
public boolean overrideIdeShortcuts() {
return false;
}
@Override
public boolean useInverseSelectionColor() {
return false;
}
}
@@ -1,6 +1,22 @@
package org.jetbrains.plugins.terminal;
/*
* 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.intellij.terminal;
import com.google.common.base.Predicate;
import com.intellij.execution.filters.Filter;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
@@ -12,8 +28,8 @@ import com.intellij.util.ui.JBSwingUtilities;
import com.intellij.util.ui.RegionPainter;
import com.jediterm.terminal.SubstringFinder;
import com.jediterm.terminal.TerminalStarter;
import com.jediterm.terminal.TtyBasedArrayDataStream;
import com.jediterm.terminal.TtyConnector;
import com.jediterm.terminal.model.HyperlinkFilter;
import com.jediterm.terminal.model.JediTerminal;
import com.jediterm.terminal.model.StyleState;
import com.jediterm.terminal.model.TerminalTextBuffer;
@@ -28,25 +44,69 @@ import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.List;
import java.util.stream.Collectors;
public class JBTerminalWidget extends JediTermWidget implements Disposable{
public class JBTerminalWidget extends JediTermWidget implements Disposable {
private final Project myProject;
private final JBTerminalSystemSettingsProviderBase mySettingsProvider;
public JBTerminalWidget(Project project, JBTerminalSystemSettingsProvider settingsProvider, Disposable parent) {
super(settingsProvider);
public JBTerminalWidget(Project project, JBTerminalSystemSettingsProviderBase settingsProvider, Disposable parent) {
this(project, 80, 24, settingsProvider, parent);
}
public JBTerminalWidget(Project project, int columns, int lines, JBTerminalSystemSettingsProviderBase settingsProvider, Disposable parent) {
super(columns, lines, settingsProvider);
myProject = project;
mySettingsProvider = settingsProvider;
setName("terminal");
JBTabbedTerminalWidget.convertActions(this, getActions());
Disposer.register(parent, this);
}
public void addMessageFilter(Project project, Filter filter) {
addHyperlinkFilter(new HyperlinkFilter() {
@Override
public Result apply(String line) {
Filter.Result r = filter.applyFilter(line, line.length());
if (r != null) {
return new Result() {
@Override
public List<ResultItem> getResultItems() {
return r.getResultItems().stream().map((item -> new ResultItem() {
@Override
public int getStartOffset() {
return item.getHighlightStartOffset();
}
@Override
public int getEndOffset() {
return item.getHighlightEndOffset();
}
@Override
public void navigate() {
item.getHyperlinkInfo().navigate(project);
}
})).collect(Collectors.toList());
}
};
}
else {
return null;
}
}
});
}
@Override
protected JBTerminalPanel createTerminalPanel(@NotNull SettingsProvider settingsProvider,
@NotNull StyleState styleState,
@NotNull TerminalTextBuffer textBuffer) {
JBTerminalPanel panel = new JBTerminalPanel((JBTerminalSystemSettingsProvider)settingsProvider, textBuffer, styleState);
JBTerminalPanel panel = new JBTerminalPanel((JBTerminalSystemSettingsProviderBase)settingsProvider, textBuffer, styleState);
Disposer.register(this, panel);
return panel;
}
@@ -58,7 +118,7 @@ public class JBTerminalWidget extends JediTermWidget implements Disposable{
@Override
protected TerminalStarter createTerminalStarter(JediTerminal terminal, TtyConnector connector) {
return new JBTerminalStarter(terminal, connector, new TtyBasedArrayDataStream(connector));
return new JBTerminalStarter(terminal, connector);
}
@Override
@@ -89,7 +149,7 @@ public class JBTerminalWidget extends JediTermWidget implements Disposable{
@Override
public List<TerminalAction> getActions() {
List<TerminalAction> actions = super.getActions();
if (!TerminalOptionsProvider.Companion.getInstance().overrideIdeShortcuts()) {
if (!mySettingsProvider.overrideIdeShortcuts()) {
actions
.add(new TerminalAction("EditorEscape", new KeyStroke[]{KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0)}, new Predicate<KeyEvent>() {
@Override
@@ -115,6 +175,7 @@ public class JBTerminalWidget extends JediTermWidget implements Disposable{
protected SearchComponent createSearchComponent() {
return new SearchComponent() {
private final SearchTextField myTextField = new SearchTextField(false);
@Override
public String getText() {
return myTextField.getText();
@@ -0,0 +1,23 @@
/*
* 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.intellij.terminal;
/**
* @author traff
*/
public interface TerminalSettingsListener {
void fontChanged();
}
@@ -1,3 +1,18 @@
/*
* 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 org.jetbrains.plugins.terminal;
import com.google.common.base.Predicate;
@@ -20,6 +35,8 @@ import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileSystemItem;
import com.intellij.terminal.JBTerminalSystemSettingsProviderBase;
import com.intellij.terminal.JBTerminalWidget;
import com.intellij.ui.SimpleColoredComponent;
import com.intellij.ui.components.JBTextField;
import com.intellij.ui.docking.DockManager;
@@ -48,11 +65,11 @@ import java.util.concurrent.CopyOnWriteArraySet;
public class JBTabbedTerminalWidget extends TabbedTerminalWidget implements Disposable {
private Project myProject;
private final JBTerminalSystemSettingsProvider mySettingsProvider;
private final JBTerminalSystemSettingsProviderBase mySettingsProvider;
private Disposable myParent;
public JBTabbedTerminalWidget(@NotNull Project project,
@NotNull JBTerminalSystemSettingsProvider settingsProvider,
@NotNull JBTerminalSystemSettingsProviderBase settingsProvider,
final @NotNull Predicate<Pair<TerminalWidget, String>> createNewSessionAction, @NotNull Disposable parent) {
super(settingsProvider, new Predicate<TerminalWidget>() {
@Override
@@ -71,22 +88,22 @@ public class JBTabbedTerminalWidget extends TabbedTerminalWidget implements Disp
Disposer.register(this, settingsProvider);
DnDSupport.createBuilder(this).setDropHandler(new DnDDropHandler() {
@Override
public void drop(DnDEvent event) {
if (event.getAttachedObject() instanceof TransferableWrapper) {
TransferableWrapper ao = (TransferableWrapper)event.getAttachedObject();
if (ao != null &&
ao.getPsiElements() != null &&
ao.getPsiElements().length == 1 &&
ao.getPsiElements()[0] instanceof PsiFileSystemItem) {
PsiFileSystemItem element = (PsiFileSystemItem)ao.getPsiElements()[0];
PsiDirectory dir = element instanceof PsiFile ? ((PsiFile)element).getContainingDirectory() : (PsiDirectory)element;
@Override
public void drop(DnDEvent event) {
if (event.getAttachedObject() instanceof TransferableWrapper) {
TransferableWrapper ao = (TransferableWrapper)event.getAttachedObject();
if (ao != null &&
ao.getPsiElements() != null &&
ao.getPsiElements().length == 1 &&
ao.getPsiElements()[0] instanceof PsiFileSystemItem) {
PsiFileSystemItem element = (PsiFileSystemItem)ao.getPsiElements()[0];
PsiDirectory dir = element instanceof PsiFile ? ((PsiFile)element).getContainingDirectory() : (PsiDirectory)element;
createNewSessionAction.apply(Pair.<TerminalWidget, String>create(JBTabbedTerminalWidget.this, dir.getVirtualFile().getPath()));
}
}
}
}
createNewSessionAction.apply(Pair.<TerminalWidget, String>create(JBTabbedTerminalWidget.this, dir.getVirtualFile().getPath()));
}
}
}
}
).install();
}
@@ -120,7 +137,17 @@ public class JBTabbedTerminalWidget extends TabbedTerminalWidget implements Disp
@Override
protected JediTermWidget createInnerTerminalWidget(TabbedSettingsProvider settingsProvider) {
return new JBTerminalWidget(myProject, mySettingsProvider, myParent);
JBTerminalWidget widget = new JBTerminalWidget(myProject, mySettingsProvider, myParent);
convertActions(widget, widget.getActions());
convertActions(widget.getTerminalPanel(), widget.getTerminalPanel().getActions(), new Predicate<KeyEvent>() {
@Override
public boolean apply(KeyEvent input) {
widget.getTerminalPanel().handleKeyEvent(input);
return true;
}
});
return widget;
}
@Override
@@ -180,12 +207,12 @@ public class JBTabbedTerminalWidget extends TabbedTerminalWidget implements Disp
@Override
public int indexOfComponent(Component component) {
for (int i = 0; i<myTabs.getTabCount(); i++) {
for (int i = 0; i < myTabs.getTabCount(); i++) {
if (component.equals(myTabs.getTabAt(i).getComponent())) {
return i;
}
}
return -1;
}
@@ -1,41 +0,0 @@
package org.jetbrains.plugins.terminal;
import com.intellij.ide.GeneralSettings;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.jediterm.terminal.Terminal;
import com.jediterm.terminal.TerminalDataStream;
import com.jediterm.terminal.TerminalStarter;
import com.jediterm.terminal.TtyConnector;
import com.jediterm.terminal.emulator.JediEmulator;
/**
* @author traff
*/
public class JBTerminalStarter extends TerminalStarter {
public JBTerminalStarter(Terminal terminal, TtyConnector ttyConnector, TerminalDataStream dataStream) {
super(terminal, ttyConnector, dataStream);
}
@Override
protected JediEmulator createEmulator(TerminalDataStream dataStream, Terminal terminal) {
return new JediEmulator(dataStream, terminal) {
@Override
protected void unsupported(char... sequenceChars) {
if (sequenceChars[0] == 7) { //ESC BEL
refreshAfterExecution();
}
else {
super.unsupported();
}
}
};
}
public static void refreshAfterExecution() {
if (GeneralSettings.getInstance().isSyncOnFrameActivation()) {
//we need to refresh local file system after a command has been executed in the terminal
LocalFileSystem.getInstance().refresh(true);
}
}
}
@@ -15,123 +15,14 @@
*/
package org.jetbrains.plugins.terminal;
import com.google.common.collect.Sets;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.ide.ui.UISettings;
import com.intellij.ide.ui.UISettingsListener;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.KeyboardShortcut;
import com.intellij.openapi.actionSystem.Shortcut;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.colors.*;
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.keymap.KeymapManager;
import com.intellij.openapi.options.FontSize;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.util.containers.HashMap;
import com.intellij.util.messages.MessageBusConnection;
import com.intellij.terminal.JBTerminalSystemSettingsProviderBase;
import com.jediterm.pty.PtyProcessTtyConnector;
import com.jediterm.terminal.TerminalColor;
import com.jediterm.terminal.TextStyle;
import com.jediterm.terminal.TtyConnector;
import com.jediterm.terminal.emulator.ColorPalette;
import com.jediterm.terminal.ui.settings.DefaultTabbedSettingsProvider;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.util.*;
import java.util.List;
/**
* @author traff
*/
public class JBTerminalSystemSettingsProvider extends DefaultTabbedSettingsProvider implements Disposable {
private Set<TerminalSettingsListener> myListeners = Sets.newHashSet();
private final MyColorSchemeDelegate myColorScheme;
public JBTerminalSystemSettingsProvider() {
myColorScheme = createBoundColorSchemeDelegate(null);
MessageBusConnection connection = ApplicationManager.getApplication().getMessageBus().connect(this);
connection.subscribe(UISettingsListener.TOPIC, new UISettingsListener() {
@Override
public void uiSettingsChanged(UISettings uiSettings) {
int size = consoleFontSize(JBTerminalSystemSettingsProvider.this.myColorScheme);
if (myColorScheme.getConsoleFontSize() != size) {
myColorScheme.setConsoleFontSize(size);
fireFontChanged();
}
}
});
connection.subscribe(EditorColorsManager.TOPIC, new EditorColorsListener() {
@Override
public void globalSchemeChange(EditorColorsScheme scheme) {
myColorScheme.updateGlobalScheme(scheme);
fireFontChanged();
}
});
}
private static int consoleFontSize(MyColorSchemeDelegate colorScheme) {
int size;
if (UISettings.getInstance().PRESENTATION_MODE) {
size = UISettings.getInstance().PRESENTATION_MODE_FONT_SIZE;
}
else {
size = colorScheme.getGlobal().getConsoleFontSize();
}
return size;
}
@Override
public KeyStroke[] getCopyKeyStrokes() {
return getKeyStrokesByActionId("$Copy");
}
@Override
public KeyStroke[] getPasteKeyStrokes() {
return getKeyStrokesByActionId("$Paste");
}
@Override
public KeyStroke[] getNextTabKeyStrokes() {
return getKeyStrokesByActionId("NextTab");
}
@Override
public KeyStroke[] getPreviousTabKeyStrokes() {
return getKeyStrokesByActionId("PreviousTab");
}
@Override
public KeyStroke[] getFindKeyStrokes() {
return getKeyStrokesByActionId("Find");
}
@Override
public ColorPalette getTerminalColorPalette() {
return new JBTerminalSchemeColorPalette(myColorScheme);
}
private KeyStroke[] getKeyStrokesByActionId(String actionId) {
List<KeyStroke> keyStrokes = new ArrayList<>();
Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts(actionId);
for (Shortcut sc : shortcuts) {
if (sc instanceof KeyboardShortcut) {
KeyStroke ks = ((KeyboardShortcut)sc).getFirstKeyStroke();
keyStrokes.add(ks);
}
}
return keyStrokes.toArray(new KeyStroke[keyStrokes.size()]);
}
public class JBTerminalSystemSettingsProvider extends JBTerminalSystemSettingsProviderBase {
@Override
public boolean shouldCloseTabOnLogout(TtyConnector ttyConnector) {
return TerminalOptionsProvider.Companion.getInstance().closeSessionOnLogout();
@@ -147,90 +38,6 @@ public class JBTerminalSystemSettingsProvider extends DefaultTabbedSettingsProvi
}
}
@Override
public float getLineSpace() {
return myColorScheme.getConsoleLineSpacing();
}
@Override
public boolean useInverseSelectionColor() {
return false;
}
@Override
public TextStyle getSelectionColor() {
return new TextStyle(TerminalColor.awt(myColorScheme.getColor(EditorColors.SELECTION_FOREGROUND_COLOR)),
TerminalColor.awt(myColorScheme.getColor(EditorColors.SELECTION_BACKGROUND_COLOR)));
}
@Override
public TextStyle getFoundPatternColor() {
return new TextStyle(TerminalColor.awt(myColorScheme.getAttributes(EditorColors.TEXT_SEARCH_RESULT_ATTRIBUTES).getForegroundColor()),
TerminalColor.awt(myColorScheme.getAttributes(EditorColors.TEXT_SEARCH_RESULT_ATTRIBUTES).getBackgroundColor()));
}
@Override
public TextStyle getDefaultStyle() {
return new TextStyle(TerminalColor.awt(myColorScheme.getDefaultForeground()), TerminalColor.awt(
myColorScheme.getDefaultBackground()));
}
@Override
public Font getTerminalFont() {
Font normalFont = Font.decode(getFontName());
if (normalFont == null) {
normalFont = super.getTerminalFont();
}
normalFont = normalFont.deriveFont(getTerminalFontSize());
return normalFont;
}
public String getFontName() {
List<String> fonts = myColorScheme.getConsoleFontPreferences().getEffectiveFontFamilies();
if (fonts.size() > 0) {
return fonts.get(0);
}
return "Monospaced-14";
}
@Override
public float getTerminalFontSize() {
return (float)myColorScheme.getConsoleFontSize();
}
@Override
public boolean useAntialiasing() {
return true; // we return true here because all the settings are checked again in UiSettings.setupAntialiasing
}
@Override
public int caretBlinkingMs() {
if (!EditorSettingsExternalizable.getInstance().isBlinkCaret()) {
return 0;
}
return EditorSettingsExternalizable.getInstance().getBlinkPeriod();
}
@Override
public int getBufferMaxLinesCount() {
final int linesCount = Registry.get("terminal.buffer.max.lines.count").asInteger();
if (linesCount > 0) {
return linesCount;
}
else {
return super.getBufferMaxLinesCount();
}
}
public EditorColorsScheme getColorScheme() {
return myColorScheme;
}
@Override
public boolean audibleBell() {
@@ -252,264 +59,13 @@ public class JBTerminalSystemSettingsProvider extends DefaultTabbedSettingsProvi
return TerminalOptionsProvider.Companion.getInstance().pasteOnMiddleMouseButton();
}
@NotNull
private static MyColorSchemeDelegate createBoundColorSchemeDelegate(@Nullable final EditorColorsScheme customGlobalScheme) {
return new MyColorSchemeDelegate(customGlobalScheme);
}
@Override
public boolean forceActionOnMouseReporting() {
return true;
}
@Override
public void dispose() {
}
private static class MyColorSchemeDelegate implements EditorColorsScheme {
private final FontPreferences myFontPreferences = new FontPreferences();
private final HashMap<TextAttributesKey, TextAttributes> myOwnAttributes = new HashMap<>();
private final HashMap<ColorKey, Color> myOwnColors = new HashMap<>();
private Map<EditorFontType, Font> myFontsMap = null;
private String myFaceName = null;
private EditorColorsScheme myGlobalScheme;
private int myConsoleFontSize;
private MyColorSchemeDelegate(@Nullable final EditorColorsScheme globalScheme) {
updateGlobalScheme(globalScheme);
myConsoleFontSize = consoleFontSize(this);
initFonts();
}
private EditorColorsScheme getGlobal() {
return myGlobalScheme;
}
@NotNull
@Override
public String getName() {
return getGlobal().getName();
}
protected void initFonts() {
String consoleFontName = getConsoleFontName();
int consoleFontSize = getConsoleFontSize();
myFontPreferences.clear();
myFontPreferences.register(consoleFontName, consoleFontSize);
myFontsMap = new EnumMap<>(EditorFontType.class);
Font plainFont = new Font(consoleFontName, Font.PLAIN, consoleFontSize);
Font boldFont = new Font(consoleFontName, Font.BOLD, consoleFontSize);
Font italicFont = new Font(consoleFontName, Font.ITALIC, consoleFontSize);
Font boldItalicFont = new Font(consoleFontName, Font.BOLD | Font.ITALIC, consoleFontSize);
myFontsMap.put(EditorFontType.PLAIN, plainFont);
myFontsMap.put(EditorFontType.BOLD, boldFont);
myFontsMap.put(EditorFontType.ITALIC, italicFont);
myFontsMap.put(EditorFontType.BOLD_ITALIC, boldItalicFont);
}
@Override
public void setName(String name) {
getGlobal().setName(name);
}
@Override
public TextAttributes getAttributes(TextAttributesKey key) {
if (myOwnAttributes.containsKey(key)) return myOwnAttributes.get(key);
return getGlobal().getAttributes(key);
}
@Override
public void setAttributes(@NotNull TextAttributesKey key, TextAttributes attributes) {
myOwnAttributes.put(key, attributes);
}
@NotNull
@Override
public Color getDefaultBackground() {
Color color = getGlobal().getColor(ConsoleViewContentType.CONSOLE_BACKGROUND_KEY);
return color != null ? color : getGlobal().getDefaultBackground();
}
@NotNull
@Override
public Color getDefaultForeground() {
Color foregroundColor = getGlobal().getAttributes(ConsoleViewContentType.NORMAL_OUTPUT_KEY).getForegroundColor();
return foregroundColor != null ? foregroundColor : getGlobal().getDefaultForeground();
}
@Override
public Color getColor(ColorKey key) {
if (myOwnColors.containsKey(key)) return myOwnColors.get(key);
return getGlobal().getColor(key);
}
@Override
public void setColor(ColorKey key, Color color) {
myOwnColors.put(key, color);
}
@NotNull
@Override
public FontPreferences getFontPreferences() {
return myGlobalScheme.getFontPreferences();
}
@Override
public void setFontPreferences(@NotNull FontPreferences preferences) {
throw new IllegalStateException();
}
@Override
public int getEditorFontSize() {
return getGlobal().getEditorFontSize();
}
@Override
public void setEditorFontSize(int fontSize) {
}
@Override
public FontSize getQuickDocFontSize() {
return myGlobalScheme.getQuickDocFontSize();
}
@Override
public void setQuickDocFontSize(@NotNull FontSize fontSize) {
myGlobalScheme.setQuickDocFontSize(fontSize);
}
@Override
public String getEditorFontName() {
return getGlobal().getEditorFontName();
}
@Override
public void setEditorFontName(String fontName) {
throw new IllegalStateException();
}
@Override
public Font getFont(EditorFontType key) {
if (myFontsMap != null) {
Font font = myFontsMap.get(key);
if (font != null) return font;
}
return getGlobal().getFont(key);
}
@Override
public void setFont(EditorFontType key, Font font) {
if (myFontsMap == null) {
initFonts();
}
myFontsMap.put(key, font);
}
@Override
public float getLineSpacing() {
return getGlobal().getLineSpacing();
}
@Override
public void setLineSpacing(float lineSpacing) {
getGlobal().setLineSpacing(lineSpacing);
}
@Override
@Nullable
public Object clone() {
return null;
}
@Override
public void readExternal(Element element) {
}
public void updateGlobalScheme(EditorColorsScheme scheme) {
myFontsMap = null;
myGlobalScheme = scheme == null ? EditorColorsManager.getInstance().getGlobalScheme() : scheme;
}
@NotNull
@Override
public FontPreferences getConsoleFontPreferences() {
return myFontPreferences;
}
@Override
public void setConsoleFontPreferences(@NotNull FontPreferences preferences) {
preferences.copyTo(myFontPreferences);
initFonts();
}
@Override
public String getConsoleFontName() {
if (myFaceName == null) {
return getGlobal().getConsoleFontName();
}
else {
return myFaceName;
}
}
@Override
public void setConsoleFontName(String fontName) {
myFaceName = fontName;
initFonts();
}
@Override
public int getConsoleFontSize() {
if (myConsoleFontSize == -1) {
return getGlobal().getConsoleFontSize();
}
else {
return myConsoleFontSize;
}
}
@Override
public void setConsoleFontSize(int fontSize) {
myConsoleFontSize = fontSize;
initFonts();
}
@Override
public float getConsoleLineSpacing() {
return getGlobal().getConsoleLineSpacing();
}
@Override
public void setConsoleLineSpacing(float lineSpacing) {
getGlobal().setConsoleLineSpacing(lineSpacing);
}
@NotNull
@Override
public Properties getMetaProperties() {
return myGlobalScheme.getMetaProperties();
}
}
public void addListener(TerminalSettingsListener listener) {
myListeners.add(listener);
}
public void removeListener(TerminalSettingsListener listener) {
myListeners.remove(listener);
}
public void fireFontChanged() {
for (TerminalSettingsListener l : myListeners) {
l.fontChanged();
}
public boolean overrideIdeShortcuts() {
return TerminalOptionsProvider.Companion.getInstance().overrideIdeShortcuts();
}
}
@@ -1,8 +0,0 @@
package org.jetbrains.plugins.terminal;
/**
* @author traff
*/
public interface TerminalSettingsListener {
void fontChanged();
}
+2 -9
View File
@@ -11,15 +11,6 @@
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="lang-api" />
<orderEntry type="module" module-name="platform-impl" />
<orderEntry type="module-library" exported="">
<library name="jediterm-pty">
<CLASSES>
<root url="jar://$MODULE_DIR$/lib/jediterm-pty-2.2.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</orderEntry>
<orderEntry type="library" name="Guava" level="project" />
<orderEntry type="library" name="pty4j" level="project" />
<orderEntry type="library" name="jna" level="project" />
@@ -27,5 +18,7 @@
<orderEntry type="module" module-name="remote-servers-api" />
<orderEntry type="module" module-name="remote-servers-impl" />
<orderEntry type="library" scope="TEST" name="JUnit4" level="project" />
<orderEntry type="module" module-name="testFramework" scope="TEST" />
<orderEntry type="library" name="jediterm-pty" level="project" />
</component>
</module>