ide/src/wombat/gui/text/BracketMatcher.java
public void caretUpdate(CaretEvent event) {
		// Update the current row and column of the caret.
		try {
			// Find the current row of the caret.
			int caretPos = textArea.code.getCaretPosition();
			int rowNum = (caretPos == 0) ? 1 : 0;
			for (int offset = caretPos; offset > 0;) {
				offset = Utilities.getRowStart(textArea.code, offset) - 1;
				rowNum++;
			}

			// Use that to find the current column.
			int offset = Utilities.getRowStart(textArea.code, caretPos);
			int colNum = caretPos - offset + 1;

			MainFrame.Singleton().RowColumn.setText(rowNum + ":" + colNum);

		}

		// Can't find the caret correctly, reset the row:column indicator.
		catch (BadLocationException ex) {
			MainFrame.Singleton().RowColumn.setText("row:column");
		}

		// If the bracket matcher has broken, don't keep trying.
		if (disabled)
			return;

		try {
			// Get the highlighter and remove all active tags.
			Highlighter h = textArea.code.getHighlighter();
			for (Object tag : activeTags)
				h.removeHighlight(tag);
			activeTags.clear();

			// Get the caret position.
			int pos = event.getDot() - 1;

			// If the caret is in the document and adjacent to a bracket.
			if (pos >= 0 
					&& pos < textArea.getText().length()
					&& "()[]".contains(textArea.code.getDocument().getText(pos, 1))) {
				
				// Get a direct link to the full text of the document to speed up future access.
				String text = textArea.code.getDocument().getText(0, textArea.code.getDocument().getLength());

				// Skip character literals
				if (pos >= 2 && "#\\".equals(text.substring(pos - 2, pos)))
					return;

				// Skip if we're in a comment
				if ((text.lastIndexOf("#|", pos) > text.lastIndexOf("|#", pos))
						|| (text.lastIndexOf(';', pos) > text.lastIndexOf('\n', pos)))
					return;
				
				// Which way are we going?
				char orig, c;
				orig = c = text.charAt(pos);
				int matchPos, d = ((orig == '(' || orig == '[') ? 1 : -1);
				
				// Keep a stack of brackets so we find the correct level.
				Stack<Character> brackets = new Stack<Character>();
				
				// Loop either forward or back depending on opening or closing initial bracket.
				int index;
				boolean foundMatch = false;
				for (matchPos = pos; matchPos >= 0 && matchPos < text.length(); matchPos += d) {
					// When moving towards the front:
					if (d < 0) {
						// Ignore line comments.
						index = text.lastIndexOf(';', matchPos);
						if (index >= 0 && index > text.lastIndexOf("\n", matchPos)) {
							matchPos = index;
							continue;
						}

						// Ignore block comments.
						index = text.lastIndexOf("#|", matchPos);
						if (index >= 0 && index < matchPos && matchPos < text.indexOf("|#")) {
							matchPos = index;
							continue;
						}
					}
					
					// When moving towards the end:
					else {
						// Ignore line comments.
						index = text.lastIndexOf(';', matchPos);
						if (index >= 0 && text.lastIndexOf('\n', matchPos) < index) {
							matchPos = text.indexOf('\n', matchPos);
							if (matchPos < 0) break;
							continue;
						}
						
						// Ignore block comments.
						index = text.indexOf("|#", matchPos);
						if (index >= 0 && text.lastIndexOf("#|", matchPos) < matchPos && matchPos < index) {
							matchPos = index;
							continue;
						}
					}

					// Get the current character.
					c = text.charAt(matchPos);

					// Ignore character literals
					if (matchPos >= 2 && "#\\".equals(text.substring(matchPos - 2, matchPos)))
						continue;

					// We're only done when we're at the correct level and find the correct bracket.
					if (!brackets.isEmpty() && brackets.peek() == c) {
						brackets.pop();
						if (brackets.isEmpty()) {
							foundMatch = true;
							break;
						}
					}
					
					// If we still have brackets to deal with, make sure it's the correct kind.
					// If it's the incorrect kind, highligh with an error (default = red).
					else if (!brackets.isEmpty()
							&& ((brackets.peek() == '(' && c == '[')
									|| (brackets.peek() == '[' && c == '(')
									|| (brackets.peek() == ')' && c == ']') 
									|| (brackets.peek() == ']' && c == ')'))) {
						foundMatch = false;
						break;
					}

					// Remember bracket level.
					else if (c == '(')
						brackets.push(')');
					else if (c == ')')
						brackets.push('(');
					else if (c == '[')
						brackets.push(']');
					else if (c == ']')
						brackets.push('[');
				}

				// Highlight it.
				Highlighter.HighlightPainter hp = new DefaultHighlighter.DefaultHighlightPainter(
						StyleConstants.getForeground(SchemeDocument.attributes.get(foundMatch ? "bracket" : "invalid-bracket")));

				// Remember the bracket so we can remove it on the next cycle.
				try {
					activeTags.add(h.addHighlight(pos, pos + 1, hp));
					activeTags.add(h.addHighlight(matchPos, matchPos + 1, hp));
				} catch (BadLocationException ble) {
				}
			}
		} 
		
		// Ignore bad locations. This is usually empty documents.
		catch (BadLocationException ex) {

		} 
		
		// If we get this, we broke the bracket matcher. Remember the error and disable it for the future.
		// This shouldn't happen unless things go badly wrong.
		catch (Exception ex) {
			ErrorManager.logError("Unable to match paranthesis: " + ex.getMessage());
			ex.printStackTrace();
			disabled = true;
		}
	}
