1
0
mirror of https://github.com/mitb-archive/filebot synced 2024-08-13 17:03:45 -04:00
filebot/source/net/filebot/ui/rename/FormatExpressionTokenMaker.java

160 lines
4.4 KiB
Java

package net.filebot.ui.rename;
import javax.swing.text.Segment;
import org.fife.ui.rsyntaxtextarea.Token;
import org.fife.ui.rsyntaxtextarea.TokenImpl;
import org.fife.ui.rsyntaxtextarea.TokenMakerBase;
import org.fife.ui.rsyntaxtextarea.TokenTypes;
import org.fife.ui.rsyntaxtextarea.modes.GroovyTokenMaker;
public class FormatExpressionTokenMaker extends TokenMakerBase {
private static final GroovyExpressionTokenMaker groovyTokenMaker = new GroovyExpressionTokenMaker();
public static final int LANGUAGE_LITERAL = 0;
public static final int LANGUAGE_GROOVY = 1;
@Override
public Token getTokenList(Segment segment, int initialTokenType, int startOffset) {
resetTokenList();
groovyTokenMaker.reset();
int level = getInitialLevel(segment, initialTokenType, startOffset);
setLanguageIndex(level > 0 ? LANGUAGE_GROOVY : LANGUAGE_LITERAL);
int start = 0;
int end = 0;
// parse expressions and literals
for (int i = 0; i < segment.length(); i++) {
switch (segment.charAt(i)) {
case '{':
if (level <= 0) {
if (start != end) {
addToken(segment, segment.getBeginIndex() + start, segment.getBeginIndex() + end - 1, Token.MARKUP_CDATA, startOffset + start);
}
setLanguageIndex(LANGUAGE_GROOVY);
addToken(segment, segment.getBeginIndex() + i, segment.getBeginIndex() + i, Token.MARKUP_CDATA_DELIMITER, startOffset + i);
start = end = i + 1;
level = 0;
} else {
end++;
}
level++;
break;
case '}':
if (level == 1) {
if (start != end) {
Segment groovySegment = new Segment(segment.array, segment.getBeginIndex() + start, end - start);
addToken(groovyTokenMaker.getTokenList(groovySegment, initialTokenType, startOffset + start));
}
addToken(segment, segment.getBeginIndex() + i, segment.getBeginIndex() + i, Token.MARKUP_CDATA_DELIMITER, startOffset + i);
setLanguageIndex(LANGUAGE_LITERAL);
start = end = i + 1;
} else {
end++;
}
level--;
break;
default:
end++;
break;
}
}
switch (getLanguageIndex()) {
case LANGUAGE_GROOVY:
// keyboard navigation doesn't work right unless there's a null token to end the line
if (start <= end) {
Segment groovySegment = new Segment(segment.array, segment.getBeginIndex() + start, end - start);
addToken(groovyTokenMaker.getTokenList(groovySegment, initialTokenType, startOffset + start));
}
addLevelToken(level);
break;
default:
if (start < end) {
addToken(segment, segment.getBeginIndex() + start, segment.getBeginIndex() + end - 1, Token.MARKUP_CDATA, startOffset + start);
}
addNullToken();
break;
}
return firstToken;
}
protected void addLevelToken(int level) {
addNullToken();
currentToken.setType(-level);
}
protected int getInitialLevel(Segment segment, int initialTokenType, int startOffset) {
return initialTokenType < 0 ? -initialTokenType : 0;
}
protected void addToken(Token token) {
Token tail = token.getNextToken();
if (firstToken == null) {
firstToken = (TokenImpl) token;
currentToken = firstToken;
} else {
TokenImpl next = (TokenImpl) token;
currentToken.setNextToken(next);
previousToken = currentToken;
currentToken = next;
}
currentToken.setLanguageIndex(getLanguageIndex());
currentToken.setHyperlink(false);
// new current token must be the tail
currentToken.setNextToken(null);
if (tail != null && tail.getType() != TokenTypes.NULL) {
addToken(tail);
}
}
@Override
public int getClosestStandardTokenTypeForInternalType(int type) {
return type < 0 ? TokenTypes.NULL : groovyTokenMaker.getClosestStandardTokenTypeForInternalType(type);
}
@Override
public boolean getCurlyBracesDenoteCodeBlocks(int languageIndex) {
return true;
}
@Override
public String[] getLineCommentStartAndEnd(int languageIndex) {
switch (languageIndex) {
case LANGUAGE_GROOVY:
return groovyTokenMaker.getLineCommentStartAndEnd(0);
default:
return null;
}
}
@Override
public boolean getShouldIndentNextLineAfter(Token token) {
return groovyTokenMaker.getShouldIndentNextLineAfter(token);
}
private static class GroovyExpressionTokenMaker extends GroovyTokenMaker {
@Override
protected void resetTokenList() {
// reset list structure, but do not reset shared token objects
firstToken = currentToken = previousToken = null;
}
protected void reset() {
// reset list structure and reset shared token objects
super.resetTokenList();
}
}
}