2 * Copyright 2000-2013 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.execution.console;
18 import com.intellij.codeInsight.daemon.impl.HighlightInfo;
19 import com.intellij.execution.impl.ConsoleViewUtil;
20 import com.intellij.execution.ui.ConsoleViewContentType;
21 import com.intellij.ide.DataManager;
22 import com.intellij.ide.highlighter.HighlighterFactory;
23 import com.intellij.ide.impl.TypeSafeDataProviderAdapter;
24 import com.intellij.injected.editor.EditorWindow;
25 import com.intellij.lang.Language;
26 import com.intellij.lang.annotation.HighlightSeverity;
27 import com.intellij.openapi.Disposable;
28 import com.intellij.openapi.actionSystem.*;
29 import com.intellij.openapi.application.ApplicationManager;
30 import com.intellij.openapi.editor.*;
31 import com.intellij.openapi.editor.actions.EditorActionUtil;
32 import com.intellij.openapi.editor.colors.EditorColors;
33 import com.intellij.openapi.editor.colors.EditorColorsManager;
34 import com.intellij.openapi.editor.colors.EditorColorsScheme;
35 import com.intellij.openapi.editor.colors.impl.DelegateColorScheme;
36 import com.intellij.openapi.editor.event.*;
37 import com.intellij.openapi.editor.ex.EditorEx;
38 import com.intellij.openapi.editor.ex.FocusChangeListener;
39 import com.intellij.openapi.editor.ex.RangeHighlighterEx;
40 import com.intellij.openapi.editor.ex.util.EditorUtil;
41 import com.intellij.openapi.editor.highlighter.EditorHighlighter;
42 import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory;
43 import com.intellij.openapi.editor.highlighter.HighlighterIterator;
44 import com.intellij.openapi.editor.impl.DocumentMarkupModel;
45 import com.intellij.openapi.editor.impl.EditorFactoryImpl;
46 import com.intellij.openapi.editor.markup.*;
47 import com.intellij.openapi.fileEditor.*;
48 import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
49 import com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl;
50 import com.intellij.openapi.fileTypes.FileTypes;
51 import com.intellij.openapi.project.Project;
52 import com.intellij.openapi.util.Comparing;
53 import com.intellij.openapi.util.TextRange;
54 import com.intellij.openapi.util.text.StringUtil;
55 import com.intellij.openapi.util.text.StringUtilRt;
56 import com.intellij.openapi.vfs.VirtualFile;
57 import com.intellij.psi.PsiFile;
58 import com.intellij.psi.PsiManager;
59 import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
60 import com.intellij.testFramework.LightVirtualFile;
61 import com.intellij.ui.JBColor;
62 import com.intellij.ui.SideBorder;
63 import com.intellij.util.DocumentUtil;
64 import com.intellij.util.FileContentUtil;
65 import com.intellij.util.ObjectUtils;
66 import com.intellij.util.SingleAlarm;
67 import com.intellij.util.ui.AbstractLayoutManager;
68 import com.intellij.util.ui.UIUtil;
69 import org.jetbrains.annotations.NotNull;
70 import org.jetbrains.annotations.Nullable;
74 import java.awt.event.ComponentAdapter;
75 import java.awt.event.ComponentEvent;
76 import java.awt.event.KeyAdapter;
77 import java.awt.event.KeyEvent;
78 import java.util.Collections;
79 import java.util.concurrent.atomic.AtomicBoolean;
82 * @author Gregory.Shrago
83 * In case of REPL consider to use {@link LanguageConsoleBuilder}
85 public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider {
86 private static final int SEPARATOR_THICKNESS = 1;
87 private final Project myProject;
89 private final EditorEx myConsoleEditor;
90 private final EditorEx myHistoryViewer;
91 private final Document myEditorDocument;
92 private final LightVirtualFile myVirtualFile;
94 protected PsiFile myFile; // will change on language change
96 private final JPanel myPanel = new JPanel(new MyLayout());
97 private String myTitle;
99 private String myPrompt = "> ";
100 private final LightVirtualFile myHistoryFile;
101 private Editor myCurrentEditor;
103 private final AtomicBoolean myForceScrollToEnd = new AtomicBoolean(false);
104 private final SingleAlarm myUpdateQueue;
105 private Runnable myUiUpdateRunnable;
107 private boolean myShowSeparatorLine = true;
109 private final FocusChangeListener myFocusListener = new FocusChangeListener() {
111 public void focusGained(Editor editor) {
112 myCurrentEditor = editor;
116 public void focusLost(Editor editor) {
120 public LanguageConsoleImpl(@NotNull Project project, @NotNull String title, @NotNull Language language) {
121 this(project, title, language, true);
124 public LanguageConsoleImpl(@NotNull Project project, @NotNull String title, @NotNull Language language, boolean initComponents) {
125 this(project, title, new LightVirtualFile(title, language, ""), initComponents);
128 public LanguageConsoleImpl(@NotNull Project project, @NotNull String title, @NotNull LightVirtualFile lightFile, boolean initComponents) {
131 myVirtualFile = lightFile;
132 EditorFactory editorFactory = EditorFactory.getInstance();
133 myHistoryFile = new LightVirtualFile(getTitle() + ".history.txt", FileTypes.PLAIN_TEXT, "");
134 myEditorDocument = FileDocumentManager.getInstance().getDocument(lightFile);
135 assert myEditorDocument != null;
136 myFile = createFile(myVirtualFile, myEditorDocument, myProject);
137 myConsoleEditor = (EditorEx)editorFactory.createEditor(myEditorDocument, myProject);
138 myConsoleEditor.addFocusListener(myFocusListener);
139 myCurrentEditor = myConsoleEditor;
140 myHistoryViewer = (EditorEx)editorFactory.createViewer(((EditorFactoryImpl)editorFactory).createDocument(true), myProject);
141 myUpdateQueue = new SingleAlarm(new Runnable() {
144 if (isConsoleEditorEnabled()) {
145 myPanel.revalidate();
148 if (myUiUpdateRunnable != null) {
149 myUiUpdateRunnable.run();
154 // action shortcuts are not yet registered
155 ApplicationManager.getApplication().invokeLater(new Runnable() {
158 installEditorFactoryListener();
160 }, myProject.getDisposed());
162 if (initComponents) {
167 public void initComponents() {
168 final EditorColorsScheme colorsScheme = myConsoleEditor.getColorsScheme();
169 final DelegateColorScheme scheme = new DelegateColorScheme(colorsScheme) {
172 public Color getDefaultBackground() {
173 final Color color = getColor(ConsoleViewContentType.CONSOLE_BACKGROUND_KEY);
174 return color == null ? super.getDefaultBackground() : color;
177 myConsoleEditor.setColorsScheme(scheme);
178 myHistoryViewer.setColorsScheme(scheme);
179 myPanel.add(myHistoryViewer.getComponent());
180 myPanel.add(myConsoleEditor.getComponent());
182 DataManager.registerDataProvider(myPanel, new TypeSafeDataProviderAdapter(this));
184 myHistoryViewer.getComponent().addComponentListener(new ComponentAdapter() {
186 public void componentResized(ComponentEvent e) {
187 if (myForceScrollToEnd.getAndSet(false)) {
188 scrollHistoryToEnd();
193 public void componentShown(ComponentEvent e) {
197 setPromptInner(myPrompt);
200 public void setConsoleEditorEnabled(boolean consoleEditorEnabled) {
201 if (isConsoleEditorEnabled() == consoleEditorEnabled) {
205 if (consoleEditorEnabled) {
206 FileEditorManager.getInstance(getProject()).closeFile(myVirtualFile);
208 myPanel.add(myHistoryViewer.getComponent());
209 myPanel.add(myConsoleEditor.getComponent());
211 myHistoryViewer.setHorizontalScrollbarVisible(false);
212 myCurrentEditor = myConsoleEditor;
216 myPanel.add(myHistoryViewer.getComponent(), BorderLayout.CENTER);
217 myHistoryViewer.setHorizontalScrollbarVisible(true);
221 public void setShowSeparatorLine(boolean showSeparatorLine) {
222 myShowSeparatorLine = showSeparatorLine;
225 private void setupComponents() {
226 setupEditorDefault(myConsoleEditor);
227 setupEditorDefault(myHistoryViewer);
229 //noinspection PointlessBooleanExpression,ConstantConditions
230 if (SEPARATOR_THICKNESS > 0 && myShowSeparatorLine) {
231 myHistoryViewer.getComponent().setBorder(new SideBorder(JBColor.LIGHT_GRAY, SideBorder.BOTTOM));
233 myHistoryViewer.getComponent().setMinimumSize(new Dimension(0, 0));
234 myHistoryViewer.getComponent().setPreferredSize(new Dimension(0, 0));
235 myHistoryViewer.setCaretEnabled(false);
237 myConsoleEditor.addEditorMouseListener(EditorActionUtil.createEditorPopupHandler(IdeActions.GROUP_CONSOLE_EDITOR_POPUP));
238 myConsoleEditor.setHighlighter(EditorHighlighterFactory.getInstance().createEditorHighlighter(myProject, myVirtualFile));
240 final VisibleAreaListener areaListener = new VisibleAreaListener() {
242 public void visibleAreaChanged(VisibleAreaEvent e) {
243 final int offset = myConsoleEditor.getScrollingModel().getHorizontalScrollOffset();
244 final ScrollingModel model = myHistoryViewer.getScrollingModel();
245 final int historyOffset = model.getHorizontalScrollOffset();
246 if (historyOffset != offset) {
248 model.disableAnimation();
249 model.scrollHorizontally(offset);
252 model.enableAnimation();
257 myConsoleEditor.getScrollingModel().addVisibleAreaListener(areaListener);
258 final DocumentAdapter docListener = new DocumentAdapter() {
260 public void documentChanged(final DocumentEvent e) {
261 queueUiUpdate(false);
264 myEditorDocument.addDocumentListener(docListener, this);
265 myHistoryViewer.getDocument().addDocumentListener(docListener, this);
267 myHistoryViewer.getContentComponent().addKeyListener(new KeyAdapter() {
269 public void keyTyped(KeyEvent event) {
270 if (isConsoleEditorEnabled() && UIUtil.isReallyTypedEvent(event)) {
271 myConsoleEditor.getContentComponent().requestFocus();
272 myConsoleEditor.processKeyTyped(event);
276 for (AnAction action : createActions()) {
277 action.registerCustomShortcutSet(action.getShortcutSet(), myConsoleEditor.getComponent());
279 EmptyAction.registerActionShortcuts(myHistoryViewer.getComponent(), myConsoleEditor.getComponent());
282 public boolean isConsoleEditorEnabled() {
283 return myPanel.getComponentCount() > 1;
287 protected AnAction[] createActions() {
288 return AnAction.EMPTY_ARRAY;
291 public void setTextToEditor(@NotNull final String text) {
292 ApplicationManager.getApplication().runWriteAction(new Runnable() {
295 myConsoleEditor.getDocument().setText(text);
301 protected void setupEditorDefault(@NotNull EditorEx editor) {
302 ConsoleViewUtil.setupConsoleEditor(editor, false, false);
303 editor.getContentComponent().setFocusCycleRoot(false);
304 editor.setHorizontalScrollbarVisible(false);
305 editor.setVerticalScrollbarVisible(true);
306 editor.setBorder(null);
308 final EditorSettings editorSettings = editor.getSettings();
309 editorSettings.setAdditionalLinesCount(myHistoryViewer == editor ? 0 : 2);
310 editorSettings.setAdditionalColumnsCount(1);
311 editorSettings.setRightMarginShown(false);
314 public void setUiUpdateRunnable(Runnable uiUpdateRunnable) {
315 assert myUiUpdateRunnable == null : "can be set only once";
316 myUiUpdateRunnable = uiUpdateRunnable;
319 public void flushAllUiUpdates() {
320 myUpdateQueue.flush();
323 @SuppressWarnings("UnusedDeclaration")
325 public LightVirtualFile getHistoryFile() {
326 return myHistoryFile;
330 public String getPrompt() {
334 public void setPrompt(@Nullable String prompt) {
335 // always add space to the prompt otherwise it may look ugly
336 myPrompt = prompt != null && !prompt.endsWith(" ") ? prompt + " " : prompt;
337 setPromptInner(myPrompt);
340 private void setPromptInner(@Nullable final String prompt) {
341 UIUtil.invokeAndWaitIfNeeded(new Runnable() {
344 myConsoleEditor.setPrefixTextAndAttributes(prompt, ConsoleViewContentType.USER_INPUT.getAttributes());
345 if (myPanel.isVisible()) {
346 queueUiUpdate(false);
352 public void setEditable(boolean editable) {
353 myConsoleEditor.setRendererMode(!editable);
354 setPromptInner(editable ? myPrompt : "");
357 public boolean isEditable() {
358 return !myConsoleEditor.isRendererMode();
362 public PsiFile getFile() {
367 public VirtualFile getVirtualFile() {
368 return myVirtualFile;
372 public EditorEx getHistoryViewer() {
373 return myHistoryViewer;
377 public Document getEditorDocument() {
378 return myEditorDocument;
382 public EditorEx getConsoleEditor() {
383 return myConsoleEditor;
387 public Project getProject() {
392 public String getTitle() {
396 public void setTitle(@NotNull String title) {
400 public void printToHistory(@NotNull CharSequence text, @NotNull TextAttributes attributes) {
401 ApplicationManager.getApplication().assertIsDispatchThread();
402 text = StringUtilRt.unifyLineSeparators(text);
403 final boolean scrollToEnd = shouldScrollHistoryToEnd();
404 addTextToHistory(text, attributes);
406 scrollHistoryToEnd();
408 queueUiUpdate(scrollToEnd);
411 protected void addTextToHistory(@Nullable CharSequence text, @Nullable TextAttributes attributes) {
412 if (StringUtil.isEmpty(text) || attributes == null) {
416 Document history = myHistoryViewer.getDocument();
417 int offset = appendToHistoryDocument(history, text);
418 DocumentMarkupModel.forDocument(history, myProject, true).addRangeHighlighter(offset, offset + text.length(), HighlighterLayer.SYNTAX, attributes,
419 HighlighterTargetArea.EXACT_RANGE);
422 @SuppressWarnings("UnusedDeclaration")
425 * @deprecated Use {@link LanguageConsoleBuilder},
426 * {@link LanguageConsoleBuilder#registerExecuteAction)} or
427 * {@link ConsoleExecuteAction#prepareRunExecuteAction)}
429 * to remove in IDEA 15
431 public String addCurrentToHistory(@NotNull TextRange textRange, boolean erase, boolean preserveMarkup) {
432 return addToHistoryInner(textRange, myConsoleEditor, erase, preserveMarkup);
435 public String addToHistory(@NotNull TextRange textRange, @NotNull EditorEx editor, boolean preserveMarkup) {
436 return addToHistoryInner(textRange, editor, false, preserveMarkup);
440 public String prepareExecuteAction(boolean addToHistory, boolean preserveMarkup, boolean clearInput) {
441 Editor editor = getCurrentEditor();
442 Document document = editor.getDocument();
443 String text = document.getText();
444 TextRange range = new TextRange(0, document.getTextLength());
446 editor.getSelectionModel().setSelection(range.getStartOffset(), range.getEndOffset());
450 addToHistoryInner(range, myConsoleEditor, clearInput, preserveMarkup);
452 else if (clearInput) {
459 protected String addToHistoryInner(@NotNull final TextRange textRange, @NotNull final EditorEx editor, boolean erase, final boolean preserveMarkup) {
460 ApplicationManager.getApplication().assertIsDispatchThread();
462 String result = addTextRangeToHistory(textRange, editor, preserveMarkup);
464 DocumentUtil.writeInRunUndoTransparentAction(new Runnable() {
467 editor.getDocument().deleteString(textRange.getStartOffset(), textRange.getEndOffset());
471 // always scroll to end on user input
472 scrollHistoryToEnd();
477 public boolean shouldScrollHistoryToEnd() {
478 final Rectangle visibleArea = myHistoryViewer.getScrollingModel().getVisibleArea();
479 final Dimension contentSize = myHistoryViewer.getContentSize();
480 return contentSize.getHeight() - visibleArea.getMaxY() < 2 * myHistoryViewer.getLineHeight();
483 private void scrollHistoryToEnd() {
484 final int lineCount = myHistoryViewer.getDocument().getLineCount();
485 if (lineCount == 0) {
488 myHistoryViewer.getCaretModel().moveToOffset(myHistoryViewer.getDocument().getLineStartOffset(lineCount - 1), false);
489 myHistoryViewer.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
493 protected String addTextRangeToHistory(@NotNull TextRange textRange, @NotNull EditorEx consoleEditor, boolean preserveMarkup) {
494 doAddPromptToHistory();
496 final Document history = myHistoryViewer.getDocument();
497 final MarkupModel markupModel = DocumentMarkupModel.forDocument(history, myProject, true);
498 final int localStartOffset = textRange.getStartOffset();
500 EditorHighlighter highlighter;
501 if (consoleEditor instanceof EditorWindow) {
502 PsiFile file = ((EditorWindow)consoleEditor).getInjectedFile();
503 highlighter = HighlighterFactory.createHighlighter(file.getVirtualFile(), EditorColorsManager.getInstance().getGlobalScheme(), getProject());
504 String fullText = InjectedLanguageUtil.getUnescapedText(file, null, null);
505 highlighter.setText(fullText);
506 text = textRange.substring(fullText);
509 text = consoleEditor.getDocument().getText(textRange);
510 highlighter = consoleEditor.getHighlighter();
512 //offset can be changed after text trimming after insert due to buffer constraints
513 int offset = appendToHistoryDocument(history, text);
515 final HighlighterIterator iterator = highlighter.createIterator(localStartOffset);
516 final int localEndOffset = textRange.getEndOffset();
517 while (!iterator.atEnd()) {
518 final int itStart = iterator.getStart();
519 if (itStart > localEndOffset) {
522 final int itEnd = iterator.getEnd();
523 if (itEnd >= localStartOffset) {
524 final int start = Math.max(itStart, localStartOffset) - localStartOffset + offset;
525 final int end = Math.min(itEnd, localEndOffset) - localStartOffset + offset;
526 markupModel.addRangeHighlighter(start, end, HighlighterLayer.SYNTAX, iterator.getTextAttributes(),
527 HighlighterTargetArea.EXACT_RANGE);
531 if (preserveMarkup) {
532 duplicateHighlighters(markupModel, DocumentMarkupModel.forDocument(consoleEditor.getDocument(), myProject, true), offset, textRange);
533 // don't copy editor markup model, i.e. brace matcher, spell checker, etc.
534 // duplicateHighlighters(markupModel, consoleEditor.getMarkupModel(), offset, textRange);
536 if (!text.endsWith("\n")) {
537 appendToHistoryDocument(history, "\n");
542 protected void doAddPromptToHistory() {
543 addTextToHistory(myPrompt, ConsoleViewContentType.USER_INPUT.getAttributes());
546 // returns the real (cyclic-buffer-aware) start offset of the inserted text
547 protected int appendToHistoryDocument(@NotNull Document history, @NotNull CharSequence text) {
548 ApplicationManager.getApplication().assertIsDispatchThread();
549 history.insertString(history.getTextLength(), text);
550 return history.getTextLength() - text.length();
553 private static void duplicateHighlighters(@NotNull MarkupModel to, @NotNull MarkupModel from, int offset, @NotNull TextRange textRange) {
554 for (RangeHighlighter rangeHighlighter : from.getAllHighlighters()) {
555 if (!rangeHighlighter.isValid()) {
558 Object tooltip = rangeHighlighter.getErrorStripeTooltip();
559 HighlightInfo highlightInfo = tooltip instanceof HighlightInfo? (HighlightInfo)tooltip : null;
560 if (highlightInfo != null) {
561 if (highlightInfo.getSeverity() != HighlightSeverity.INFORMATION) {
564 if (highlightInfo.type.getAttributesKey() == EditorColors.IDENTIFIER_UNDER_CARET_ATTRIBUTES) {
568 final int localOffset = textRange.getStartOffset();
569 final int start = Math.max(rangeHighlighter.getStartOffset(), localOffset) - localOffset;
570 final int end = Math.min(rangeHighlighter.getEndOffset(), textRange.getEndOffset()) - localOffset;
574 final RangeHighlighter h = to.addRangeHighlighter(start + offset, end + offset, rangeHighlighter.getLayer(), rangeHighlighter.getTextAttributes(), rangeHighlighter.getTargetArea());
575 ((RangeHighlighterEx)h).setAfterEndOfLine(((RangeHighlighterEx)rangeHighlighter).isAfterEndOfLine());
580 public JComponent getComponent() {
584 public void queueUiUpdate(boolean forceScrollToEnd) {
585 myForceScrollToEnd.compareAndSet(false, forceScrollToEnd);
586 myUpdateQueue.request();
590 public void dispose() {
591 final EditorFactory editorFactory = EditorFactory.getInstance();
592 editorFactory.releaseEditor(myConsoleEditor);
593 editorFactory.releaseEditor(myHistoryViewer);
595 final FileEditorManager editorManager = FileEditorManager.getInstance(getProject());
596 if (editorManager.isFileOpen(myVirtualFile)) {
597 editorManager.closeFile(myVirtualFile);
602 public void calcData(@NotNull DataKey key, @NotNull DataSink sink) {
603 if (OpenFileDescriptor.NAVIGATE_IN_EDITOR == key) {
604 sink.put(OpenFileDescriptor.NAVIGATE_IN_EDITOR, myConsoleEditor);
606 else if (getProject().isInitialized()) {
607 sink.put(key, FileEditorManagerEx.getInstanceEx(getProject()).getData(key.getName(), myConsoleEditor, myVirtualFile));
611 private void installEditorFactoryListener() {
612 FileEditorManagerAdapter fileEditorListener = new FileEditorManagerAdapter() {
614 public void fileOpened(@NotNull FileEditorManager source, @NotNull VirtualFile file) {
615 if (myConsoleEditor == null || !Comparing.equal(file, myVirtualFile)) {
619 Editor selectedTextEditor = source.getSelectedTextEditor();
620 for (FileEditor fileEditor : source.getAllEditors(file)) {
621 if (!(fileEditor instanceof TextEditor)) {
625 final EditorEx editor = (EditorEx)((TextEditor)fileEditor).getEditor();
626 editor.addFocusListener(myFocusListener);
627 if (selectedTextEditor == editor) { // already focused
628 myCurrentEditor = editor;
630 EmptyAction.registerActionShortcuts(editor.getComponent(), myConsoleEditor.getComponent());
631 editor.getCaretModel().addCaretListener(new CaretListener() {
633 public void caretPositionChanged(CaretEvent e) {
634 queueUiUpdate(false);
638 queueUiUpdate(false);
642 public void fileClosed(@NotNull FileEditorManager source, @NotNull VirtualFile file) {
643 if (!Comparing.equal(file, myVirtualFile)) {
646 if (myUiUpdateRunnable != null && !Boolean.TRUE.equals(file.getUserData(FileEditorManagerImpl.CLOSING_TO_REOPEN))) {
647 if (myCurrentEditor != null && myCurrentEditor.isDisposed()) {
648 myCurrentEditor = null;
650 ApplicationManager.getApplication().runReadAction(myUiUpdateRunnable);
654 myProject.getMessageBus().connect(this).subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, fileEditorListener);
655 FileEditorManager editorManager = FileEditorManager.getInstance(getProject());
656 if (editorManager.isFileOpen(myVirtualFile)) {
657 fileEditorListener.fileOpened(editorManager, myVirtualFile);
661 public Editor getCurrentEditor() {
662 return ObjectUtils.chooseNotNull(myCurrentEditor, myConsoleEditor);
665 public Language getLanguage() {
666 return myVirtualFile.getLanguage();
669 public void setLanguage(@NotNull Language language) {
670 myVirtualFile.setLanguage(language);
671 myVirtualFile.setContent(myEditorDocument, myEditorDocument.getText(), false);
672 FileContentUtil.reparseFiles(myProject, Collections.<VirtualFile>singletonList(myVirtualFile), false);
673 myFile = createFile(myVirtualFile, myEditorDocument, myProject);
676 public void setInputText(@NotNull final String query) {
677 DocumentUtil.writeInRunUndoTransparentAction(new Runnable() {
680 myConsoleEditor.getDocument().setText(query);
686 protected PsiFile createFile(@NotNull LightVirtualFile virtualFile, @NotNull Document document, @NotNull Project project) {
687 return ObjectUtils.assertNotNull(PsiManager.getInstance(project).findFile(virtualFile));
690 private class MyLayout extends AbstractLayoutManager {
692 public Dimension preferredLayoutSize(final Container parent) {
693 return new Dimension(0, 0);
697 public void layoutContainer(@NotNull final Container parent) {
698 final int componentCount = parent.getComponentCount();
699 if (componentCount == 0) {
703 final EditorEx history = myHistoryViewer;
704 final EditorEx editor = componentCount == 2 ? myConsoleEditor : null;
705 if (editor == null) {
706 parent.getComponent(0).setBounds(parent.getBounds());
710 final Dimension panelSize = parent.getSize();
711 if (panelSize.getHeight() <= 0) {
714 final Dimension historySize = history.getContentSize();
715 final Dimension editorSize = editor.getContentSize();
716 final Dimension newEditorSize = new Dimension();
719 final int width = Math.max(editorSize.width, historySize.width);
720 newEditorSize.width = width + editor.getScrollPane().getHorizontalScrollBar().getHeight();
721 history.getSoftWrapModel().forceAdditionalColumnsUsage();
722 editor.getSettings().setAdditionalColumnsCount(2 + (width - editorSize.width) / EditorUtil.getSpaceWidth(Font.PLAIN, editor));
723 history.getSettings().setAdditionalColumnsCount(2 + (width - historySize.width) / EditorUtil.getSpaceWidth(Font.PLAIN, history));
726 if (historySize.width == 0) {
727 historySize.height = 0;
729 final int minHistorySize = historySize.height > 0 ? 2 * history.getLineHeight() + (myShowSeparatorLine ? SEPARATOR_THICKNESS : 0) : 0;
730 final int minEditorSize = editor.isViewer() ? 0 : editor.getLineHeight();
731 final int editorPreferred = editor.isViewer() ? 0 : Math.max(minEditorSize, editorSize.height);
732 final int historyPreferred = Math.max(minHistorySize, historySize.height);
733 if (panelSize.height < minEditorSize) {
734 newEditorSize.height = panelSize.height;
736 else if (panelSize.height < editorPreferred) {
737 newEditorSize.height = panelSize.height - minHistorySize;
739 else if (panelSize.height < editorPreferred + historyPreferred) {
740 newEditorSize.height = editorPreferred;
743 newEditorSize.height = editorPreferred == 0 ? 0 : panelSize.height - historyPreferred;
745 final Dimension newHistorySize = new Dimension(width, panelSize.height - newEditorSize.height);
748 editor.getComponent().setBounds(0, newHistorySize.height, panelSize.width, newEditorSize.height);
749 myForceScrollToEnd.compareAndSet(false, shouldScrollHistoryToEnd());
750 history.getComponent().setBounds(0, 0, panelSize.width, newHistorySize.height);