View Javadoc

    1   /*
    2    * TextUtilities.java - Utility functions used by the text area classes
    3    * Copyright (C) 1999 Slava Pestov
    4    *
    5    * You may use and modify this package for any purpose. Redistribution is
    6    * permitted, in both source and binary form, provided that this notice
    7    * remains intact in all source distributions of this package.
    8    */
    9
    10  package org.syntax.jedit;
    11
    12  import javax.swing.text.BadLocationException;
    13  import javax.swing.text.Document;
    14
    15  /***
    16   * Class with several utility functions used by the text area component.
    17   * @author Slava Pestov
    18   * @version $Id$
    19   */
    20  public class TextUtilities
    21  {
    22  	/***
    23  	 * Returns the offset of the bracket matching the one at the
    24  	 * specified offset of the document, or -1 if the bracket is
    25  	 * unmatched (or if the character is not a bracket).
    26  	 * @param doc The document
    27  	 * @param offset The offset
    28  	 * @exception BadLocationException If an out-of-bounds access
    29  	 * was attempted on the document text
    30  	 */
    31  	public static int findMatchingBracket(Document doc, int offset)
    32  		throws BadLocationException
    33  	{
    34  		if(doc.getLength() == 0)
    35  			return -1;
    36  		char c = doc.getText(offset,1).charAt(0);
    37  		char cprime; // c` - corresponding character
    38  		boolean direction; // true = back, false = forward
    39
    40  		switch(c)
    41  		{
    42  		case '(': cprime = ')'; direction = false; break;
    43  		case ')': cprime = '('; direction = true; break;
    44  		case '[': cprime = ']'; direction = false; break;
    45  		case ']': cprime = '['; direction = true; break;
    46  		case '{': cprime = '}'; direction = false; break;
    47  		case '}': cprime = '{'; direction = true; break;
    48  		default: return -1;
    49  		}
    50
    51  		int count;
    52
    53  		// How to merge these two cases is left as an exercise
    54  		// for the reader.
    55
    56  		// Go back or forward
    57  		if(direction)
    58  		{
    59  			// Count is 1 initially because we have already
    60  			// `found' one closing bracket
    61  			count = 1;
    62
    63  			// Get text[0,offset-1];
    64  			String text = doc.getText(0,offset);
    65
    66  			// Scan backwards
    67  			for(int i = offset - 1; i >= 0; i--)
    68  			{
    69  				// If text[i] == c, we have found another
    70  				// closing bracket, therefore we will need
    71  				// two opening brackets to complete the
    72  				// match.
    73  				char x = text.charAt(i);
    74  				if(x == c)
    75  					count++;
    76
    77  				// If text[i] == cprime, we have found a
    78  				// opening bracket, so we return i if
    79  				// --count == 0
    80  				else if(x == cprime)
    81  				{
    82  					if(--count == 0)
    83  						return i;
    84  				}
    85  			}
    86  		}
    87  		else
    88  		{
    89  			// Count is 1 initially because we have already
    90  			// `found' one opening bracket
    91  			count = 1;
    92
    93  			// So we don't have to + 1 in every loop
    94  			offset++;
    95
    96  			// Number of characters to check
    97  			int len = doc.getLength() - offset;
    98
    99  			// Get text[offset+1,len];
    100 			String text = doc.getText(offset,len);
    101
    102 			// Scan forwards
    103 			for(int i = 0; i < len; i++)
    104 			{
    105 				// If text[i] == c, we have found another
    106 				// opening bracket, therefore we will need
    107 				// two closing brackets to complete the
    108 				// match.
    109 				char x = text.charAt(i);
    110
    111 				if(x == c)
    112 					count++;
    113
    114 				// If text[i] == cprime, we have found an
    115 				// closing bracket, so we return i if
    116 				// --count == 0
    117 				else if(x == cprime)
    118 				{
    119 					if(--count == 0)
    120 						return i + offset;
    121 				}
    122 			}
    123 		}
    124
    125 		// Nothing found
    126 		return -1;
    127 	}
    128
    129 	/***
    130 	 * Locates the start of the word at the specified position.
    131 	 * @param line The text
    132 	 * @param pos The position
    133 	 */
    134 	public static int findWordStart(String line, int pos, String noWordSep)
    135 	{
    136 		char ch = line.charAt(pos - 1);
    137
    138 		if(noWordSep == null)
    139 			noWordSep = "";
    140 		boolean selectNoLetter = (!Character.isLetterOrDigit(ch)
    141 			&& noWordSep.indexOf(ch) == -1);
    142
    143 		int wordStart = 0;
    144 		for(int i = pos - 1; i >= 0; i--)
    145 		{
    146 			ch = line.charAt(i);
    147 			if(selectNoLetter ^ (!Character.isLetterOrDigit(ch) &&
    148 				noWordSep.indexOf(ch) == -1))
    149 			{
    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 	{
    165 		char ch = line.charAt(pos);
    166
    167 		if(noWordSep == null)
    168 			noWordSep = "";
    169 		boolean selectNoLetter = (!Character.isLetterOrDigit(ch)
    170 			&& noWordSep.indexOf(ch) == -1);
    171
    172 		int wordEnd = line.length();
    173 		for(int i = pos; i < line.length(); i++)
    174 		{
    175 			ch = line.charAt(i);
    176 			if(selectNoLetter ^ (!Character.isLetterOrDigit(ch) &&
    177 				noWordSep.indexOf(ch) == -1))
    178 			{
    179 				wordEnd = i;
    180 				break;
    181 			}
    182 		}
    183 		return wordEnd;
    184 	}
    185 }