@@ -94,6 +94,9 @@ org.openpatch.scratch4j.core.compile.Completions.Result complete(Path file, Stri
9494 });
9595
9696 private static final String INDENT = " " ;
97+ /** A method snippet from the block palette (an event block): its name. */
98+ private static final java .util .regex .Pattern EVENT_METHOD = java .util .regex .Pattern .compile (
99+ "^(?:public |protected |private )?void (\\ w+)\\ ([^)]*\\ ) \\ {\n " );
97100 private static final Pattern IDENTIFIER = Pattern .compile ("[A-Za-z_][A-Za-z0-9_]*$" );
98101 private static final Pattern WORD = Pattern .compile ("\\ b[A-Za-z_][A-Za-z0-9_]{2,}\\ b" );
99102 private static final Pattern IMAGE_STRING = Pattern .compile (
@@ -536,6 +539,27 @@ void insertBlock(String snippet) {
536539 }
537540 String body = snippet .substring (0 , snippet .length () - 1 );
538541 boolean multiLine = body .contains ("\n " );
542+ var method = EVENT_METHOD .matcher (body );
543+ if (method .find ()) {
544+ // an event block is a method: it goes into the class body, not into a method
545+ int current = area .getCurrentParagraph ();
546+ int lineEnd = area .getAbsolutePosition (current , area .getParagraph (current ).length ());
547+ var place = MemberPlacement .place (area .getText (), lineEnd , method .group (1 ));
548+ if (place != null && place .existing ()) {
549+ // the class already reacts to this event: go there instead of a second copy
550+ area .moveTo (place .offset ());
551+ int open = area .getCurrentParagraph ();
552+ if (open + 1 < area .getParagraphs ().size ()
553+ && !area .getParagraph (open + 1 ).getText ().strip ().startsWith ("}" )) {
554+ open ++; // the method's first line
555+ }
556+ area .moveTo (open , area .getParagraph (open ).length ());
557+ area .requestFollowCaret ();
558+ area .requestFocus ();
559+ return ;
560+ }
561+ if (place != null ) area .moveTo (place .offset ());
562+ }
539563 int paragraph = area .getCurrentParagraph ();
540564 String line = area .getParagraph (paragraph ).getText ();
541565 boolean blank = line .isBlank ();
@@ -545,8 +569,10 @@ void insertBlock(String snippet) {
545569 boolean prevIsBlank = blank
546570 ? paragraph == 0 || area .getParagraph (paragraph - 1 ).getText ().isBlank ()
547571 : false ;
572+ // a closing brace below needs no blank line before it either
548573 boolean nextIsBlank = paragraph + 1 >= area .getParagraphs ().size ()
549- || area .getParagraph (paragraph + 1 ).getText ().isBlank ();
574+ || area .getParagraph (paragraph + 1 ).getText ().isBlank ()
575+ || area .getParagraph (paragraph + 1 ).getText ().strip ().startsWith ("}" );
550576 int lineStart = area .getAbsolutePosition (paragraph , 0 );
551577 // multi-line snippets (method overrides) keep a blank line on both sides
552578 String before = blank ? (multiLine && !prevIsBlank ? "\n " : "" )
0 commit comments