Skip to content

Commit 44f6c10

Browse files
committed
Action handler workaround
1 parent 63da129 commit 44f6c10

2 files changed

Lines changed: 278 additions & 69 deletions

File tree

src/main/java/org/exbin/bined/intellij/BinEdPluginStartupActivity.java

Lines changed: 218 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import com.intellij.openapi.application.ApplicationManager;
2424
import com.intellij.openapi.editor.Caret;
2525
import com.intellij.openapi.editor.Editor;
26+
import com.intellij.openapi.editor.actionSystem.DocCommandGroupId;
2627
import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
2728
import com.intellij.openapi.editor.actionSystem.EditorActionManager;
2829
import com.intellij.openapi.extensions.ExtensionPointAdapter;
@@ -53,6 +54,7 @@
5354
import com.intellij.ui.components.JBTextField;
5455
import com.intellij.util.messages.MessageBus;
5556
import com.intellij.util.messages.MessageBusConnection;
57+
import java.lang.Deprecated;
5658
import kotlin.Unit;
5759
import kotlin.coroutines.Continuation;
5860
import org.exbin.bined.intellij.api.BinaryViewData;
@@ -64,6 +66,8 @@
6466
import org.exbin.bined.intellij.options.impl.IntegrationOptionsImpl;
6567
import org.exbin.bined.intellij.preferences.IntegrationPreferences;
6668
import org.exbin.bined.intellij.search.BinEdIntelliJComponentSearch;
69+
import org.exbin.bined.swing.CodeAreaCommandHandler;
70+
import org.exbin.bined.swing.CodeAreaCore;
6771
import org.exbin.framework.App;
6872
import org.exbin.framework.Module;
6973
import org.exbin.framework.ModuleProvider;
@@ -147,6 +151,7 @@
147151
import javax.swing.ImageIcon;
148152
import javax.swing.JCheckBox;
149153
import javax.swing.JCheckBoxMenuItem;
154+
import javax.swing.JComponent;
150155
import javax.swing.JLabel;
151156
import javax.swing.JMenu;
152157
import javax.swing.JMenuItem;
@@ -158,6 +163,7 @@
158163
import java.awt.Graphics;
159164
import java.awt.Graphics2D;
160165
import java.awt.event.ActionEvent;
166+
import java.awt.event.KeyEvent;
161167
import java.net.MalformedURLException;
162168
import java.net.URL;
163169
import java.util.ArrayList;
@@ -210,6 +216,210 @@ public static void initialize() {
210216
appModuleProvider.createModules();
211217
App.setModuleProvider(appModuleProvider);
212218
appModuleProvider.init();
219+
220+
// Editor actions overtakes action events
221+
// No other method how to handle this was found so far...
222+
registerActionHandler(IdeActions.ACTION_EDITOR_MOVE_LINE_START, 0, KeyEvent.VK_HOME);
223+
registerActionHandler(IdeActions.ACTION_EDITOR_MOVE_LINE_START_WITH_SELECTION, KeyEvent.SHIFT_DOWN_MASK, KeyEvent.VK_HOME);
224+
registerActionHandler(IdeActions.ACTION_EDITOR_TEXT_START, KeyEvent.CTRL_DOWN_MASK | KeyEvent.META_DOWN_MASK, KeyEvent.VK_HOME);
225+
registerActionHandler(IdeActions.ACTION_EDITOR_TEXT_START_WITH_SELECTION, KeyEvent.SHIFT_DOWN_MASK | KeyEvent.CTRL_DOWN_MASK | KeyEvent.META_DOWN_MASK, KeyEvent.VK_HOME);
226+
registerActionHandler(IdeActions.ACTION_EDITOR_MOVE_LINE_END, 0, KeyEvent.VK_END);
227+
registerActionHandler(IdeActions.ACTION_EDITOR_MOVE_LINE_END_WITH_SELECTION, KeyEvent.SHIFT_DOWN_MASK, KeyEvent.VK_END);
228+
registerActionHandler(IdeActions.ACTION_EDITOR_TEXT_END, KeyEvent.CTRL_DOWN_MASK | KeyEvent.META_DOWN_MASK, KeyEvent.VK_END);
229+
registerActionHandler(IdeActions.ACTION_EDITOR_TEXT_END_WITH_SELECTION, KeyEvent.SHIFT_DOWN_MASK | KeyEvent.CTRL_DOWN_MASK | KeyEvent.META_DOWN_MASK, KeyEvent.VK_END);
230+
registerActionHandler(IdeActions.ACTION_EDITOR_BACKSPACE, 0, KeyEvent.VK_BACK_SPACE);
231+
registerActionHandler(IdeActions.ACTION_EDITOR_CUT, CodeAreaCommandHandler::cut);
232+
registerActionHandler(IdeActions.ACTION_EDITOR_COPY, CodeAreaCommandHandler::copy);
233+
registerActionHandler(IdeActions.ACTION_EDITOR_PASTE, CodeAreaCommandHandler::paste);
234+
registerActionHandler(IdeActions.ACTION_SELECT_ALL, CodeAreaCommandHandler::selectAll);
235+
registerActionHandler(IdeActions.ACTION_FIND, KeyEvent.CTRL_DOWN_MASK | KeyEvent.META_DOWN_MASK, KeyEvent.VK_F);
236+
registerActionHandler(IdeActions.ACTION_REPLACE, KeyEvent.CTRL_DOWN_MASK | KeyEvent.META_DOWN_MASK, KeyEvent.VK_H);
237+
}
238+
}
239+
240+
private static void registerActionHandler(String actionId, int modifiers, int key) {
241+
registerActionHandlerCodeArea(actionId, codeAreaComponent ->
242+
codeAreaComponent.getCommandHandler().keyPressed(new KeyEvent(codeAreaComponent, 0, 0, modifiers, key))
243+
);
244+
}
245+
246+
private static void registerActionHandler(String actionId, CodeAreaCommanderAction codeAreaCommanderAction) {
247+
registerActionHandlerCodeArea(actionId, codeAreaComponent -> codeAreaCommanderAction.perform(codeAreaComponent.getCommandHandler()));
248+
}
249+
250+
private static void registerActionHandlerCodeArea(String actionId, CodeAreaCoreAction codeAreaCoreAction) {
251+
EditorActionManager actionManager = EditorActionManager.getInstance();
252+
EditorActionHandler actionHandler = actionManager.getActionHandler(actionId);
253+
if (actionHandler instanceof EditorActionHandler.ForEachCaret) {
254+
actionManager.setActionHandler(actionId,
255+
new EditorActionHandler.ForEachCaret() {
256+
/**
257+
* @deprecated Implementations should override
258+
* {@link #isEnabledForCaret(Editor, Caret, DataContext)}
259+
* instead,
260+
* client code should invoke
261+
* {@link #isEnabled(Editor, Caret, DataContext)}
262+
* instead.
263+
*/
264+
@Deprecated
265+
@Override
266+
public boolean isEnabled(Editor editor, DataContext dataContext) {
267+
JComponent component = editor.getComponent();
268+
if (component instanceof CodeAreaCore) {
269+
return super.isEnabled(editor, dataContext);
270+
}
271+
272+
return actionHandler.isEnabled(editor, dataContext);
273+
}
274+
275+
@Override
276+
protected boolean isEnabledForCaret(@NotNull Editor editor,
277+
@NotNull Caret caret,
278+
DataContext dataContext) {
279+
JComponent component = editor.getComponent();
280+
if (component instanceof CodeAreaCore) {
281+
return super.isEnabledForCaret(editor, caret, dataContext);
282+
}
283+
284+
return actionHandler.isEnabled(editor, caret, dataContext);
285+
}
286+
287+
/**
288+
* @deprecated To implement action logic, override
289+
* {@link #doExecute(Editor, Caret, DataContext)},
290+
* to invoke the handler, call
291+
* {@link #execute(Editor, Caret, DataContext)}.
292+
*/
293+
@Deprecated
294+
@Override
295+
public void execute(@NotNull Editor editor,
296+
@org.jetbrains.annotations.Nullable DataContext dataContext) {
297+
JComponent component = editor.getComponent();
298+
if (component instanceof CodeAreaCore) {
299+
super.execute(editor, dataContext);
300+
}
301+
302+
actionHandler.execute(editor, dataContext);
303+
}
304+
305+
@Override
306+
public boolean executeInCommand(@NotNull Editor editor, DataContext dataContext) {
307+
JComponent component = editor.getComponent();
308+
if (component instanceof CodeAreaCore) {
309+
return super.executeInCommand(editor, dataContext);
310+
}
311+
312+
return actionHandler.executeInCommand(editor, dataContext);
313+
}
314+
315+
@Override
316+
public boolean runForAllCarets() {
317+
return actionHandler.runForAllCarets();
318+
}
319+
320+
@Override
321+
public DocCommandGroupId getCommandGroupId(@NotNull Editor editor) {
322+
return actionHandler.getCommandGroupId(editor);
323+
}
324+
325+
@Override
326+
protected void doExecute(@NotNull Editor editor, @NotNull Caret caret, DataContext dataContext) {
327+
JComponent component = editor.getComponent();
328+
if (component instanceof CodeAreaCore) {
329+
codeAreaCoreAction.perform((CodeAreaCore) component);
330+
return;
331+
}
332+
333+
// This should not be reached unless there will be some changes in EditorActionHandler
334+
actionHandler.execute(editor, caret, dataContext);
335+
}
336+
}
337+
);
338+
} else {
339+
actionManager.setActionHandler(actionId,
340+
new EditorActionHandler() {
341+
/**
342+
* @deprecated Implementations should override
343+
* {@link #isEnabledForCaret(Editor, Caret, DataContext)}
344+
* instead,
345+
* client code should invoke
346+
* {@link #isEnabled(Editor, Caret, DataContext)}
347+
* instead.
348+
*/
349+
@Deprecated
350+
@Override
351+
public boolean isEnabled(Editor editor, DataContext dataContext) {
352+
JComponent component = editor.getComponent();
353+
if (component instanceof CodeAreaCore) {
354+
return super.isEnabled(editor, dataContext);
355+
}
356+
357+
return actionHandler.isEnabled(editor, dataContext);
358+
}
359+
360+
@Override
361+
protected boolean isEnabledForCaret(@NotNull Editor editor,
362+
@NotNull Caret caret,
363+
DataContext dataContext) {
364+
JComponent component = editor.getComponent();
365+
if (component instanceof CodeAreaCore) {
366+
return super.isEnabledForCaret(editor, caret, dataContext);
367+
}
368+
369+
return actionHandler.isEnabled(editor, caret, dataContext);
370+
}
371+
372+
/**
373+
* @deprecated To implement action logic, override
374+
* {@link #doExecute(Editor, Caret, DataContext)},
375+
* to invoke the handler, call
376+
* {@link #execute(Editor, Caret, DataContext)}.
377+
*/
378+
@Deprecated
379+
@Override
380+
public void execute(@NotNull Editor editor,
381+
@org.jetbrains.annotations.Nullable DataContext dataContext) {
382+
JComponent component = editor.getComponent();
383+
if (component instanceof CodeAreaCore) {
384+
super.execute(editor, dataContext);
385+
}
386+
387+
actionHandler.execute(editor, dataContext);
388+
}
389+
390+
@Override
391+
public boolean executeInCommand(@NotNull Editor editor, DataContext dataContext) {
392+
JComponent component = editor.getComponent();
393+
if (component instanceof CodeAreaCore) {
394+
return super.executeInCommand(editor, dataContext);
395+
}
396+
397+
return actionHandler.executeInCommand(editor, dataContext);
398+
}
399+
400+
@Override
401+
public boolean runForAllCarets() {
402+
return actionHandler.runForAllCarets();
403+
}
404+
405+
@Override
406+
public DocCommandGroupId getCommandGroupId(@NotNull Editor editor) {
407+
return actionHandler.getCommandGroupId(editor);
408+
}
409+
410+
@Override
411+
protected void doExecute(@NotNull Editor editor, @Nullable Caret caret, DataContext dataContext) {
412+
JComponent component = editor.getComponent();
413+
if (component instanceof CodeAreaCore) {
414+
codeAreaCoreAction.perform((CodeAreaCore) component);
415+
return;
416+
}
417+
418+
// This should not be reached unless there will be some changes in EditorActionHandler
419+
actionHandler.execute(editor, caret, dataContext);
420+
}
421+
}
422+
);
213423
}
214424
}
215425

