001: package bluej.editor.moe;
002:
003: /*
004: * TextUtilities.java - Utility functions used by the text area classes
005: * Copyright (C) 1999 Slava Pestov
006: *
007: * You may use and modify this package for any purpose. Redistribution is
008: * permitted, in both source and binary form, provided that this notice
009: * remains intact in all source distributions of this package.
010: */
011:
012: import javax.swing.text.*;
013:
014: /**
015: * Class with several utility functions used by the text area component.
016: * @author Slava Pestov
017: * @version $Id: TextUtilities.java 4757 2006-12-08 04:41:48Z davmac $
018: */
019: public class TextUtilities {
020: /**
021: * Returns the offset of the bracket matching the one at the
022: * specified offset of the document, or -1 if the bracket is
023: * unmatched (or if the character is not a bracket).
024: * @param doc The document
025: * @param offset The offset
026: * @exception BadLocationException If an out-of-bounds access
027: * was attempted on the document text
028: */
029: public static int findMatchingBracket(Document doc, int offset)
030: throws BadLocationException {
031: if (doc.getLength() == 0) {
032: return -1;
033: }
034:
035: char c = doc.getText(offset, 1).charAt(0);
036: char cprime; // c` - corresponding character
037: boolean direction; // true = back, false = forward
038:
039: switch (c) {
040: case '(':
041: cprime = ')';
042: direction = false;
043: break;
044: case ')':
045: cprime = '(';
046: direction = true;
047: break;
048: case '[':
049: cprime = ']';
050: direction = false;
051: break;
052: case ']':
053: cprime = '[';
054: direction = true;
055: break;
056: case '{':
057: cprime = '}';
058: direction = false;
059: break;
060: case '}':
061: cprime = '{';
062: direction = true;
063: break;
064: default:
065: return -1;
066: }
067:
068: int count = 1;
069: int step;
070: int texttOffset;
071: int len;
072: int i;
073: if (direction) {
074: // search backwards
075: step = -1;
076: texttOffset = 0;
077: len = offset;
078: i = len - 1;
079: } else {
080: // search forwards
081: step = 1;
082: texttOffset = offset + 1;
083: len = doc.getLength() - texttOffset;
084: i = 0;
085: }
086: String textt = doc.getText(texttOffset, len);
087:
088: while (len > 0) {
089: char x = textt.charAt(i);
090: if (x == c) {
091: count++;
092: }
093:
094: // If text[i] == cprime, we have found a
095: // opening bracket, so we return i if
096: // --count == 0
097: else if (x == cprime) {
098: if (--count == 0) {
099: return i + texttOffset;
100: }
101: }
102:
103: len--;
104: i += step;
105:
106: if (x == '\"' || x == '\'') {
107: char quoteChar = x;
108: // A quoted string, need to find the matching quote before matching
109: // further brackets...
110: while (len > 0) {
111: x = textt.charAt(i);
112: if (x == quoteChar) {
113: // Found the matching quote, as long as it is not \-quoted.
114: if (i == 0 || textt.charAt(i - 1) != '\\') {
115: len--;
116: i += step;
117: break;
118: }
119: }
120: len--;
121: i += step;
122: }
123: }
124: }
125:
126: // Nothing found
127: return -1;
128: }
129:
130: /**
131: * Locates the start of the word at the specified position.
132: * @param line The text
133: * @param pos The position
134: */
135: public static int findWordStart(String line, int pos,
136: String noWordSep) {
137: char ch = line.charAt(pos - 1);
138:
139: if (noWordSep == null)
140: noWordSep = "";
141: boolean selectNoLetter = (!Character.isLetterOrDigit(ch) && noWordSep
142: .indexOf(ch) == -1);
143:
144: int wordStart = 0;
145: for (int i = pos - 1; i >= 0; i--) {
146: ch = line.charAt(i);
147: if (selectNoLetter
148: ^ (!Character.isLetterOrDigit(ch) && noWordSep
149: .indexOf(ch) == -1)) {
150: wordStart = i + 1;
151: break;
152: }
153: }
154:
155: return wordStart;
156: }
157:
158: /**
159: * Locates the end of the word at the specified position.
160: * @param line The text
161: * @param pos The position
162: */
163: public static int findWordEnd(String line, int pos, String noWordSep) {
164: char ch = line.charAt(pos);
165:
166: if (noWordSep == null)
167: noWordSep = "";
168: boolean selectNoLetter = (!Character.isLetterOrDigit(ch) && noWordSep
169: .indexOf(ch) == -1);
170:
171: int wordEnd = line.length();
172: for (int i = pos; i < line.length(); i++) {
173: ch = line.charAt(i);
174: if (selectNoLetter
175: ^ (!Character.isLetterOrDigit(ch) && noWordSep
176: .indexOf(ch) == -1)) {
177: wordEnd = i;
178: break;
179: }
180: }
181: return wordEnd;
182: }
183: }
|