2 * Copyright (c) 2003-2004 Christopher Lenz and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
9 * Christopher Lenz - initial API and implementation
11 * $Id: CssDoubleClickStrategy.java,v 1.1 2004-09-02 18:11:48 jsurfer Exp $
14 package net.sourceforge.phpeclipse.css.ui.internal.text;
16 import net.sourceforge.phpeclipse.css.core.internal.text.CssTextUtils;
17 import net.sourceforge.phpeclipse.css.ui.CssUI;
19 import org.eclipse.jface.text.BadLocationException;
20 import org.eclipse.jface.text.IDocument;
21 import org.eclipse.jface.text.IRegion;
22 import org.eclipse.jface.text.ITextDoubleClickStrategy;
23 import org.eclipse.jface.text.ITextViewer;
24 import org.eclipse.jface.text.Region;
25 import org.eclipse.jface.text.source.ICharacterPairMatcher;
26 import org.eclipse.jface.util.Assert;
29 * Strategy for selecting CSS identifiers on double click in the editor.
31 * This strategy implements selection of CSS identifiers on double click inside
32 * an identifier, as well as selection of blocks delimited by square brackets,
33 * curly braces and parenthesis when the user double clicks directly after
34 * either the opening or the closing delimiter.
36 public class CssDoubleClickStrategy implements ITextDoubleClickStrategy {
38 // Instance Variables ------------------------------------------------------
41 * The pair matcher used to select ranges delimited by matching pairs of
42 * braces, brackets and parenthesis.
44 private ICharacterPairMatcher pairMatcher = new CssPairMatcher();
46 // ITextDoubleClickStrategy Implementation ---------------------------------
49 * @see ITextDoubleClickStrategy#doubleClicked(ITextViewer)
51 public void doubleClicked(ITextViewer viewer) {
52 IDocument document = viewer.getDocument();
53 if (document.getLength() == 0) {
56 int offset = viewer.getSelectedRange().x;
57 Assert.isLegal(offset >= 0,
58 "Double click offset may not be negative"); //$NON-NLS-1$
59 Assert.isLegal(offset <= document.getLength(),
60 "Double click offset out of range"); //$NON-NLS-1$
61 IRegion region = pairMatcher.match(document, offset);
62 if ((region != null) && (region.getLength() >= 2)) {
63 viewer.setSelectedRange(region.getOffset() + 1,
64 region.getLength() - 2);
67 region = getSurroundingIdentifier(document, offset);
69 viewer.setSelectedRange(
70 region.getOffset(), region.getLength());
72 } catch (BadLocationException e) {
73 CssUI.log("Failed to get surrounding " + //$NON-NLS-1$
74 "word for double click selection"); //$NON-NLS-1$
79 // Private Methods ---------------------------------------------------------
82 * Returns the region that delimits the identifier surrounding the given
83 * offset into the document. If no identifier is found at the specified
84 * offset, this method returns <code>null</code>.
86 * @param doc the document
87 * @param offset the zero-based offset into the document
88 * @return the region covered by the identifier, or <code>null</code> if no
89 * identifier was found at that offset
91 private IRegion getSurroundingIdentifier(IDocument doc, int offset)
92 throws BadLocationException {
93 IRegion retVal = null;
94 int length = doc.getLength();
95 offset = Math.min(offset, length - 1);
96 if (CssTextUtils.isCssIdentifierPart(doc.getChar(offset))) {
99 if (!CssTextUtils.isCssIdentifierPart(doc.getChar(start - 1))) {
105 while (end < (length - 1)) {
106 if (!CssTextUtils.isCssIdentifierPart(doc.getChar(end + 1))) {
111 retVal = new Region(start, end - start + 1);