📄 tokenmarker.java
字号:
//{{{ Handle start of rule else if(!end) { if(context.inRule != null) handleRule(context.inRule,true); markKeyword((checkRule.action & ParserRule.MARK_PREVIOUS) != ParserRule.MARK_PREVIOUS); switch(checkRule.action & ParserRule.MAJOR_ACTIONS) { //{{{ SEQ case ParserRule.SEQ: context.spanEndSubst = null; if((checkRule.action & ParserRule.REGEXP) != 0) { handleTokenWithSpaces(tokenHandler, checkRule.token, pos - line.offset, matchedChars, context); } else { tokenHandler.handleToken(line, checkRule.token, pos - line.offset, matchedChars,context); } // a DELEGATE attribute on a SEQ changes the // ruleset from the end of the SEQ onwards if(checkRule.delegate != null) { context = new LineContext( checkRule.delegate, context.parent); keywords = context.rules.getKeywords(); } break; //}}} //{{{ SPAN, EOL_SPAN case ParserRule.SPAN: case ParserRule.EOL_SPAN: context.inRule = checkRule; byte tokenType = ((checkRule.action & ParserRule.EXCLUDE_MATCH) == ParserRule.EXCLUDE_MATCH ? context.rules.getDefault() : checkRule.token); if((checkRule.action & ParserRule.REGEXP) != 0) { handleTokenWithSpaces(tokenHandler, tokenType, pos - line.offset, matchedChars, context); } else { tokenHandler.handleToken(line,tokenType, pos - line.offset, matchedChars,context); } char[] spanEndSubst = null; /* substitute result of matching the rule start * into the end string. * * eg, in shell script mode, <<\s*(\w+) is * matched into \<$1\> to construct rules for * highlighting read-ins like this <<EOF * ... * EOF */ if(charIndexed != null && checkRule.end != null) { spanEndSubst = substitute(match, checkRule.end); } context.spanEndSubst = spanEndSubst; context = new LineContext( checkRule.delegate, context); keywords = context.rules.getKeywords(); break; //}}} //{{{ MARK_FOLLOWING case ParserRule.MARK_FOLLOWING: tokenHandler.handleToken(line,(checkRule.action & ParserRule.EXCLUDE_MATCH) == ParserRule.EXCLUDE_MATCH ? context.rules.getDefault() : checkRule.token,pos - line.offset, pattern.count,context); context.spanEndSubst = null; context.inRule = checkRule; break; //}}} //{{{ MARK_PREVIOUS case ParserRule.MARK_PREVIOUS: context.spanEndSubst = null; if ((checkRule.action & ParserRule.EXCLUDE_MATCH) == ParserRule.EXCLUDE_MATCH) { if(pos != lastOffset) { tokenHandler.handleToken(line, checkRule.token, lastOffset - line.offset, pos - lastOffset, context); } tokenHandler.handleToken(line, context.rules.getDefault(), pos - line.offset,pattern.count, context); } else { tokenHandler.handleToken(line, checkRule.token, lastOffset - line.offset, pos - lastOffset + pattern.count, context); } break; //}}} default: throw new InternalError("Unhandled major action"); } // move pos to last character of match sequence pos += (matchedChars - 1); lastOffset = pos + 1; // break out of inner for loop to check next char } //}}} //{{{ Handle end of MARK_FOLLOWING else if((context.inRule.action & ParserRule.MARK_FOLLOWING) != 0) { if(pos != lastOffset) { tokenHandler.handleToken(line, context.inRule.token, lastOffset - line.offset, pos - lastOffset,context); } lastOffset = pos; context.inRule = null; } //}}} return true; } //}}} //{{{ handleNoWordBreak() method private void handleNoWordBreak() { if(context.parent != null) { ParserRule rule = context.parent.inRule; if(rule != null && (context.parent.inRule.action & ParserRule.NO_WORD_BREAK) != 0) { if(pos != lastOffset) { tokenHandler.handleToken(line, rule.token, lastOffset - line.offset, pos - lastOffset,context); } lastOffset = pos; context = context.parent; keywords = context.rules.getKeywords(); context.inRule = null; } } } //}}} //{{{ handleTokenWithSpaces() method private void handleTokenWithSpaces(TokenHandler tokenHandler, byte tokenType, int start, int len, LineContext context) { int last = start; int end = start + len; for(int i = start; i < end; i++) { if(Character.isWhitespace(line.array[i + line.offset])) { if(last != i) { tokenHandler.handleToken(line, tokenType,last,i - last,context); } tokenHandler.handleToken(line,tokenType,i,1,context); last = i + 1; } } if(last != end) { tokenHandler.handleToken(line,tokenType,last, end - last,context); } } //}}} //{{{ markKeyword() method private void markKeyword(boolean addRemaining) { int len = pos - lastOffset; if(len == 0) return; //{{{ Do digits if(context.rules.getHighlightDigits()) { boolean digit = false; boolean mixed = false; for(int i = lastOffset; i < pos; i++) { char ch = line.array[i]; if(Character.isDigit(ch)) digit = true; else mixed = true; } if(mixed) { RE digitRE = context.rules.getDigitRegexp(); // only match against regexp if its not all // digits; if all digits, no point matching if(digit) { if(digitRE == null) { // mixed digit/alpha keyword, // and no regexp... don't // highlight as DIGIT digit = false; } else { CharIndexedSegment seg = new CharIndexedSegment( line,false); int oldCount = line.count; int oldOffset = line.offset; line.offset = lastOffset; line.count = len; if(!digitRE.isMatch(seg)) digit = false; line.offset = oldOffset; line.count = oldCount; } } } if(digit) { tokenHandler.handleToken(line,Token.DIGIT, lastOffset - line.offset, len,context); lastOffset = pos; return; } } //}}} //{{{ Do keywords if(keywords != null) { byte id = keywords.lookup(line, lastOffset, len); if(id != Token.NULL) { tokenHandler.handleToken(line,id, lastOffset - line.offset, len,context); lastOffset = pos; return; } } //}}} //{{{ Handle any remaining crud if(addRemaining) { tokenHandler.handleToken(line,context.rules.getDefault(), lastOffset - line.offset,len,context); lastOffset = pos; } //}}} } //}}} //{{{ substitute() method private char[] substitute(REMatch match, char[] end) { StringBuffer buf = new StringBuffer(); for(int i = 0; i < end.length; i++) { char ch = end[i]; if(ch == '$') { if(i == end.length - 1) buf.append(ch); else { char digit = end[i + 1]; if(!Character.isDigit(digit)) buf.append(ch); else { buf.append(match.toString( digit - '0')); i++; } } } else buf.append(ch); } char[] returnValue = new char[buf.length()]; buf.getChars(0,buf.length(),returnValue,0); return returnValue; } //}}} //}}} //{{{ LineContext class /** * Stores persistent per-line syntax parser state. */ public static class LineContext { private static Hashtable intern = new Hashtable(); public LineContext parent; public ParserRule inRule; public ParserRuleSet rules; // used for SPAN_REGEXP rules; otherwise null public char[] spanEndSubst; //{{{ LineContext constructor public LineContext(ParserRuleSet rs, LineContext lc) { rules = rs; parent = (lc == null ? null : (LineContext)lc.clone()); } //}}} //{{{ LineContext constructor public LineContext() { } //}}} //{{{ intern() method public LineContext intern() { Object obj = intern.get(this); if(obj == null) { intern.put(this,this); return this; } else return (LineContext)obj; } //}}} //{{{ hashCode() method public int hashCode() { if(inRule != null) return inRule.hashCode(); else if(rules != null) return rules.hashCode(); else return 0; } //}}} //{{{ equals() method public boolean equals(Object obj) { if(obj instanceof LineContext) { LineContext lc = (LineContext)obj; return lc.inRule == inRule && lc.rules == rules && MiscUtilities.objectsEqual(parent,lc.parent) && charArraysEqual(spanEndSubst,lc.spanEndSubst); } else return false; } //}}} //{{{ clone() method public Object clone() { LineContext lc = new LineContext(); lc.inRule = inRule; lc.rules = rules; lc.parent = (parent == null) ? null : (LineContext) parent.clone(); lc.spanEndSubst = spanEndSubst; return lc; } //}}} //{{{ charArraysEqual() method private boolean charArraysEqual(char[] c1, char[] c2) { if(c1 == null) return (c2 == null); else if(c2 == null) return (c1 == null); if(c1.length != c2.length) return false; for(int i = 0; i < c1.length; i++) { if(c1[i] != c2[i]) return false; } return true; } //}}} } //}}}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -