Intellij idea 如何创建通过热键插入角色的操作?

Intellij idea 如何创建通过热键插入角色的操作?,intellij-idea,intellij-plugin,Intellij Idea,Intellij Plugin,我正在为IntelliJ IDEA编写一个插件,遗憾的是,整个插件系统似乎缺少API参考(除了JetBrains网站上的一些非常有用的教程)这个插件是为一种与特定文件类型相关联的自定义语言设计的,解析器API可以与文件关联和模板系统一起管理,但我不明白的是,与这些类型相比,它应该是一个非常容易解决的问题 我想创建一个热键,当在编辑器中使用时(没有菜单项或工具栏图标,只有键盘组合),它将插入一个unicode字符,或者,如果有活动的选择,则将所选文本包装为一对unicode字符 例如,要在我的文件

我正在为IntelliJ IDEA编写一个插件,遗憾的是,整个插件系统似乎缺少API参考(除了JetBrains网站上的一些非常有用的教程)这个插件是为一种与特定文件类型相关联的自定义语言设计的,解析器API可以与文件关联和模板系统一起管理,但我不明白的是,与这些类型相比,它应该是一个非常容易解决的问题

我想创建一个热键,当在编辑器中使用时(没有菜单项或工具栏图标,只有键盘组合),它将插入一个unicode字符,或者,如果有活动的选择,则将所选文本包装为一对unicode字符

例如,要在我的文件类型中捕获
ALT_SHIFT+[
,如果没有选择,它将插入字符
在当前插入符号位置,如果有选择,则它将在

这似乎是可行的,因为
.java
文件实际上使用
ALT+SHIFT+[
组合来更改IntelliJ中的选择,而我的自定义文件类型目前只是忽略它

自定义文件类型继承自
com.intellij.openapi.fileTypes
包中的
LanguageFileType

编辑:

添加由此产生的代码,以防其他人遇到此问题:

热键操作(需要在plugin.xml中注册)

public类热键操作扩展了一个操作{
私有静态最终记录器Logger=Logger.getInstance(“AQUE”);
私有ArrayList热键处理程序;
公共热键操作(){
超级();
this.hotkeyHandlers=newArrayList();
此.AddBracketShortcut(true,
“{”,击键。getKeyStroke(VK_OPEN_括号,SHIFT_掩码,false),
“}”,KeyStroke.getKeyStroke(VK_CLOSE_括号,SHIFT_掩码,false));
此.AddBracketShortcut(true,
"⧼", KeyStroke.getKeyStroke(VK_OPEN_括号,CTRL_掩码,SHIFT_掩码,false),
"⧽,KeyStroke.getKeyStroke(VK_CLOSE_括号,CTRL_掩码,SHIFT_掩码,false));
此.AddBracketShortcut(true,
"⦓,击键。getKeyStroke(VK_OPEN_括号,ALT_掩码,SHIFT_掩码,false),
"⦔,KeyStroke.getKeyStroke(VK_CLOSE_括号,ALT_MASK | SHIFT_MASK,false));
此.AddBracketShortcut(true,
"⦃,击键。getKeyStroke(VK_OPEN_括号,CTRL_掩码,ALT_掩码,SHIFT_掩码,false),
"⦄,KeyStroke.getKeyStroke(VK_CLOSE_括号,CTRL_掩码,ALT_掩码,SHIFT_掩码,false));
此.AddBracketShortcut(true,
“(”,KeyStroke.getKeyStroke(VK_9,SHIFT_MASK,false),
“”),击键.getKeyStroke(VK_0,SHIFT_MASK,false);
此.AddBracketShortcut(true,
"⦗,击键。getKeyStroke(VK_9,CTRL_MASK | SHIFT_MASK,false),
"⦘,KeyStroke.getKeyStroke(VK_0,CTRL_MASK | SHIFT_MASK,false));
此.AddBracketShortcut(true,
"⦅,击键。getKeyStroke(VK_9,ALT_MASK | SHIFT_MASK,false),
"⦆,KeyStroke.getKeyStroke(VK_0,ALT_MASK | SHIFT_MASK,false));
此.AddBracketShortcut(true,
"⸨,击键。getKeyStroke(VK_9,CTRL_MASK | ALT_MASK | SHIFT_MASK,false),
"⸩,KeyStroke.getKeyStroke(VK_0,CTRL_MASK | ALT_MASK | SHIFT_MASK,false));
此.AddBracketShortcut(true,
“[”,KeyStroke.getKeyStroke(VK_OPEN_括号,0,false),
“]”,KeyStroke.getKeyStroke(VK_CLOSE_括号,0,false));
此.AddBracketShortcut(true,
“——”,击键。getKeyStroke(VK_OPEN_括号,CTRL_掩码,false),
“——”,KeyStroke.getKeyStroke(VK_CLOSE_括号,CTRL_MASK,false));
此.AddBracketShortcut(true,
“[”,击键。getKeyStroke(VK_OPEN_括号,ALT_掩码,false),
“]”,击键。getKeyStroke(VK_CLOSE_括号,ALT_掩码,false));
此.AddBracketShortcut(true,
“〚”,击键。getKeyStroke(VK_OPEN_括号,CTRL_MASK,ALT_MASK,false),
“〛”,KeyStroke.getKeyStroke(VK_CLOSE_括号,CTRL_MASK,ALT_MASK,false));
此.AddBracketShortcut(true,
“”,KeyStroke.getKeyStroke(VK_句点,SHIFT_掩码,false));
此.AddBracketShortcut(true,
"᚜,击键。getKeyStroke(VK_逗号,CTRL_掩码| SHIFT_掩码,false),
"᚛,KeyStroke.getKeyStroke(VK_句点,CTRL_掩码| SHIFT_掩码,false));
此.AddBracketShortcut(true,
"⦑,KeyStroke.getKeyStroke(VK_逗号,ALT_掩码| SHIFT_掩码,false),
"⦒,KeyStroke.getKeyStroke(VK_句点,ALT_掩码| SHIFT_掩码,false));
此.AddBracketShortcut(true,
"⟪,击键。getKeyStroke(VK_逗号,CTRL_掩码,ALT_掩码,SHIFT_掩码,false),
"⟫,KeyStroke.getKeyStroke(VK_句点,CTRL_掩码| ALT_掩码| SHIFT_掩码,false));
}
热键操作(ArrayList击键){
超级();
this.hotkeyHandlers=newArrayList();
}
public void AddBracketShortcut(布尔值completeWithoutSelection、字符串打开、击键打开、击键关闭、击键关闭){
HotkeyBracketInsertionHandler=新的HotkeyBracketInsertionHandler(完成而不选择、打开、打开击键、关闭、关闭击键);
this.hotkeyHandlers.add(handler);
KeymapManager.getInstance().getActiveKeymap().addShortcut(“org.aquae.slip.HotkeyAction”,handler.getOpenShortcut());
KeymapManager.getInstance().getActiveKeymap().addShortcut(“org.aquae.slip.HotkeyAction”,handler.getCloseShortcut());
}
@凌驾
已执行的公共作废操作(AnActionEvent AnActionEvent){
字符串s=“”;
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);
            }
        }
    }
}
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); }
}
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)); }
}
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());
    }
}