/**
	 * When the caret moves, update the matched brackets.
	 * 
	 * Also used to show the current line and column. TODO: Move this code to
	 * its own object.
	 * 
	 * @param event
	 *            Event parameters (ignored).
	 */
When the caret moves, update the matched brackets.

Also used to show the current line and column. TODO: Move this code to
its own object.

@param event
Event parameters (ignored).
When the caret moves update the matched brackets . Also used to show the current line and column . TODO : Move this code to its own object . @param event Event parameters ( ignored ) .
public void caretUpdate(CaretEvent event) {
		try {
			int caretPos = textArea.code.getCaretPosition();
			int rowNum = (caretPos == 0) ? 1 : 0;
			for (int offset = caretPos; offset > 0;) {
				offset = Utilities.getRowStart(textArea.code, offset) - 1;
				rowNum++;
			}
			int offset = Utilities.getRowStart(textArea.code, caretPos);
			int colNum = caretPos - offset + 1;
			MainFrame.Singleton().RowColumn.setText(rowNum + ":" + colNum);
		}
		catch (BadLocationException ex) {
			MainFrame.Singleton().RowColumn.setText("row:column");
		}
		if (disabled)
			return;
		try {
			Highlighter h = textArea.code.getHighlighter();
			for (Object tag : activeTags)
				h.removeHighlight(tag);
			activeTags.clear();
			int pos = event.getDot() - 1;
			if (pos >= 0 
					&& pos < textArea.getText().length()
					&& "()[]".contains(textArea.code.getDocument().getText(pos, 1))) {
				String text = textArea.code.getDocument().getText(0, textArea.code.getDocument().getLength());
				if (pos >= 2 && "#\\".equals(text.substring(pos - 2, pos)))
					return;
				if ((text.lastIndexOf("#|", pos) > text.lastIndexOf("|#", pos))
						|| (text.lastIndexOf(';', pos) > text.lastIndexOf('\n', pos)))
					return;
				char orig, c;
				orig = c = text.charAt(pos);
				int matchPos, d = ((orig == '(' || orig == '[') ? 1 : -1);
				Stack<Character> brackets = new Stack<Character>();
				int index;
				boolean foundMatch = false;
				for (matchPos = pos; matchPos >= 0 && matchPos < text.length(); matchPos += d) {
					if (d < 0) {
						index = text.lastIndexOf(';', matchPos);
						if (index >= 0 && index > text.lastIndexOf("\n", matchPos)) {
							matchPos = index;
							continue;
						}
						index = text.lastIndexOf("#|", matchPos);
						if (index >= 0 && index < matchPos && matchPos < text.indexOf("|#")) {
							matchPos = index;
							continue;
						}
					}
					else {
						index = text.lastIndexOf(';', matchPos);
						if (index >= 0 && text.lastIndexOf('\n', matchPos) < index) {
							matchPos = text.indexOf('\n', matchPos);
							if (matchPos < 0) break;
							continue;
						}
						index = text.indexOf("|#", matchPos);
						if (index >= 0 && text.lastIndexOf("#|", matchPos) < matchPos && matchPos < index) {
							matchPos = index;
							continue;
						}
					}
					c = text.charAt(matchPos);
					if (matchPos >= 2 && "#\\".equals(text.substring(matchPos - 2, matchPos)))
						continue;
					if (!brackets.isEmpty() && brackets.peek() == c) {
						brackets.pop();
						if (brackets.isEmpty()) {
							foundMatch = true;
							break;
						}
					}
					else if (!brackets.isEmpty()
							&& ((brackets.peek() == '(' && c == '[')
									|| (brackets.peek() == '[' && c == '(')
									|| (brackets.peek() == ')' && c == ']') 
									|| (brackets.peek() == ']' && c == ')'))) {
						foundMatch = false;
						break;
					}
					else if (c == '(')
						brackets.push(')');
					else if (c == ')')
						brackets.push('(');
					else if (c == '[')
						brackets.push(']');
					else if (c == ']')
						brackets.push('[');
				}
				Highlighter.HighlightPainter hp = new DefaultHighlighter.DefaultHighlightPainter(
						StyleConstants.getForeground(SchemeDocument.attributes.get(foundMatch ? "bracket" : "invalid-bracket")));
				try {
					activeTags.add(h.addHighlight(pos, pos + 1, hp));
					activeTags.add(h.addHighlight(matchPos, matchPos + 1, hp));
				} catch (BadLocationException ble) {
				}
			}
		} 
		catch (BadLocationException ex) {
		} 
		catch (Exception ex) {
			ErrorManager.logError("Unable to match paranthesis: " + ex.getMessage());
			ex.printStackTrace();
			disabled = true;
		}
	}
