001: /*
002: * Copyright (C) 2005 - 2008 JasperSoft Corporation. All rights reserved.
003: * http://www.jaspersoft.com.
004: *
005: * Unless you have purchased a commercial license agreement from JasperSoft,
006: * the following license terms apply:
007: *
008: * This program is free software; you can redistribute it and/or modify
009: * it under the terms of the GNU General Public License version 2 as published by
010: * the Free Software Foundation.
011: *
012: * This program is distributed WITHOUT ANY WARRANTY; and without the
013: * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
014: * See the GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, see http://www.gnu.org/licenses/gpl.txt
018: * or write to:
019: *
020: * Free Software Foundation, Inc.,
021: * 59 Temple Place - Suite 330,
022: * Boston, MA USA 02111-1307
023: *
024: *
025: *
026: *
027: * TextUtilities.java
028: *
029: */
030:
031: package org.syntax.jedit;
032:
033: import javax.swing.text.*;
034:
035: /**
036: * Class with several utility functions used by the text area component.
037: * @author Slava Pestov
038: * @version $Id: TextUtilities.java 1167 2008-01-15 18:49:05Z gtoffoli $
039: */
040: public class TextUtilities {
041: /**
042: * Returns the offset of the bracket matching the one at the
043: * specified offset of the document, or -1 if the bracket is
044: * unmatched (or if the character is not a bracket).
045: * @param doc The document
046: * @param offset The offset
047: * @exception BadLocationException If an out-of-bounds access
048: * was attempted on the document text
049: */
050: public static int findMatchingBracket(Document doc, int offset)
051: throws BadLocationException {
052: if (doc.getLength() == 0)
053: return -1;
054: char c = doc.getText(offset, 1).charAt(0);
055: char cprime; // c` - corresponding character
056: boolean direction; // true = back, false = forward
057:
058: switch (c) {
059: case '(':
060: cprime = ')';
061: direction = false;
062: break;
063: case ')':
064: cprime = '(';
065: direction = true;
066: break;
067: case '[':
068: cprime = ']';
069: direction = false;
070: break;
071: case ']':
072: cprime = '[';
073: direction = true;
074: break;
075: case '{':
076: cprime = '}';
077: direction = false;
078: break;
079: case '}':
080: cprime = '{';
081: direction = true;
082: break;
083: default:
084: return -1;
085: }
086:
087: int count;
088:
089: // How to merge these two cases is left as an exercise
090: // for the reader.
091:
092: // Go back or forward
093: if (direction) {
094: // Count is 1 initially because we have already
095: // `found' one closing bracket
096: count = 1;
097:
098: // Get text[0,offset-1];
099: String text = doc.getText(0, offset);
100:
101: // Scan backwards
102: for (int i = offset - 1; i >= 0; i--) {
103: // If text[i] == c, we have found another
104: // closing bracket, therefore we will need
105: // two opening brackets to complete the
106: // match.
107: char x = text.charAt(i);
108: if (x == c)
109: count++;
110:
111: // If text[i] == cprime, we have found a
112: // opening bracket, so we return i if
113: // --count == 0
114: else if (x == cprime) {
115: if (--count == 0)
116: return i;
117: }
118: }
119: } else {
120: // Count is 1 initially because we have already
121: // `found' one opening bracket
122: count = 1;
123:
124: // So we don't have to + 1 in every loop
125: offset++;
126:
127: // Number of characters to check
128: int len = doc.getLength() - offset;
129:
130: // Get text[offset+1,len];
131: String text = doc.getText(offset, len);
132:
133: // Scan forwards
134: for (int i = 0; i < len; i++) {
135: // If text[i] == c, we have found another
136: // opening bracket, therefore we will need
137: // two closing brackets to complete the
138: // match.
139: char x = text.charAt(i);
140:
141: if (x == c)
142: count++;
143:
144: // If text[i] == cprime, we have found an
145: // closing bracket, so we return i if
146: // --count == 0
147: else if (x == cprime) {
148: if (--count == 0)
149: return i + offset;
150: }
151: }
152: }
153:
154: // Nothing found
155: return -1;
156: }
157:
158: /**
159: * Locates the start of the word at the specified position.
160: * @param line The text
161: * @param pos The position
162: */
163: public static int findWordStart(String line, int pos,
164: String noWordSep) {
165: char ch = line.charAt(pos - 1);
166:
167: if (noWordSep == null)
168: noWordSep = "";
169: boolean selectNoLetter = (!Character.isLetterOrDigit(ch) && noWordSep
170: .indexOf(ch) == -1);
171:
172: int wordStart = 0;
173: for (int i = pos - 1; i >= 0; i--) {
174: ch = line.charAt(i);
175: if (selectNoLetter
176: ^ (!Character.isLetterOrDigit(ch) && noWordSep
177: .indexOf(ch) == -1)) {
178: wordStart = i + 1;
179: break;
180: }
181: }
182:
183: return wordStart;
184: }
185:
186: /**
187: * Locates the end of the word at the specified position.
188: * @param line The text
189: * @param pos The position
190: */
191: public static int findWordEnd(String line, int pos, String noWordSep) {
192: char ch = line.charAt(pos);
193:
194: if (noWordSep == null)
195: noWordSep = "";
196: boolean selectNoLetter = (!Character.isLetterOrDigit(ch) && noWordSep
197: .indexOf(ch) == -1);
198:
199: int wordEnd = line.length();
200: for (int i = pos; i < line.length(); i++) {
201: ch = line.charAt(i);
202: if (selectNoLetter
203: ^ (!Character.isLetterOrDigit(ch) && noWordSep
204: .indexOf(ch) == -1)) {
205: wordEnd = i;
206: break;
207: }
208: }
209: return wordEnd;
210: }
211: }
|