package org.eclipse.ui.examples.javaeditor.java; | |
/* | |
* (c) Copyright IBM Corp. 2000, 2001. | |
* All Rights Reserved. | |
*/ | |
import org.eclipse.jface.text.BadLocationException; | |
import org.eclipse.jface.text.IDocument; | |
import org.eclipse.jface.text.ITextDoubleClickStrategy; | |
import org.eclipse.jface.text.ITextViewer; | |
/** | |
* Double click strategy aware of Java identifier syntax rules. | |
*/ | |
public class JavaDoubleClickSelector implements ITextDoubleClickStrategy { | |
protected ITextViewer fText; | |
protected int fPos; | |
protected int fStartPos; | |
protected int fEndPos; | |
protected static char[] fgBrackets= { '{', '}', '(', ')', '[', ']', '"', '"' }; | |
/* | |
* Create a JavaDoubleClickSelector. | |
*/ | |
public JavaDoubleClickSelector() { | |
super(); | |
} | |
/* (non-Javadoc) | |
* Method declared on ITextDoubleClickStrategy | |
*/ | |
public void doubleClicked(ITextViewer text) { | |
fPos= text.getSelectedRange().x; | |
if (fPos < 0) | |
return; | |
fText= text; | |
if (!selectBracketBlock()) | |
selectWord(); | |
} | |
/** | |
* Match the brackets at the current selection. Return true if successful, | |
* false otherwise. | |
*/ | |
protected boolean matchBracketsAt() { | |
char prevChar, nextChar; | |
int i; | |
int bracketIndex1= fgBrackets.length; | |
int bracketIndex2= fgBrackets.length; | |
fStartPos= -1; | |
fEndPos= -1; | |
// get the chars preceding and following the start position | |
try { | |
IDocument doc= fText.getDocument(); | |
prevChar= doc.getChar(fPos - 1); | |
nextChar= doc.getChar(fPos); | |
// is the char either an open or close bracket? | |
for (i= 0; i < fgBrackets.length; i= i + 2) { | |
if (prevChar == fgBrackets[i]) { | |
fStartPos= fPos - 1; | |
bracketIndex1= i; | |
} | |
} | |
for (i= 1; i < fgBrackets.length; i= i + 2) { | |
if (nextChar == fgBrackets[i]) { | |
fEndPos= fPos; | |
bracketIndex2= i; | |
} | |
} | |
if (fStartPos > -1 && bracketIndex1 < bracketIndex2) { | |
fEndPos= searchForClosingBracket(fStartPos, prevChar, fgBrackets[bracketIndex1 + 1], doc); | |
if (fEndPos > -1) | |
return true; | |
else | |
fStartPos= -1; | |
} else if (fEndPos > -1) { | |
fStartPos= searchForOpenBracket(fEndPos, fgBrackets[bracketIndex2 - 1], nextChar, doc); | |
if (fStartPos > -1) | |
return true; | |
else | |
fEndPos= -1; | |
} | |
} catch (BadLocationException x) { | |
} | |
return false; | |
} | |
/** | |
* Select the word at the current selection. Return true if successful, | |
* false otherwise. | |
*/ | |
protected boolean matchWord() { | |
IDocument doc= fText.getDocument(); | |
try { | |
int pos= fPos; | |
char c; | |
while (pos >= 0) { | |
c= doc.getChar(pos); | |
if (!Character.isJavaIdentifierPart(c)) | |
break; | |
--pos; | |
} | |
fStartPos= pos; | |
pos= fPos; | |
int length= doc.getLength(); | |
while (pos < length) { | |
c= doc.getChar(pos); | |
if (!Character.isJavaIdentifierPart(c)) | |
break; | |
++pos; | |
} | |
fEndPos= pos; | |
return true; | |
} catch (BadLocationException x) { | |
} | |
return false; | |
} | |
/** | |
* Returns the position of the closing bracket after startPosition. | |
* @returns the location of the closing bracket. | |
* @param startPosition - the beginning position | |
* @param openBracket - the character that represents the open bracket | |
* @param closeBracket - the character that represents the close bracket | |
* @param document - the document being searched | |
*/ | |
protected int searchForClosingBracket(int startPosition, char openBracket, char closeBracket, IDocument document) throws BadLocationException { | |
int stack= 1; | |
int closePosition= startPosition + 1; | |
int length= document.getLength(); | |
char nextChar; | |
while (closePosition < length && stack > 0) { | |
nextChar= document.getChar(closePosition); | |
if (nextChar == openBracket && nextChar != closeBracket) | |
stack++; | |
else if (nextChar == closeBracket) | |
stack--; | |
closePosition++; | |
} | |
if (stack == 0) | |
return closePosition - 1; | |
else | |
return -1; | |
} | |
/** | |
* Returns the position of the open bracket before startPosition. | |
* @returns the location of the starting bracket. | |
* @param startPosition - the beginning position | |
* @param openBracket - the character that represents the open bracket | |
* @param closeBracket - the character that represents the close bracket | |
* @param document - the document being searched | |
*/ | |
protected int searchForOpenBracket(int startPosition, char openBracket, char closeBracket, IDocument document) throws BadLocationException { | |
int stack= 1; | |
int openPos= startPosition - 1; | |
char nextChar; | |
while (openPos >= 0 && stack > 0) { | |
nextChar= document.getChar(openPos); | |
if (nextChar == closeBracket && nextChar != openBracket) | |
stack++; | |
else if (nextChar == openBracket) | |
stack--; | |
openPos--; | |
} | |
if (stack == 0) | |
return openPos + 1; | |
else | |
return -1; | |
} | |
/** | |
* Select the area between the selected bracket and the closing bracket. Return | |
* true if successful. | |
*/ | |
protected boolean selectBracketBlock() { | |
if (matchBracketsAt()) { | |
if (fStartPos == fEndPos) | |
fText.setSelectedRange(fStartPos, 0); | |
else | |
fText.setSelectedRange(fStartPos + 1, fEndPos - fStartPos - 1); | |
return true; | |
} | |
return false; | |
} | |
/** | |
* Select the word at the current selection. | |
*/ | |
protected void selectWord() { | |
if (matchWord()) { | |
if (fStartPos == fEndPos) | |
fText.setSelectedRange(fStartPos, 0); | |
else | |
fText.setSelectedRange(fStartPos + 1, fEndPos - fStartPos - 1); | |
} | |
} | |
} |