1 19 20 package org.netbeans.modules.languages.features; 21 22 import java.util.ConcurrentModificationException ; 23 import java.util.HashMap ; 24 import java.util.Iterator ; 25 import java.util.List ; 26 import java.util.Map ; 27 import java.util.WeakHashMap ; 28 import javax.swing.text.BadLocationException ; 29 import org.netbeans.api.languages.LanguagesManager; 30 import org.netbeans.api.languages.ParseException; 31 import org.netbeans.api.lexer.Token; 32 import org.netbeans.api.lexer.TokenHierarchy; 33 import org.netbeans.api.lexer.TokenSequence; 34 import org.netbeans.editor.BaseDocument; 35 import org.netbeans.editor.BaseDocument; 36 import org.netbeans.editor.ext.ExtSyntaxSupport; 37 import org.netbeans.modules.languages.Feature; 38 import org.netbeans.modules.languages.Language; 39 import org.netbeans.modules.languages.LanguagesManagerImpl; 40 import org.netbeans.modules.languages.lexer.STokenId; 41 42 43 47 public class BraceHighlighting extends ExtSyntaxSupport { 48 49 public BraceHighlighting (BaseDocument doc) { 50 super (doc); 51 } 52 53 public int[] findMatchingBlock (int offset, boolean simpleSearch) throws BadLocationException { 54 try { 55 BaseDocument doc = getDocument (); 56 TokenHierarchy<BaseDocument> tokenHierarchy = TokenHierarchy.<BaseDocument>get (doc); 57 TokenSequence tokens = tokenHierarchy.tokenSequence(); 58 tokens.move(offset); 59 tokens.moveNext (); 60 Token<STokenId> token = tokens.token (); 61 String mimeType = (String ) doc.getProperty("mimeType"); Language language = ((LanguagesManagerImpl)LanguagesManager.getDefault()).getLanguage(mimeType); 63 Map <String ,String >[] bracesValue = getBraces (language); 64 if (bracesValue == null) { 65 return super.findMatchingBlock(offset, simpleSearch); 66 } 67 68 CharSequence text = token.text().toString(); 69 boolean moveToRight = false; 70 String bracket = bracesValue [0].get (text); 71 if (bracket != null) { 72 moveToRight = true; 73 } else { 74 bracket = bracesValue [1].get (text); 75 if (bracket == null) { 76 return null; 77 } 78 } 79 String focusedBracket = text.toString(); 80 int focusedBracketLength = focusedBracket.length(); 81 int length = bracket.length(); 82 int depth = 1; 83 while (moveToRight ? tokens.moveNext() : tokens.movePrevious()) { 84 token = tokens.token(); 85 text = token.text(); 86 if (text.length() == length && bracket.equals(text.toString())) { 87 depth--; 88 if (depth == 0) { 89 int position = token.offset(tokenHierarchy); 90 return new int[] {position, position + token.length()}; 91 } 92 } else if (text.length() == focusedBracketLength && focusedBracket.equals(text.toString())) { 93 depth++; 94 } 95 } 96 } catch (ConcurrentModificationException e) { 97 } catch (ParseException e) { 98 } 99 return null; 100 } 101 102 private static Map <Language,Map <String ,String >[]> braces = new WeakHashMap <Language,Map <String ,String >[]> (); 103 104 private static Map <String ,String >[] getBraces (Language l) { 105 if (!braces.containsKey (l)) { 106 Map <String ,String > startToEnd = new HashMap <String ,String > (); 107 Map <String ,String > endToStart = new HashMap <String ,String > (); 108 109 List <Feature> indents = l.getFeatures ("BRACE"); 110 Iterator <Feature> it = indents.iterator (); 111 while (it.hasNext ()) { 112 Feature indent = it.next (); 113 String s = (String ) indent.getValue (); 114 int i = s.indexOf (':'); 115 String start = s.substring (0, i); 116 String end = s.substring (i + 1); 117 startToEnd.put (start, end); 118 endToStart.put (end, start); 119 } 120 braces.put ( 121 l, 122 new Map [] {startToEnd, endToStart} 123 ); 124 } 125 return braces.get (l); 126 } 127 } 128 129 | Popular Tags |