Slide 1

Slide 1 text

WRITING A PLUGIN FOR @ALEXEYBUZDIN, SEPTEMBER 2017

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

WRITING A PLUGIN FOR @ALEXEYBUZDIN, SEPTEMBER 2017

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

PLUGINS.JETBRAINS.COM

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

DEMO LET’S START WITH A PROJECT!

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

PLUGIN.XML == ANDROIDMANIFEST.XML

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

BUILDING A PLUGIN INCREMENTALY

Slide 16

Slide 16 text

BUILDING A PLUGIN INCREMENTALY BUT FOR WHAT?

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

DEMO LET’S START WITH AN ACTION!

Slide 19

Slide 19 text

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 ☺

Slide 20

Slide 20 text

MORE ON ACTION: GROUPING ACTIONS

Slide 21

Slide 21 text

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); } }

Slide 22

Slide 22 text

LET’S FIX THIS! Name: Comments:

Slide 23

Slide 23 text

LET’S FIX THIS! Name: Comments:

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

BACKUS–NAUR FORM FOR CSV ::= *

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

DEMO LET’S DESCRIBE A LANGUAGE!

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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\\] | "\\ "

Slide 34

Slide 34 text

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; }

Slide 35

Slide 35 text

DEMO NEXT STEP IS LEXER!

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

COLORSETTINGSPAGE

Slide 38

Slide 38 text

PROJECT WIZARD Full javax.swing.* support

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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