如何创建通过热键插入字符的动作?
How to create an action which inserts a character via hotkey?
我正在为 IntelliJ IDEA 编写一个插件,遗憾的是 API 参考资料似乎对整个插件系统有点缺乏(除了 JetBrains 网站上的一些非常有用的教程。)这个插件是一种与特定文件类型关联的自定义语言,解析器 API 可与文件关联和模板系统一起管理,但我无法弄清楚的是,这应该是一个非常容易解决的问题对比那些。
我想创建一个热键,当在编辑器中使用时(没有菜单项或工具栏图标,只有键盘组合),它将插入一个 unicode 字符,或者如果有一个活动的选择,将换行一对 unicode 字符中的选定文本。
例如在我的文件类型中捕获 ALT_SHIFT+[
的东西,如果没有选择,它会在当前插入符号位置插入字符 ⦓
,如果有选择,那么它将把该选择包装在 ⦓
... ⦔
这似乎是可行的,因为 .java
文件实际上使用 ALT+SHIFT+[
组合来更改 IntelliJ 中的选择,而我的自定义文件类型目前只是忽略它。
自定义文件类型继承自 com.intellij.openapi.fileTypes
包中的 LanguageFileType
。
编辑:
添加由此产生的代码以防其他人遇到此问题:
HotkeyAction(需要在plugin.xml中注册)
public class HotkeyAction extends AnAction {
private static final Logger logger = Logger.getInstance("Aquae");
private ArrayList<HotkeyHandler> hotkeyHandlers;
public HotkeyAction() {
super();
this.hotkeyHandlers = new ArrayList<HotkeyHandler>();
this.AddBracketShortcut(true,
"{", KeyStroke.getKeyStroke(VK_OPEN_BRACKET, SHIFT_MASK, false),
"}", KeyStroke.getKeyStroke(VK_CLOSE_BRACKET, SHIFT_MASK, false));
this.AddBracketShortcut(true,
"⧼", KeyStroke.getKeyStroke(VK_OPEN_BRACKET, CTRL_MASK | SHIFT_MASK, false),
"⧽", KeyStroke.getKeyStroke(VK_CLOSE_BRACKET, CTRL_MASK | SHIFT_MASK, false));
this.AddBracketShortcut(true,
"⦓", KeyStroke.getKeyStroke(VK_OPEN_BRACKET, ALT_MASK | SHIFT_MASK, false),
"⦔", KeyStroke.getKeyStroke(VK_CLOSE_BRACKET, ALT_MASK | SHIFT_MASK, false));
this.AddBracketShortcut(true,
"⦃", KeyStroke.getKeyStroke(VK_OPEN_BRACKET, CTRL_MASK | ALT_MASK | SHIFT_MASK, false),
"⦄", KeyStroke.getKeyStroke(VK_CLOSE_BRACKET, CTRL_MASK | ALT_MASK | SHIFT_MASK, false));
this.AddBracketShortcut(true,
"(", KeyStroke.getKeyStroke(VK_9, SHIFT_MASK, false),
")", KeyStroke.getKeyStroke(VK_0, SHIFT_MASK, false));
this.AddBracketShortcut(true,
"⦗", KeyStroke.getKeyStroke(VK_9, CTRL_MASK | SHIFT_MASK, false),
"⦘", KeyStroke.getKeyStroke(VK_0, CTRL_MASK | SHIFT_MASK, false));
this.AddBracketShortcut(true,
"⦅", KeyStroke.getKeyStroke(VK_9, ALT_MASK | SHIFT_MASK, false),
"⦆", KeyStroke.getKeyStroke(VK_0, ALT_MASK | SHIFT_MASK, false));
this.AddBracketShortcut(true,
"⸨", KeyStroke.getKeyStroke(VK_9, CTRL_MASK | ALT_MASK | SHIFT_MASK, false),
"⸩", KeyStroke.getKeyStroke(VK_0, CTRL_MASK | ALT_MASK | SHIFT_MASK, false));
this.AddBracketShortcut(true,
"[", KeyStroke.getKeyStroke(VK_OPEN_BRACKET, 0, false),
"]", KeyStroke.getKeyStroke(VK_CLOSE_BRACKET, 0, false));
this.AddBracketShortcut(true,
"⁅", KeyStroke.getKeyStroke(VK_OPEN_BRACKET, CTRL_MASK, false),
"⁆", KeyStroke.getKeyStroke(VK_CLOSE_BRACKET, CTRL_MASK, false));
this.AddBracketShortcut(true,
"【", KeyStroke.getKeyStroke(VK_OPEN_BRACKET, ALT_MASK, false),
"】", KeyStroke.getKeyStroke(VK_CLOSE_BRACKET, ALT_MASK, false));
this.AddBracketShortcut(true,
"〚", KeyStroke.getKeyStroke(VK_OPEN_BRACKET, CTRL_MASK | ALT_MASK, false),
"〛", KeyStroke.getKeyStroke(VK_CLOSE_BRACKET, CTRL_MASK | ALT_MASK, false));
this.AddBracketShortcut(true,
"<", KeyStroke.getKeyStroke(VK_COMMA, SHIFT_MASK, false),
">", KeyStroke.getKeyStroke(VK_PERIOD, SHIFT_MASK, false));
this.AddBracketShortcut(true,
"᚜", KeyStroke.getKeyStroke(VK_COMMA, CTRL_MASK | SHIFT_MASK, false),
"᚛", KeyStroke.getKeyStroke(VK_PERIOD, CTRL_MASK | SHIFT_MASK, false));
this.AddBracketShortcut(true,
"⦑", KeyStroke.getKeyStroke(VK_COMMA, ALT_MASK | SHIFT_MASK, false),
"⦒", KeyStroke.getKeyStroke(VK_PERIOD, ALT_MASK | SHIFT_MASK, false));
this.AddBracketShortcut(true,
"⟪", KeyStroke.getKeyStroke(VK_COMMA, CTRL_MASK | ALT_MASK | SHIFT_MASK, false),
"⟫", KeyStroke.getKeyStroke(VK_PERIOD, CTRL_MASK | ALT_MASK | SHIFT_MASK, false));
}
HotkeyAction(ArrayList<HotkeyHandler> keyStrokes) {
super();
this.hotkeyHandlers = new ArrayList<HotkeyHandler>();
}
public void AddBracketShortcut(boolean completeWithoutSelection, String open, KeyStroke openKeyStroke, String close, KeyStroke closeKeyStroke) {
HotkeyBracketInsertionHandler handler = new HotkeyBracketInsertionHandler(completeWithoutSelection, open, openKeyStroke, close, closeKeyStroke);
this.hotkeyHandlers.add(handler);
KeymapManager.getInstance().getActiveKeymap().addShortcut("org.aquae.slip.HotkeyAction", handler.getOpenShortcut());
KeymapManager.getInstance().getActiveKeymap().addShortcut("org.aquae.slip.HotkeyAction", handler.getCloseShortcut());
}
@Override
public void actionPerformed(AnActionEvent anActionEvent) {
String s = "";
InputEvent inputEvent = anActionEvent.getInputEvent();
logger.warn(inputEvent.toString());
boolean hit = false;
Project project = anActionEvent.getProject();
if (inputEvent instanceof KeyEvent) {
KeyEvent keyEvent = (KeyEvent) inputEvent;
int mask = 0;
s = String.valueOf(keyEvent.getKeyChar());
if (inputEvent.isShiftDown()) {
s = "SHIFT" + (s.length() > 0 ? " + " + s : "");
mask |= SHIFT_DOWN_MASK;
}
if (inputEvent.isAltDown()) {
s = "ALT" + (s.length() > 0 ? " + " + s : "");
mask |= ALT_DOWN_MASK;
}
if (inputEvent.isControlDown()) {
s = "CTRL" + (s.length() > 0 ? " + " + s : "");
mask |= CTRL_DOWN_MASK;
}
logger.warn("KeyCode = " + keyEvent.getKeyCode());
logger.warn("Modifiers = " + keyEvent.getModifiers());
logger.warn(s);
for (HotkeyHandler hotkeyHandler : this.hotkeyHandlers) {
if (hotkeyHandler.match(anActionEvent)) {
hit = true;
if (hotkeyHandler instanceof HotkeyBracketInsertionHandler) {
HotkeyBracketInsertionHandler hotkeyBracketInsertionHandler = (HotkeyBracketInsertionHandler) hotkeyHandler;
logger.warn(hotkeyBracketInsertionHandler.getOpen() + "x" + hotkeyBracketInsertionHandler.getClose());
WriteCommandAction.runWriteCommandAction(project, () -> { hotkeyHandler.execute(project, anActionEvent); });
}
break;
}
}
if (!hit) {
logger.warn(s);
}
}
}
}
HotkeyHandler
public abstract class HotkeyHandler {
protected ArrayList<KeyStroke> _keyStrokes;
protected ArrayList<Shortcut> _shortcuts;
public HotkeyHandler(ArrayList<KeyStroke> keyStrokes) {
this._keyStrokes = keyStrokes;
this._shortcuts = new ArrayList<Shortcut>();
for (KeyStroke keyStroke : keyStrokes) {
this._shortcuts.add(new KeyboardShortcut(keyStroke, null));
}
}
abstract void execute(Project project, AnActionEvent anActionEvent);
public boolean indifferentMatch(int i, KeyEvent keyEvent) {
KeyStroke keyStroke = this._keyStrokes.get(i);
if (keyStroke.getKeyCode() == keyEvent.getKeyCode()) {
int modifiers = keyEvent.getModifiers();
if ((keyStroke.getModifiers() & (CTRL_MASK | CTRL_DOWN_MASK)) > 0) {
if ((modifiers & (CTRL_MASK | CTRL_DOWN_MASK)) < 1) { return (false); }
if ((modifiers & CTRL_MASK) > 0) { modifiers -= CTRL_MASK; }
if ((modifiers & CTRL_DOWN_MASK) > 0) { modifiers -= CTRL_DOWN_MASK; }
}
if ((keyStroke.getModifiers() & (ALT_MASK | ALT_DOWN_MASK)) > 0) {
if ((modifiers & (ALT_MASK | ALT_DOWN_MASK)) < 1) { return (false); }
if ((modifiers & ALT_MASK) > 0) { modifiers -= ALT_MASK; }
if ((modifiers & ALT_DOWN_MASK) > 0) { modifiers -= ALT_DOWN_MASK; }
}
if ((keyStroke.getModifiers() & (SHIFT_MASK | SHIFT_DOWN_MASK)) > 0) {
if ((modifiers & (SHIFT_MASK | SHIFT_DOWN_MASK)) < 1) { return (false); }
if ((modifiers & SHIFT_MASK) > 0) { modifiers -= SHIFT_MASK; }
if ((modifiers & SHIFT_DOWN_MASK) > 0) { modifiers -= SHIFT_DOWN_MASK; }
}
if (modifiers < 1) { return (true); }
}
return (false);
}
public boolean match(AnActionEvent anActionEvent) {
InputEvent inputEvent = anActionEvent.getInputEvent();
if (!(inputEvent instanceof KeyEvent)) { return (false); }
KeyEvent keyEvent = (KeyEvent) inputEvent;
for (int i = this._keyStrokes.size() - 1; i >= 0; i--) {
if (this.indifferentMatch(i, keyEvent)) { return (true); }
}
return (false);
}
public KeyStroke getKeyStroke(int i) { return (this._keyStrokes.get(i)); }
public ArrayList<KeyStroke> getKeyStrokes() { return (this._keyStrokes); }
public Shortcut getShortcut(int i) { return (this._shortcuts.get(i)); }
public ArrayList<Shortcut> getShortcuts() { return (this._shortcuts); }
}
HotkeyBracketInsertionHandler
public class HotkeyBracketInsertionHandler extends HotkeyHandler {
private static final Logger logger = Logger.getInstance("Aquae");
private boolean _completeWithoutSelection;
private String _open;
private String _close;
public HotkeyBracketInsertionHandler(boolean completeWithoutSelection, String open, KeyStroke openKeyStroke, String close, KeyStroke closeKeyStroke) {
super(new ArrayList<KeyStroke>() {{
add(openKeyStroke);
add(closeKeyStroke);
}});
this._completeWithoutSelection = completeWithoutSelection;
this._open = open;
this._close = close;
}
@Override
void execute(Project project, AnActionEvent anActionEvent) {
InputEvent inputEvent = anActionEvent.getInputEvent();
if (!(inputEvent instanceof KeyEvent)) { return; }
KeyEvent keyEvent = (KeyEvent) inputEvent;
FileEditorManager fileEditorManager = FileEditorManager.getInstance(project);
Editor textEditor = fileEditorManager.getSelectedTextEditor();
final Document document = textEditor.getDocument();
final CaretModel caretModel = textEditor.getCaretModel();
final int caretOffset = caretModel.getOffset();
if (caretOffset < 0) { return; }
final SelectionModel selectionModel = textEditor.getSelectionModel();
boolean rev = (caretOffset == selectionModel.getSelectionStart()) && (caretOffset != selectionModel.getSelectionEnd());
boolean opening = this.indifferentMatch(0, keyEvent);
if (opening) {
if (this._completeWithoutSelection || selectionModel.hasSelection()) {
document.insertString(selectionModel.getSelectionEnd(), this._close);
document.insertString(selectionModel.getSelectionStart(), this._open);
caretModel.moveToOffset((rev ? selectionModel.getSelectionStart() : selectionModel.getSelectionEnd()) + (!selectionModel.hasSelection() ? this._open.length() : 0));
selectionModel.setSelection(selectionModel.getSelectionStart(), selectionModel.getSelectionEnd());
} else {
document.insertString(selectionModel.getSelectionStart(), this._open);
caretModel.moveToOffset(selectionModel.getSelectionEnd() + this._open.length());
}
} else {
if (this._close.length() < 1) { return; }
if (selectionModel.hasSelection()) {
document.insertString(selectionModel.getSelectionStart(), this._close);
document.deleteString(selectionModel.getSelectionStart(), selectionModel.getSelectionEnd());
caretModel.moveToOffset(rev ? selectionModel.getSelectionStart() : selectionModel.getSelectionEnd());
selectionModel.setSelection(selectionModel.getSelectionStart(), selectionModel.getSelectionEnd());
} else {
document.insertString(selectionModel.getSelectionStart(), this._close);
selectionModel.removeSelection();
caretModel.moveToOffset(selectionModel.getSelectionEnd() + this._close.length());
}
}
}
public String getClose() { return (this._close); }
public KeyStroke getCloseKeyStroke() { return (this._keyStrokes.get(1)); }
public Shortcut getCloseShortcut() { return (this._shortcuts.get(1)); }
public String getOpen() { return (this._open); }
public KeyStroke getOpenKeyStroke() { return (this._keyStrokes.get(0)); }
public Shortcut getOpenShortcut() { return (this._shortcuts.get(0)); }
}
HotkeyPromoter(需要在plugin.xml注册)
public class HotkeyPromoter implements ActionPromoter {
@Override
public List<AnAction> promote(List<AnAction> actions, DataContext dataContext) {
AnAction action = ContainerUtil.findInstance(actions, HotkeyAction.class);
return (action != null ? Collections.singletonList(action) : Collections.emptyList());
}
}
您需要实施一个 'action',它将执行相应的更改 - 请参阅 this guide for a start, and also this section。
由于您的操作将在编辑器中运行,因此使用 EditorAction 作为操作的基础是有意义的 class(然后您还需要实现 EditorActionHandler,它将执行实际逻辑)。
我正在为 IntelliJ IDEA 编写一个插件,遗憾的是 API 参考资料似乎对整个插件系统有点缺乏(除了 JetBrains 网站上的一些非常有用的教程。)这个插件是一种与特定文件类型关联的自定义语言,解析器 API 可与文件关联和模板系统一起管理,但我无法弄清楚的是,这应该是一个非常容易解决的问题对比那些。
我想创建一个热键,当在编辑器中使用时(没有菜单项或工具栏图标,只有键盘组合),它将插入一个 unicode 字符,或者如果有一个活动的选择,将换行一对 unicode 字符中的选定文本。
例如在我的文件类型中捕获 ALT_SHIFT+[
的东西,如果没有选择,它会在当前插入符号位置插入字符 ⦓
,如果有选择,那么它将把该选择包装在 ⦓
... ⦔
这似乎是可行的,因为 .java
文件实际上使用 ALT+SHIFT+[
组合来更改 IntelliJ 中的选择,而我的自定义文件类型目前只是忽略它。
自定义文件类型继承自 com.intellij.openapi.fileTypes
包中的 LanguageFileType
。
编辑:
添加由此产生的代码以防其他人遇到此问题:
HotkeyAction(需要在plugin.xml中注册)
public class HotkeyAction extends AnAction {
private static final Logger logger = Logger.getInstance("Aquae");
private ArrayList<HotkeyHandler> hotkeyHandlers;
public HotkeyAction() {
super();
this.hotkeyHandlers = new ArrayList<HotkeyHandler>();
this.AddBracketShortcut(true,
"{", KeyStroke.getKeyStroke(VK_OPEN_BRACKET, SHIFT_MASK, false),
"}", KeyStroke.getKeyStroke(VK_CLOSE_BRACKET, SHIFT_MASK, false));
this.AddBracketShortcut(true,
"⧼", KeyStroke.getKeyStroke(VK_OPEN_BRACKET, CTRL_MASK | SHIFT_MASK, false),
"⧽", KeyStroke.getKeyStroke(VK_CLOSE_BRACKET, CTRL_MASK | SHIFT_MASK, false));
this.AddBracketShortcut(true,
"⦓", KeyStroke.getKeyStroke(VK_OPEN_BRACKET, ALT_MASK | SHIFT_MASK, false),
"⦔", KeyStroke.getKeyStroke(VK_CLOSE_BRACKET, ALT_MASK | SHIFT_MASK, false));
this.AddBracketShortcut(true,
"⦃", KeyStroke.getKeyStroke(VK_OPEN_BRACKET, CTRL_MASK | ALT_MASK | SHIFT_MASK, false),
"⦄", KeyStroke.getKeyStroke(VK_CLOSE_BRACKET, CTRL_MASK | ALT_MASK | SHIFT_MASK, false));
this.AddBracketShortcut(true,
"(", KeyStroke.getKeyStroke(VK_9, SHIFT_MASK, false),
")", KeyStroke.getKeyStroke(VK_0, SHIFT_MASK, false));
this.AddBracketShortcut(true,
"⦗", KeyStroke.getKeyStroke(VK_9, CTRL_MASK | SHIFT_MASK, false),
"⦘", KeyStroke.getKeyStroke(VK_0, CTRL_MASK | SHIFT_MASK, false));
this.AddBracketShortcut(true,
"⦅", KeyStroke.getKeyStroke(VK_9, ALT_MASK | SHIFT_MASK, false),
"⦆", KeyStroke.getKeyStroke(VK_0, ALT_MASK | SHIFT_MASK, false));
this.AddBracketShortcut(true,
"⸨", KeyStroke.getKeyStroke(VK_9, CTRL_MASK | ALT_MASK | SHIFT_MASK, false),
"⸩", KeyStroke.getKeyStroke(VK_0, CTRL_MASK | ALT_MASK | SHIFT_MASK, false));
this.AddBracketShortcut(true,
"[", KeyStroke.getKeyStroke(VK_OPEN_BRACKET, 0, false),
"]", KeyStroke.getKeyStroke(VK_CLOSE_BRACKET, 0, false));
this.AddBracketShortcut(true,
"⁅", KeyStroke.getKeyStroke(VK_OPEN_BRACKET, CTRL_MASK, false),
"⁆", KeyStroke.getKeyStroke(VK_CLOSE_BRACKET, CTRL_MASK, false));
this.AddBracketShortcut(true,
"【", KeyStroke.getKeyStroke(VK_OPEN_BRACKET, ALT_MASK, false),
"】", KeyStroke.getKeyStroke(VK_CLOSE_BRACKET, ALT_MASK, false));
this.AddBracketShortcut(true,
"〚", KeyStroke.getKeyStroke(VK_OPEN_BRACKET, CTRL_MASK | ALT_MASK, false),
"〛", KeyStroke.getKeyStroke(VK_CLOSE_BRACKET, CTRL_MASK | ALT_MASK, false));
this.AddBracketShortcut(true,
"<", KeyStroke.getKeyStroke(VK_COMMA, SHIFT_MASK, false),
">", KeyStroke.getKeyStroke(VK_PERIOD, SHIFT_MASK, false));
this.AddBracketShortcut(true,
"᚜", KeyStroke.getKeyStroke(VK_COMMA, CTRL_MASK | SHIFT_MASK, false),
"᚛", KeyStroke.getKeyStroke(VK_PERIOD, CTRL_MASK | SHIFT_MASK, false));
this.AddBracketShortcut(true,
"⦑", KeyStroke.getKeyStroke(VK_COMMA, ALT_MASK | SHIFT_MASK, false),
"⦒", KeyStroke.getKeyStroke(VK_PERIOD, ALT_MASK | SHIFT_MASK, false));
this.AddBracketShortcut(true,
"⟪", KeyStroke.getKeyStroke(VK_COMMA, CTRL_MASK | ALT_MASK | SHIFT_MASK, false),
"⟫", KeyStroke.getKeyStroke(VK_PERIOD, CTRL_MASK | ALT_MASK | SHIFT_MASK, false));
}
HotkeyAction(ArrayList<HotkeyHandler> keyStrokes) {
super();
this.hotkeyHandlers = new ArrayList<HotkeyHandler>();
}
public void AddBracketShortcut(boolean completeWithoutSelection, String open, KeyStroke openKeyStroke, String close, KeyStroke closeKeyStroke) {
HotkeyBracketInsertionHandler handler = new HotkeyBracketInsertionHandler(completeWithoutSelection, open, openKeyStroke, close, closeKeyStroke);
this.hotkeyHandlers.add(handler);
KeymapManager.getInstance().getActiveKeymap().addShortcut("org.aquae.slip.HotkeyAction", handler.getOpenShortcut());
KeymapManager.getInstance().getActiveKeymap().addShortcut("org.aquae.slip.HotkeyAction", handler.getCloseShortcut());
}
@Override
public void actionPerformed(AnActionEvent anActionEvent) {
String s = "";
InputEvent inputEvent = anActionEvent.getInputEvent();
logger.warn(inputEvent.toString());
boolean hit = false;
Project project = anActionEvent.getProject();
if (inputEvent instanceof KeyEvent) {
KeyEvent keyEvent = (KeyEvent) inputEvent;
int mask = 0;
s = String.valueOf(keyEvent.getKeyChar());
if (inputEvent.isShiftDown()) {
s = "SHIFT" + (s.length() > 0 ? " + " + s : "");
mask |= SHIFT_DOWN_MASK;
}
if (inputEvent.isAltDown()) {
s = "ALT" + (s.length() > 0 ? " + " + s : "");
mask |= ALT_DOWN_MASK;
}
if (inputEvent.isControlDown()) {
s = "CTRL" + (s.length() > 0 ? " + " + s : "");
mask |= CTRL_DOWN_MASK;
}
logger.warn("KeyCode = " + keyEvent.getKeyCode());
logger.warn("Modifiers = " + keyEvent.getModifiers());
logger.warn(s);
for (HotkeyHandler hotkeyHandler : this.hotkeyHandlers) {
if (hotkeyHandler.match(anActionEvent)) {
hit = true;
if (hotkeyHandler instanceof HotkeyBracketInsertionHandler) {
HotkeyBracketInsertionHandler hotkeyBracketInsertionHandler = (HotkeyBracketInsertionHandler) hotkeyHandler;
logger.warn(hotkeyBracketInsertionHandler.getOpen() + "x" + hotkeyBracketInsertionHandler.getClose());
WriteCommandAction.runWriteCommandAction(project, () -> { hotkeyHandler.execute(project, anActionEvent); });
}
break;
}
}
if (!hit) {
logger.warn(s);
}
}
}
}
HotkeyHandler
public abstract class HotkeyHandler {
protected ArrayList<KeyStroke> _keyStrokes;
protected ArrayList<Shortcut> _shortcuts;
public HotkeyHandler(ArrayList<KeyStroke> keyStrokes) {
this._keyStrokes = keyStrokes;
this._shortcuts = new ArrayList<Shortcut>();
for (KeyStroke keyStroke : keyStrokes) {
this._shortcuts.add(new KeyboardShortcut(keyStroke, null));
}
}
abstract void execute(Project project, AnActionEvent anActionEvent);
public boolean indifferentMatch(int i, KeyEvent keyEvent) {
KeyStroke keyStroke = this._keyStrokes.get(i);
if (keyStroke.getKeyCode() == keyEvent.getKeyCode()) {
int modifiers = keyEvent.getModifiers();
if ((keyStroke.getModifiers() & (CTRL_MASK | CTRL_DOWN_MASK)) > 0) {
if ((modifiers & (CTRL_MASK | CTRL_DOWN_MASK)) < 1) { return (false); }
if ((modifiers & CTRL_MASK) > 0) { modifiers -= CTRL_MASK; }
if ((modifiers & CTRL_DOWN_MASK) > 0) { modifiers -= CTRL_DOWN_MASK; }
}
if ((keyStroke.getModifiers() & (ALT_MASK | ALT_DOWN_MASK)) > 0) {
if ((modifiers & (ALT_MASK | ALT_DOWN_MASK)) < 1) { return (false); }
if ((modifiers & ALT_MASK) > 0) { modifiers -= ALT_MASK; }
if ((modifiers & ALT_DOWN_MASK) > 0) { modifiers -= ALT_DOWN_MASK; }
}
if ((keyStroke.getModifiers() & (SHIFT_MASK | SHIFT_DOWN_MASK)) > 0) {
if ((modifiers & (SHIFT_MASK | SHIFT_DOWN_MASK)) < 1) { return (false); }
if ((modifiers & SHIFT_MASK) > 0) { modifiers -= SHIFT_MASK; }
if ((modifiers & SHIFT_DOWN_MASK) > 0) { modifiers -= SHIFT_DOWN_MASK; }
}
if (modifiers < 1) { return (true); }
}
return (false);
}
public boolean match(AnActionEvent anActionEvent) {
InputEvent inputEvent = anActionEvent.getInputEvent();
if (!(inputEvent instanceof KeyEvent)) { return (false); }
KeyEvent keyEvent = (KeyEvent) inputEvent;
for (int i = this._keyStrokes.size() - 1; i >= 0; i--) {
if (this.indifferentMatch(i, keyEvent)) { return (true); }
}
return (false);
}
public KeyStroke getKeyStroke(int i) { return (this._keyStrokes.get(i)); }
public ArrayList<KeyStroke> getKeyStrokes() { return (this._keyStrokes); }
public Shortcut getShortcut(int i) { return (this._shortcuts.get(i)); }
public ArrayList<Shortcut> getShortcuts() { return (this._shortcuts); }
}
HotkeyBracketInsertionHandler
public class HotkeyBracketInsertionHandler extends HotkeyHandler {
private static final Logger logger = Logger.getInstance("Aquae");
private boolean _completeWithoutSelection;
private String _open;
private String _close;
public HotkeyBracketInsertionHandler(boolean completeWithoutSelection, String open, KeyStroke openKeyStroke, String close, KeyStroke closeKeyStroke) {
super(new ArrayList<KeyStroke>() {{
add(openKeyStroke);
add(closeKeyStroke);
}});
this._completeWithoutSelection = completeWithoutSelection;
this._open = open;
this._close = close;
}
@Override
void execute(Project project, AnActionEvent anActionEvent) {
InputEvent inputEvent = anActionEvent.getInputEvent();
if (!(inputEvent instanceof KeyEvent)) { return; }
KeyEvent keyEvent = (KeyEvent) inputEvent;
FileEditorManager fileEditorManager = FileEditorManager.getInstance(project);
Editor textEditor = fileEditorManager.getSelectedTextEditor();
final Document document = textEditor.getDocument();
final CaretModel caretModel = textEditor.getCaretModel();
final int caretOffset = caretModel.getOffset();
if (caretOffset < 0) { return; }
final SelectionModel selectionModel = textEditor.getSelectionModel();
boolean rev = (caretOffset == selectionModel.getSelectionStart()) && (caretOffset != selectionModel.getSelectionEnd());
boolean opening = this.indifferentMatch(0, keyEvent);
if (opening) {
if (this._completeWithoutSelection || selectionModel.hasSelection()) {
document.insertString(selectionModel.getSelectionEnd(), this._close);
document.insertString(selectionModel.getSelectionStart(), this._open);
caretModel.moveToOffset((rev ? selectionModel.getSelectionStart() : selectionModel.getSelectionEnd()) + (!selectionModel.hasSelection() ? this._open.length() : 0));
selectionModel.setSelection(selectionModel.getSelectionStart(), selectionModel.getSelectionEnd());
} else {
document.insertString(selectionModel.getSelectionStart(), this._open);
caretModel.moveToOffset(selectionModel.getSelectionEnd() + this._open.length());
}
} else {
if (this._close.length() < 1) { return; }
if (selectionModel.hasSelection()) {
document.insertString(selectionModel.getSelectionStart(), this._close);
document.deleteString(selectionModel.getSelectionStart(), selectionModel.getSelectionEnd());
caretModel.moveToOffset(rev ? selectionModel.getSelectionStart() : selectionModel.getSelectionEnd());
selectionModel.setSelection(selectionModel.getSelectionStart(), selectionModel.getSelectionEnd());
} else {
document.insertString(selectionModel.getSelectionStart(), this._close);
selectionModel.removeSelection();
caretModel.moveToOffset(selectionModel.getSelectionEnd() + this._close.length());
}
}
}
public String getClose() { return (this._close); }
public KeyStroke getCloseKeyStroke() { return (this._keyStrokes.get(1)); }
public Shortcut getCloseShortcut() { return (this._shortcuts.get(1)); }
public String getOpen() { return (this._open); }
public KeyStroke getOpenKeyStroke() { return (this._keyStrokes.get(0)); }
public Shortcut getOpenShortcut() { return (this._shortcuts.get(0)); }
}
HotkeyPromoter(需要在plugin.xml注册)
public class HotkeyPromoter implements ActionPromoter {
@Override
public List<AnAction> promote(List<AnAction> actions, DataContext dataContext) {
AnAction action = ContainerUtil.findInstance(actions, HotkeyAction.class);
return (action != null ? Collections.singletonList(action) : Collections.emptyList());
}
}
您需要实施一个 'action',它将执行相应的更改 - 请参阅 this guide for a start, and also this section。 由于您的操作将在编辑器中运行,因此使用 EditorAction 作为操作的基础是有意义的 class(然后您还需要实现 EditorActionHandler,它将执行实际逻辑)。