package org.elixir_lang; import com.intellij.codeInsight.editorActions.TypedHandlerDelegate; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.editor.highlighter.EditorHighlighter; import com.intellij.openapi.editor.highlighter.HighlighterIterator; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.TokenSet; import org.elixir_lang.psi.ElixirFile; import org.elixir_lang.psi.ElixirTypes; import org.jetbrains.annotations.NotNull; public class TypedHandler extends TypedHandlerDelegate { /* * CONSTANTS */ private static final TokenSet SIGIL_PROMOTERS = TokenSet.create( ElixirTypes.CHAR_LIST_SIGIL_PROMOTER, ElixirTypes.REGEX_PROMOTER, ElixirTypes.SIGIL_PROMOTER, ElixirTypes.STRING_SIGIL_PROMOTER, ElixirTypes.WORDS_PROMOTER ); /* * Instance Methods */ /** * Called after the specified character typed by the user has been inserted in the editor. * * @param charTyped the character that was typed * @param project the project in which the {@code file} exists * @param editor the editor that has the {@code file} open * @param file the file into which the {@code charTyped} was typed */ @Override public Result charTyped(char charTyped, Project project, @NotNull Editor editor, @NotNull PsiFile file) { Result result = Result.CONTINUE; if (file instanceof ElixirFile) { if (charTyped == ' ') { int caret = editor.getCaretModel().getOffset(); if (caret > 2) { // "(do|fn)<space><caret>" final EditorHighlighter highlighter = ((EditorEx)editor).getHighlighter(); HighlighterIterator iterator = highlighter.createIterator(caret - 2); IElementType tokenType = iterator.getTokenType(); if (tokenType == ElixirTypes.DO || tokenType == ElixirTypes.FN) { editor.getDocument().insertString(caret, " end"); result = Result.STOP; } } } else if (charTyped == '<') { int caret = editor.getCaretModel().getOffset(); if (caret > 2) { // "~<sigil_name><" final EditorHighlighter highlighter = ((EditorEx)editor).getHighlighter(); HighlighterIterator iterator = highlighter.createIterator(caret - 1); IElementType tokenType = iterator.getTokenType(); if (SIGIL_PROMOTERS.contains(tokenType)) { editor.getDocument().insertString(caret, ">"); result = Result.STOP; } } if (result == Result.CONTINUE && caret > 1) { // "<<" final EditorHighlighter highlighter = ((EditorEx)editor).getHighlighter(); HighlighterIterator iterator = highlighter.createIterator(caret - 2); if (iterator.getTokenType() == ElixirTypes.OPENING_BIT) { editor.getDocument().insertString(caret, ">>"); result = Result.STOP; } } } else if (charTyped == '/' || charTyped == '|') { int caret = editor.getCaretModel().getOffset(); if (caret > 2) { // "~<sigil_name>(/|\|)" final EditorHighlighter highlighter = ((EditorEx)editor).getHighlighter(); HighlighterIterator iterator = highlighter.createIterator(caret - 1); IElementType tokenType = iterator.getTokenType(); if (SIGIL_PROMOTERS.contains(tokenType)) { editor.getDocument().insertString(caret, String.valueOf(charTyped)); result = Result.STOP; } } } } return result; } }