public void caretUpdate ( CaretEvent event ) { try { int caretPos = textArea . code . getCaretPosition ( ) ; int rowNum = ( caretPos == 0 ) ? 1 : 0 ; for ( int offset = caretPos ; offset > 0 ; ) { offset = Utilities . getRowStart ( textArea . code , offset ) - 1 ; rowNum ++ ; } int offset = Utilities . getRowStart ( textArea . code , caretPos ) ; int colNum = caretPos - offset + 1 ; MainFrame . Singleton ( ) . RowColumn . setText ( rowNum + ":" + colNum ) ; } catch ( BadLocationException ex ) { MainFrame . Singleton ( ) . RowColumn . setText ( "row:column" ) ; } if ( disabled ) return ; try { Highlighter h = textArea . code . getHighlighter ( ) ; for ( Object tag : activeTags ) h . removeHighlight ( tag ) ; activeTags . clear ( ) ; int pos = event . getDot ( ) - 1 ; if ( pos >= 0 && pos < textArea . getText ( ) . length ( ) && "()[]" . contains ( textArea . code . getDocument ( ) . getText ( pos , 1 ) ) ) { String text = textArea . code . getDocument ( ) . getText ( 0 , textArea . code . getDocument ( ) . getLength ( ) ) ; if ( pos >= 2 && "#\\" . equals ( text . substring ( pos - 2 , pos ) ) ) return ; if ( ( text . lastIndexOf ( "#|" , pos ) > text . lastIndexOf ( "|#" , pos ) ) || ( text . lastIndexOf ( ';' , pos ) > text . lastIndexOf ( '\n' , pos ) ) ) return ; char orig , c ; orig = c = text . charAt ( pos ) ; int matchPos , d = ( ( orig == '(' || orig == '[' ) ? 1 : - 1 ) ; Stack < Character > brackets = new Stack < Character > ( ) ; int index ; boolean foundMatch = false ; for ( matchPos = pos ; matchPos >= 0 && matchPos < text . length ( ) ; matchPos += d ) { if ( d < 0 ) { index = text . lastIndexOf ( ';' , matchPos ) ; if ( index >= 0 && index > text . lastIndexOf ( "\n" , matchPos ) ) { matchPos = index ; continue ; } index = text . lastIndexOf ( "#|" , matchPos ) ; if ( index >= 0 && index < matchPos && matchPos < text . indexOf ( "|#" ) ) { matchPos = index ; continue ; } } else { index = text . lastIndexOf ( ';' , matchPos ) ; if ( index >= 0 && text . lastIndexOf ( '\n' , matchPos ) < index ) { matchPos = text . indexOf ( '\n' , matchPos ) ; if ( matchPos < 0 ) break ; continue ; } index = text . indexOf ( "|#" , matchPos ) ; if ( index >= 0 && text . lastIndexOf ( "#|" , matchPos ) < matchPos && matchPos < index ) { matchPos = index ; continue ; } } c = text . charAt ( matchPos ) ; if ( matchPos >= 2 && "#\\" . equals ( text . substring ( matchPos - 2 , matchPos ) ) ) continue ; if ( ! brackets . isEmpty ( ) && brackets . peek ( ) == c ) { brackets . pop ( ) ; if ( brackets . isEmpty ( ) ) { foundMatch = true ; break ; } } else if ( ! brackets . isEmpty ( ) && ( ( brackets . peek ( ) == '(' && c == '[' ) || ( brackets . peek ( ) == '[' && c == '(' ) || ( brackets . peek ( ) == ')' && c == ']' ) || ( brackets . peek ( ) == ']' && c == ')' ) ) ) { foundMatch = false ; break ; } else if ( c == '(' ) brackets . push ( ')' ) ; else if ( c == ')' ) brackets . push ( '(' ) ; else if ( c == '[' ) brackets . push ( ']' ) ; else if ( c == ']' ) brackets . push ( '[' ) ; } Highlighter . HighlightPainter hp = new DefaultHighlighter . DefaultHighlightPainter ( StyleConstants . getForeground ( SchemeDocument . attributes . get ( foundMatch ? "bracket" : "invalid-bracket" ) ) ) ; try { activeTags . add ( h . addHighlight ( pos , pos + 1 , hp ) ) ; activeTags . add ( h . addHighlight ( matchPos , matchPos + 1 , hp ) ) ; } catch ( BadLocationException ble ) { } } } catch ( BadLocationException ex ) { } catch ( Exception ex ) { ErrorManager . logError ( "Unable to match paranthesis: " + ex . getMessage ( ) ) ; ex . printStackTrace ( ) ; disabled = true ; } }
When the caret moves, update the matched brackets.
When the caret moves update the matched brackets .
// Update the current row and column of the caret. // Find the current row of the caret. // Use that to find the current column. // Can't find the caret correctly, reset the row:column indicator. // If the bracket matcher has broken, don't keep trying. // Get the highlighter and remove all active tags. // Get the caret position. // If the caret is in the document and adjacent to a bracket. // Get a direct link to the full text of the document to speed up future access. // Skip character literals // Skip if we're in a comment // Which way are we going? // Keep a stack of brackets so we find the correct level. // Loop either forward or back depending on opening or closing initial bracket. // When moving towards the front: // Ignore line comments. // Ignore block comments. // When moving towards the end: // Ignore line comments. // Ignore block comments. // Get the current character. // Ignore character literals // We're only done when we're at the correct level and find the correct bracket. // If we still have brackets to deal with, make sure it's the correct kind. // If it's the incorrect kind, highligh with an error (default = red). // Remember bracket level. // Highlight it. // Remember the bracket so we can remove it on the next cycle. // Ignore bad locations. This is usually empty documents. // If we get this, we broke the bracket matcher. Remember the error and disable it for the future. // This shouldn't happen unless things go badly wrong.