@@ -230,18 +440,6 @@ private static void initIntegration() {
230440
// initialIntegrationOptions = new IntegrationPreferences(preferences);
231441
// applyIntegrationOptions(initialIntegrationOptions);
232442

233-
// Editor actions overtakes action events
234-
EditorActionManager actionManager = EditorActionManager.getInstance();
235-
EditorActionHandler actionHandler = actionManager.getActionHandler(IdeActions.ACTION_EDITOR_MOVE_LINE_START);
236-
actionManager.setActionHandler(IdeActions.ACTION_EDITOR_MOVE_LINE_START,
237-
new EditorActionHandler.ForEachCaret() {
238-
@Override
239-
protected void doExecute(@NotNull Editor editor, @NotNull Caret caret, DataContext dataContext) {
240-
System.out.println("Action");
241-
actionHandler.execute(editor, caret, dataContext);
242-
}
243-
}
244-
);
245443
}
246444

247445
private void projectOpened(Project project) {
@@ -747,4 +945,12 @@ public <T extends Module> T getModule(Class<T> moduleClass) {
747945
return (T) modules.get(moduleClass);
748946
}
749947
}
948+
949+
private interface CodeAreaCoreAction {
950+
void perform(CodeAreaCore component);
951+
}
952+
953+
private interface CodeAreaCommanderAction {
954+
void perform(CodeAreaCommandHandler commandHandler);
955+
}
750956
}

0 commit comments

Comments
 (0)