4
4
5
5
package net .orfjackal .sbt .plugin ;
6
6
7
- import com .intellij .execution .console .* ;
7
+ import com .intellij .execution .console .LanguageConsoleImpl ;
8
8
import com .intellij .execution .filters .*;
9
9
import com .intellij .execution .impl .ConsoleViewImpl ;
10
- import com .intellij .execution .process .ConsoleHistoryModel ;
11
10
import com .intellij .execution .process .ProcessAdapter ;
12
11
import com .intellij .execution .process .ProcessEvent ;
13
12
import com .intellij .execution .process .ProcessHandler ;
14
- import com .intellij .execution .runners .ConsoleExecuteActionHandler ;
15
13
import com .intellij .execution .ui .ConsoleView ;
16
14
import com .intellij .execution .ui .ConsoleViewContentType ;
17
15
import com .intellij .openapi .actionSystem .*;
18
16
import com .intellij .openapi .application .ApplicationManager ;
19
- import com .intellij .openapi .application .ex .ApplicationManagerEx ;
20
17
import com .intellij .openapi .diagnostic .Logger ;
21
- import com .intellij .openapi .editor .Document ;
22
- import com .intellij .openapi .editor .ScrollingModel ;
23
- import com .intellij .openapi .editor .event .VisibleAreaEvent ;
24
- import com .intellij .openapi .editor .event .VisibleAreaListener ;
25
- import com .intellij .openapi .editor .ex .EditorEx ;
26
18
import com .intellij .openapi .project .DumbAwareAction ;
27
19
import com .intellij .openapi .project .Project ;
28
20
import com .intellij .openapi .ui .SimpleToolWindowPanel ;
29
21
import com .intellij .openapi .util .IconLoader ;
30
22
import com .intellij .openapi .util .Key ;
31
- import com .intellij .openapi .util .TextRange ;
32
23
import com .intellij .openapi .wm .ToolWindow ;
33
24
import com .intellij .openapi .wm .ToolWindowManager ;
34
25
import com .intellij .psi .search .GlobalSearchScope ;
35
- import com .intellij .testFramework .LightVirtualFile ;
36
- import com .intellij .ui .components .JBScrollBar ;
37
26
import com .intellij .ui .content .Content ;
38
27
import com .intellij .ui .content .ContentFactory ;
39
- import com .intellij .util .ReflectionUtil ;
40
- import com .intellij .util .ui .UIUtil ;
41
- import net .orfjackal .sbt .plugin .sbtlang .SbtFileType ;
42
- import net .orfjackal .sbt .plugin .sbtlang .SbtLanguage ;
43
- import org .jetbrains .annotations .NotNull ;
44
28
45
29
import javax .swing .*;
46
- import javax .swing .plaf .basic .BasicScrollBarUI ;
47
30
import java .awt .*;
48
- import java .lang .reflect .Field ;
49
- import java .util .*;
31
+ import java .util .Arrays ;
50
32
import java .util .concurrent .atomic .AtomicBoolean ;
51
33
52
34
public class SbtConsole {
@@ -69,17 +51,16 @@ public class SbtConsole {
69
51
public SbtConsole (String title , Project project , SbtRunnerComponent runnerComponent ) {
70
52
this .title = title ;
71
53
this .project = project ;
72
- this .consoleView = createConsoleView (project , this );
54
+ this .consoleView = createConsoleView (project );
73
55
this .runnerComponent = runnerComponent ;
74
56
}
75
57
76
- private static ConsoleView createConsoleView (Project project , SbtConsole sbtConsole ) {
77
- boolean useClassicConsole = "true" .equalsIgnoreCase (System .getProperty ("idea.sbt.plugin.classic" ));
78
- if (useClassicConsole ) {
79
- return createTextConsole (project );
80
- } else {
81
- return createLanguageConsole (project , sbtConsole );
82
- }
58
+ private static ConsoleView createConsoleView (Project project ) {
59
+ // TODO can we figure out how to make this a LanguageConsole with IDEA 14.1+
60
+ // We need that for console history
61
+ ConsoleView consoleView = createTextConsole (project );
62
+ addFilters (project , consoleView );
63
+ return consoleView ;
83
64
}
84
65
85
66
private static ConsoleView createTextConsole (final Project project ) {
@@ -94,150 +75,7 @@ private static ConsoleView createTextConsole(final Project project) {
94
75
return builder .getConsole ();
95
76
}
96
77
97
- private static ConsoleView createLanguageConsole (final Project project , final SbtConsole sbtConsole ) {
98
- LightVirtualFile lightFile = new LightVirtualFile ("SBT" , SbtLanguage .INSTANCE , "" );
99
- lightFile .setFileType (SbtFileType .INSTANCE );
100
- final LanguageConsoleImpl sbtLanguageConsole = new LanguageConsoleImpl (project , "SBT" , lightFile , false );
101
- sbtLanguageConsole .setShowSeparatorLine (false );
102
- sbtLanguageConsole .initComponents ();
103
- enableLinkedHorizontalScrollFromHistoryViewer (sbtLanguageConsole );
104
-
105
- // important to only have one history controller, even if SBT is restarted.
106
- final ConsoleHistoryModel myConsoleHistoryModel = new ConsoleHistoryModel ();
107
- final ConsoleHistoryController historyController = new ConsoleHistoryController ("scala" , null , sbtLanguageConsole , myConsoleHistoryModel );
108
- historyController .install ();
109
- LanguageConsoleViewImpl consoleView = new LanguageConsoleViewImpl (sbtLanguageConsole ) {
110
- @ Override
111
- public void attachToProcess (ProcessHandler processHandler ) {
112
- super .attachToProcess (processHandler );
113
- ConsoleExecuteActionHandler executeActionHandler = new ConsoleExecuteActionHandler (processHandler , false ) {
114
- @ Override
115
- public ConsoleHistoryModel getConsoleHistoryModel () {
116
- return myConsoleHistoryModel ;
117
- }
118
-
119
- public void runExecuteAction (LanguageConsoleImpl languageConsole ) {
120
- EditorEx consoleEditor = languageConsole .getConsoleEditor ();
121
- consoleEditor .setCaretEnabled (false );
122
-
123
- super .runExecuteAction (languageConsole );
124
-
125
- // hide the prompts until the command has completed.
126
- languageConsole .setPrompt (" " );
127
- consoleEditor .setCaretEnabled (true );
128
- }
129
- protected void execute (@ NotNull String text , @ NotNull LanguageConsoleView console ) {
130
- EditorEx consoleEditor = console .getConsole ().getConsoleEditor ();
131
- consoleEditor .setCaretEnabled (false );
132
- super .execute (text , console );
133
- // hide the prompts until the command has completed.
134
- console .getConsole ().setPrompt (" " );
135
- consoleEditor .setCaretEnabled (true );
136
- }
137
-
138
- };
139
- // SBT echos the command, don't add it to the output a second time.
140
- executeActionHandler .setAddCurrentToHistory (true );
141
- try {
142
- java .util .List <Field > fields = ReflectionUtil .collectFields (executeActionHandler .getClass ());
143
- for (Field field : fields ) {
144
- if (field .getType () == ConsoleHistoryModel .class ) {
145
- field .setAccessible (true );
146
- field .set (executeActionHandler , myConsoleHistoryModel );
147
- }
148
- }
149
- } catch (Exception err ) {
150
- logger .warn ("Unable to reflectively set field in " + executeActionHandler .getClass () + ", history in the SBT console may not work." , err );
151
- }
152
- AnAction action = new ConsoleExecuteAction (this , executeActionHandler );
153
- action .registerCustomShortcutSet (action .getShortcutSet (), sbtLanguageConsole .getComponent ());
154
- }
155
-
156
- @ Override
157
- public boolean hasDeferredOutput () {
158
- return super .hasDeferredOutput ();
159
- }
160
- };
161
- sbtLanguageConsole .setPrompt (" " );
162
- addFilters (project , consoleView );
163
-
164
- return consoleView ;
165
- }
166
-
167
- private static void enableLinkedHorizontalScrollFromHistoryViewer (final LanguageConsoleImpl sbtLanguageConsole ) {
168
- JBScrollBar horizontalScrollBar = new JBScrollBar (Adjustable .HORIZONTAL );
169
- horizontalScrollBar .setUI (new BasicScrollBarUI () {
170
- @ Override
171
- public Dimension getPreferredSize (JComponent c ) {
172
- return new Dimension (0 , 0 );
173
- }
174
- });
175
- sbtLanguageConsole .getHistoryViewer ().getScrollPane ().setHorizontalScrollBar (horizontalScrollBar );
176
- sbtLanguageConsole .getHistoryViewer ().setHorizontalScrollbarVisible (true );
177
-
178
- final VisibleAreaListener areaListener = new VisibleAreaListener () {
179
- public void visibleAreaChanged (VisibleAreaEvent e ) {
180
- final int offset = sbtLanguageConsole .getHistoryViewer ().getScrollingModel ().getHorizontalScrollOffset ();
181
- final ScrollingModel model = sbtLanguageConsole .getConsoleEditor ().getScrollingModel ();
182
- final int historyOffset = model .getHorizontalScrollOffset ();
183
- if (historyOffset != offset ) {
184
- try {
185
- model .disableAnimation ();
186
- model .scrollHorizontally (offset );
187
- } finally {
188
- model .enableAnimation ();
189
- }
190
- }
191
- }
192
- };
193
- sbtLanguageConsole .getHistoryViewer ().getScrollingModel ().addVisibleAreaListener (areaListener );
194
- }
195
-
196
- public void enablePrompt () {
197
- if (consoleView instanceof LanguageConsoleViewImpl ) {
198
- final LanguageConsoleViewImpl languageConsoleView = (LanguageConsoleViewImpl ) consoleView ;
199
- final LanguageConsoleImpl console = languageConsoleView .getConsole ();
200
-
201
- UIUtil .invokeAndWaitIfNeeded (new Runnable () {
202
- public void run () {
203
- languageConsoleView .flushDeferredText ();
204
- ApplicationManagerEx .getApplication ().runWriteAction (new Runnable () {
205
- public void run () {
206
- Document document = console .getHistoryViewer ().getDocument ();
207
- EditorEx consoleEditor = console .getConsoleEditor ();
208
- if (deleteTextFromEnd (document , "\n > " , "\n " )) {
209
- console .setPrompt ("> " );
210
- } else if (deleteTextFromEnd (document , "\n scala> " , "\n " )) {
211
- console .setPrompt ("scala> " );
212
- // not sure why this works, but it moves the caret to the end of the prompt.
213
- // without this, it apppears between the `c` and `a`.
214
- consoleEditor .getCaretModel ().moveCaretRelatively (-1 , 0 , false , false , false );
215
- }
216
- consoleEditor .setCaretEnabled (true );
217
- }
218
- });
219
- }
220
- });
221
- }
222
- }
223
-
224
- private static boolean deleteTextFromEnd (final Document document , String lastPrompt , final String replacement ) {
225
- final int startOffset = document .getTextLength () - lastPrompt .length ();
226
- if (startOffset > 0 ) {
227
- String text = document .getText (TextRange .create (startOffset , document .getTextLength ()));
228
- if (text .equals (lastPrompt )) {
229
- UIUtil .invokeAndWaitIfNeeded (new Runnable () {
230
- public void run () {
231
- document .replaceString (startOffset , document .getTextLength (), replacement );
232
- }
233
- });
234
- return true ;
235
- }
236
- }
237
- return false ;
238
- }
239
-
240
- private static void addFilters (Project project , LanguageConsoleViewImpl consoleView ) {
78
+ private static void addFilters (Project project , ConsoleView consoleView ) {
241
79
consoleView .addMessageFilter (new ExceptionFilter (GlobalSearchScope .allScope (project )));
242
80
consoleView .addMessageFilter (new RegexpFilter (project , CONSOLE_FILTER_REGEXP ));
243
81
consoleView .addMessageFilter (new SbtColorizerFilter ());
0 commit comments