/* * Copyright 2004-2014 SmartBear Software * * Licensed under the EUPL, Version 1.1 or - as soon as they will be approved by the European Commission - subsequent * versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * * http://ec.europa.eu/idabc/eupl * * Unless required by applicable law or agreed to in writing, software distributed under the Licence is * distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the Licence for the specific language governing permissions and limitations * under the Licence. */ package org.syntax.jedit; import javax.swing.text.BadLocationException; import javax.swing.text.Document; /** * Class with several utility functions used by the text area component. * * @author Slava Pestov * @version $Id$ */ public class TextUtilities { /** * Returns the offset of the bracket matching the one at the specified offset * of the document, or -1 if the bracket is unmatched (or if the character is * not a bracket). * * @param doc The document * @param offset The offset * @throws BadLocationException If an out-of-bounds access was attempted on the document * text */ public static int findMatchingBracket(Document doc, int offset) throws BadLocationException { if (doc.getLength() == 0) { return -1; } char c = doc.getText(offset, 1).charAt(0); char cprime; // c` - corresponding character boolean direction; // true = back, false = forward switch (c) { case '(': cprime = ')'; direction = false; break; case ')': cprime = '('; direction = true; break; case '[': cprime = ']'; direction = false; break; case ']': cprime = '['; direction = true; break; case '{': cprime = '}'; direction = false; break; case '}': cprime = '{'; direction = true; break; default: return -1; } int count; // How to merge these two cases is left as an exercise // for the reader. // Go back or forward if (direction) { // Count is 1 initially because we have already // `found' one closing bracket count = 1; // Get text[0,offset-1]; String text = doc.getText(0, offset); // Scan backwards for (int i = offset - 1; i >= 0; i--) { // If text[i] == c, we have found another // closing bracket, therefore we will need // two opening brackets to complete the // match. char x = text.charAt(i); if (x == c) { count++; } // If text[i] == cprime, we have found a // opening bracket, so we return i if // --count == 0 else if (x == cprime) { if (--count == 0) { return i; } } } } else { // Count is 1 initially because we have already // `found' one opening bracket count = 1; // So we don't have to + 1 in every loop offset++; // Number of characters to check int len = doc.getLength() - offset; // Get text[offset+1,len]; String text = doc.getText(offset, len); // Scan forwards for (int i = 0; i < len; i++) { // If text[i] == c, we have found another // opening bracket, therefore we will need // two closing brackets to complete the // match. char x = text.charAt(i); if (x == c) { count++; } // If text[i] == cprime, we have found an // closing bracket, so we return i if // --count == 0 else if (x == cprime) { if (--count == 0) { return i + offset; } } } } // Nothing found return -1; } /** * Locates the start of the word at the specified position. * * @param line The text * @param pos The position */ public static int findWordStart(String line, int pos, String noWordSep) { char ch = line.charAt(pos - 1); if (noWordSep == null) { noWordSep = ""; } boolean selectNoLetter = (!Character.isLetterOrDigit(ch) && noWordSep.indexOf(ch) == -1); int wordStart = 0; for (int i = pos - 1; i >= 0; i--) { ch = line.charAt(i); if (selectNoLetter ^ (!Character.isLetterOrDigit(ch) && noWordSep.indexOf(ch) == -1)) { wordStart = i + 1; break; } } return wordStart; } /** * Locates the end of the word at the specified position. * * @param line The text * @param pos The position */ public static int findWordEnd(String line, int pos, String noWordSep) { char ch = line.charAt(pos); if (noWordSep == null) { noWordSep = ""; } boolean selectNoLetter = (!Character.isLetterOrDigit(ch) && noWordSep.indexOf(ch) == -1); int wordEnd = line.length(); for (int i = pos; i < line.length(); i++) { ch = line.charAt(i); if (selectNoLetter ^ (!Character.isLetterOrDigit(ch) && noWordSep.indexOf(ch) == -1)) { wordEnd = i; break; } } return wordEnd; } }