$30 off During Our Annual Pro Sale. View Details »

Writing A Plugin for Android Studio

Writing A Plugin for Android Studio

Do you wish you could click autocomplete an exotic language or drill down into framework String parameters? But sadly there's no IDE plugin for that, what a shame.. But do not fear, we have a solution! Let's explore how we could make our own plugin for our favourite tool. We will start with capability overview of plugin API, get into parsers and lexers, syntax highlight, adding buttons to toolbars, etc. As well as briefly cover best practices, build system configurations and deployment to get your plugin into the wilds into the plugin store!

Alexey Buzdin

November 04, 2017
Tweet

More Decks by Alexey Buzdin

Other Decks in Programming

Transcript

  1. WRITING A PLUGIN FOR
    @ALEXEYBUZDIN, SEPTEMBER 2017

    View Slide

  2. @ALEXEYBUZDIN
    WRITING MOBILE AND JAVA STUFF
    ORGANIZING EVENTS
    SPEAKING AT CONFERENCES

    View Slide

  3. WRITING A PLUGIN FOR
    @ALEXEYBUZDIN, SEPTEMBER 2017

    View Slide

  4. View Slide

  5. View Slide

  6. View Slide

  7. View Slide

  8. View Slide

  9. PLUGINS.JETBRAINS.COM

    View Slide

  10. > .gitignore plugin
    > Markdown support
    > CheckStyle-IDEA
    > Lombok Plugin
    > BashSupport
    > etc

    View Slide

  11. DEMO
    LET’S START WITH A PROJECT!

    View Slide

  12. RECAP: PLUGIN PROJECT IS
    A JAVA PROJECT WITH
    PLUGIN.XML AND TARGET
    SDK - INTELLIJ PRODUCT
    http://www.jetbrains.org/intellij/sdk/docs/tutorials/customlanguagesupport_tutorial.html

    View Slide

  13. PLUGIN.XML
    ==
    ANDROIDMANIFEST.XML

    View Slide

  14. TIP: USE GRADLE WITH
    “ORG.JETBRAINS.INTELLIJ"
    PLUGIN
    HTTPS://SL.GDG.LV/SAMPLEINTELLIJPLUGIN

    View Slide

  15. BUILDING A PLUGIN
    INCREMENTALY

    View Slide

  16. BUILDING A PLUGIN
    INCREMENTALY
    BUT FOR WHAT?

    View Slide

  17. Project Goal: www.fusetools.com
    https://github.com/AlexeyBuzdin/Fuse.IntelliJPlugin

    View Slide

  18. DEMO
    LET’S START WITH AN ACTION!

    View Slide

  19. WHAT DID WE ACHIEVE?
    1. We’ve written an Action
    2. Created our own Language
    3. Registered a new File Type
    4. Added an Icon ☺

    View Slide

  20. MORE ON ACTION: GROUPING ACTIONS



    text="Grouped Action" description="Grouped Action Demo">



    View Slide

  21. MORE ON ACTION: DEFAULTACTIONGROUP
    public class CustomDefaultActionGroup extends DefaultActionGroup {
    @Override
    public void update(AnActionEvent event) {
    Editor editor = event.getData(CommonDataKeys.EDITOR);
    event.getPresentation().setVisible(true);
    event.getPresentation().setEnabled(editor != null);
    event.getPresentation().setIcon(AllIcons.General.Error);
    }
    }

    View Slide

  22. LET’S FIX THIS!












    Name:



    Comments:






    View Slide

  23. LET’S FIX THIS!












    Name:



    Comments:






    View Slide

  24. View Slide

  25. PARSER AND
    LEXER
    LEXER - PARSES CODE INTO TOKENS
    PARSER - VALIDATES CODE STRUCTURE

    View Slide

  26. BACKUS–NAUR FORM
    > ::= __expression__
    > ::= |
    > ::=

    View Slide

  27. BACKUS–NAUR FORM FOR CSV
    ::= *

    View Slide

  28. BACKUS–NAUR FORM FOR CSV
    ::= *
    ::= ? | (“,”)+ “,”?

    View Slide

  29. BACKUS–NAUR FORM FOR CSV
    ::= *
    ::= ? | (“,”)+ “,”?
    ::= [^,]+

    View Slide

  30. Grammar-Kit
    root_rule ::= rule_A rule_B rule_C rule_D // a sequence
    rule_A ::= token | 'or_text' | "another_one" // a choice
    rule_B ::= [ optional_token ] and_another_one? // optional parts
    rule_C ::= &required !forbidden // predicates
    rule_D ::= { can_use_braces + (and_parens) * } // grouping and repetition
    // Grammar-Kit extensions:
    private left rule_with_modifier ::= '+' // rule modifiers
    left rule_with_attributes ::= '?' {elementType=rule_D} // left rule and attributes
    private meta list_macro ::= <> (',' <>) * // meta rule
    private list_usage ::= <> // external expression
    https://github.com/JetBrains/Grammar-Kit

    View Slide

  31. DEMO
    LET’S DESCRIBE A LANGUAGE!

    View Slide

  32. JFlex - Lexical Analyzer Generator
    http://jflex.de/manual.html

    View Slide

  33. package com.simpleplugin;
    import com.intellij.lexer.FlexLexer;
    import com.intellij.psi.tree.IElementType;
    import com.simpleplugin.psi.SimpleTypes;
    import com.intellij.psi.TokenType;
    %%
    %class SimpleLexer
    %implements FlexLexer
    %unicode
    %function advance
    %type IElementType
    %eof{ return;
    %eof}
    CRLF=\R
    WHITE_SPACE=[\ \n\t\f]
    FIRST_VALUE_CHARACTER=[^ \n\f\\] | "\\"{CRLF} | "\\".
    VALUE_CHARACTER=[^\n\f\\] | "\\"{CRLF} | "\\".
    END_OF_LINE_COMMENT=("#"|"!")[^\r\n]*
    SEPARATOR=[:=]
    KEY_CHARACTER=[^:=\ \n\t\f\\] | "\\ "

    View Slide

  34. PROPERTY: KEY = VALUE
    %state WAITING_VALUE
    %%
    {END_OF_LINE_COMMENT} { yybegin(YYINITIAL); return SimpleTypes.COMMENT; }
    {KEY_CHARACTER}+ { yybegin(YYINITIAL); return SimpleTypes.KEY; }
    {SEPARATOR} { yybegin(WAITING_VALUE); return SimpleTypes.SEPARATOR; }
    {CRLF}({CRLF}|{WHITE_SPACE})+ { yybegin(YYINITIAL); return TokenType.WHITE_SPACE; }
    {WHITE_SPACE}+ { yybegin(WAITING_VALUE); return TokenType.WHITE_SPACE; }
    {FIRST_VALUE_CHARACTER}{VALUE_CHARACTER}* { yybegin(YYINITIAL); return SimpleTypes.VALUE; }
    ({CRLF}|{WHITE_SPACE})+ { yybegin(YYINITIAL); return TokenType.WHITE_SPACE; }
    . { return TokenType.BAD_CHARACTER; }

    View Slide

  35. DEMO
    NEXT STEP IS LEXER!

    View Slide

  36. WHAT DID WE ACHIEVE?
    1. We’ve described a Parser
    2. Implemented a Lexer
    3. Added some !
    NEXT STEPS?

    View Slide

  37. COLORSETTINGSPAGE

    View Slide

  38. PROJECT WIZARD
    Full javax.swing.* support

    View Slide

  39. RUN CONFIGURATIONS
    Gather state from JPanel and triggers on startProcess()

    View Slide

  40. WHAT CAN YOU DO WITH PSIELEMENT
    1. References and GoTo
    2. Find Usage
    3. Code Completion
    4. Annotators
    5. Line Marker
    6. More

    View Slide

  41. TIPS
    PREVENTING UI FREEZES
    ALWAYS CHECK FOR
    NEGATIVE CASE
    IMPROVE THE BNF

    View Slide

  42. GREAT EXAMPLES
    > jetbrains-plugin-graph-database
    > intellij-erlang
    > intellij-rust

    View Slide

  43. THANK YOU!
    Q&A
    FOLLOW ME ON TWITTER
    @ALEXEYBUZDIN

    View Slide