void () { WhitespacesAndCommentsBinder leftEdgeProcessor = new WhitespacesAndCommentsBinder() { @Override public int getEdgePosition(List<? extends IElementType> tokens, boolean atStreamEdge, TokenTextGetter getter) { int pos = tokens.size() - 1; while (tokens.get(pos) != COMMENT && pos > 0) pos--; return pos; } }; WhitespacesAndCommentsBinder rightEdgeProcessor = new WhitespacesAndCommentsBinder() { @Override public int getEdgePosition(List<? extends IElementType> tokens, boolean atStreamEdge, TokenTextGetter getter) { int pos = 0; while (tokens.get(pos) != COMMENT && pos < tokens.size()-1) pos++; return pos + 1; } }; doTest("{ # i # }", """ Element(ROOT) PsiElement(OTHER)('{') PsiWhiteSpace(' ') Element(OTHER) PsiElement(COMMENT)('#') PsiWhiteSpace(' ') PsiElement(LETTER)('i') PsiWhiteSpace(' ') PsiElement(COMMENT)('#') PsiWhiteSpace(' ') PsiElement(OTHER)('}') """, builder -> { while (builder.getTokenType() != LETTER) builder.advanceLexer(); PsiBuilder.Marker marker = builder.mark(); builder.advanceLexer(); marker.done(OTHER); marker.setCustomEdgeTokenBinders(leftEdgeProcessor, rightEdgeProcessor); while (builder.getTokenType() != null) builder.advanceLexer(); } ); }