mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-23 08:55:25 +02:00
Fix string double click selection
This commit is contained in:
parent
32163b8508
commit
bf61f08fdb
4 changed files with 142 additions and 216 deletions
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000 2006 IBM Corporation and others.
|
||||
* Copyright (c) 2000, 2007 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -12,7 +12,6 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.ui.text;
|
||||
|
||||
import org.eclipse.jface.text.BadLocationException;
|
||||
import org.eclipse.jface.text.IDocument;
|
||||
import org.eclipse.jface.text.IRegion;
|
||||
import org.eclipse.jface.text.ITextDoubleClickStrategy;
|
||||
|
@ -23,111 +22,35 @@ import org.eclipse.jface.text.ITextViewer;
|
|||
*/
|
||||
public class CDoubleClickSelector implements ITextDoubleClickStrategy {
|
||||
|
||||
protected ITextViewer fText;
|
||||
protected int fPos;
|
||||
protected int fStartPos;
|
||||
protected int fEndPos;
|
||||
private CPairMatcher fPairMatcher;
|
||||
|
||||
|
||||
protected static char[] fgBrackets= {'{', '}', '(', ')', '[', ']', '"', '"'};
|
||||
protected static char[] fgBrackets= {'{', '}', '(', ')', '[', ']', '<', '>'};
|
||||
private CPairMatcher fPairMatcher= new CPairMatcher(fgBrackets);
|
||||
|
||||
public CDoubleClickSelector() {
|
||||
super();
|
||||
fPairMatcher= new CPairMatcher(fgBrackets);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see ITextDoubleClickStrategy#doubleClicked
|
||||
/*
|
||||
* @see org.eclipse.jface.text.ITextDoubleClickStrategy#doubleClicked(org.eclipse.jface.text.ITextViewer)
|
||||
*/
|
||||
public void doubleClicked(ITextViewer text) {
|
||||
fPos= text.getSelectedRange().x;
|
||||
public void doubleClicked(ITextViewer textViewer) {
|
||||
int offset= textViewer.getSelectedRange().x;
|
||||
|
||||
|
||||
if (fPos < 0)
|
||||
if (offset < 0)
|
||||
return;
|
||||
|
||||
IDocument document= textViewer.getDocument();
|
||||
|
||||
fText= text;
|
||||
|
||||
|
||||
if (!selectBracketBlock())
|
||||
selectWord();
|
||||
|
||||
fText= null;
|
||||
}
|
||||
|
||||
|
||||
protected boolean matchBracketsAt() {
|
||||
IRegion region= fPairMatcher.match(fText.getDocument(), fPos);
|
||||
if (region != null && region.getLength() > 0) {
|
||||
fStartPos= region.getOffset();
|
||||
fEndPos= fStartPos + region.getLength() - 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
protected boolean selectBracketBlock() {
|
||||
if (matchBracketsAt()) {
|
||||
if (fStartPos == fEndPos)
|
||||
fText.setSelectedRange(fStartPos, 0);
|
||||
else
|
||||
fText.setSelectedRange(fStartPos + 1, fEndPos - fStartPos - 1);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
protected void selectWord() {
|
||||
if (matchWord()) {
|
||||
if (fStartPos == fEndPos)
|
||||
fText.setSelectedRange(fStartPos, 0);
|
||||
else
|
||||
fText.setSelectedRange(fStartPos + 1, fEndPos - fStartPos - 1);
|
||||
IRegion region= fPairMatcher.match(document, offset);
|
||||
if (region != null && region.getLength() >= 2) {
|
||||
textViewer.setSelectedRange(region.getOffset() + 1, region.getLength() - 2);
|
||||
} else {
|
||||
region= selectWord(document, offset);
|
||||
textViewer.setSelectedRange(region.getOffset(), region.getLength());
|
||||
}
|
||||
}
|
||||
|
||||
protected IRegion selectWord(IDocument document, int offset) {
|
||||
return CWordFinder.findWord(document, offset);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000 2006 IBM Corporation and others.
|
||||
* Copyright (c) 2000, 2007 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -12,132 +12,17 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.ui.text;
|
||||
|
||||
import org.eclipse.jface.text.BadLocationException;
|
||||
import org.eclipse.jface.text.IDocument;
|
||||
import org.eclipse.jface.text.IRegion;
|
||||
import org.eclipse.jface.text.Region;
|
||||
import org.eclipse.jface.text.TextUtilities;
|
||||
import org.eclipse.jface.text.source.ICharacterPairMatcher;
|
||||
import org.eclipse.jface.text.source.DefaultCharacterPairMatcher;
|
||||
|
||||
import org.eclipse.cdt.ui.text.ICPartitions;
|
||||
|
||||
/**
|
||||
* Helper class for match pairs of characters.
|
||||
*/
|
||||
public class CPairMatcher implements ICharacterPairMatcher {
|
||||
|
||||
protected char[] fPairs;
|
||||
protected IDocument fDocument;
|
||||
protected int fOffset;
|
||||
|
||||
protected int fStartPos;
|
||||
protected int fEndPos;
|
||||
protected int fAnchor;
|
||||
public class CPairMatcher extends DefaultCharacterPairMatcher {
|
||||
|
||||
public CPairMatcher(char[] pairs) {
|
||||
fPairs = pairs;
|
||||
super(pairs, ICPartitions.C_PARTITIONING);
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.eclipse.jface.text.source.ICharacterPairMatcher#match(org.eclipse.jface.text.IDocument, int)
|
||||
*/
|
||||
public IRegion match(IDocument document, int offset) {
|
||||
|
||||
fOffset = offset;
|
||||
|
||||
if (fOffset < 0)
|
||||
return null;
|
||||
|
||||
fDocument = document;
|
||||
|
||||
if (matchPairsAt() && fStartPos != fEndPos)
|
||||
return new Region(fStartPos, fEndPos - fStartPos + 1);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.eclipse.jface.text.source.ICharacterPairMatcher#getAnchor()
|
||||
*/
|
||||
public int getAnchor() {
|
||||
return fAnchor;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.eclipse.jface.text.source.ICharacterPairMatcher#clear()
|
||||
*/
|
||||
public void clear() {
|
||||
}
|
||||
|
||||
/*
|
||||
* @see org.eclipse.jface.text.source.ICharacterPairMatcher#dispose()
|
||||
*/
|
||||
public void dispose() {
|
||||
clear();
|
||||
fDocument = null;
|
||||
}
|
||||
|
||||
protected boolean matchPairsAt() {
|
||||
|
||||
int i;
|
||||
int pairIndex1= fPairs.length;
|
||||
int pairIndex2= fPairs.length;
|
||||
|
||||
fStartPos= -1;
|
||||
fEndPos= -1;
|
||||
|
||||
// get the chars preceding and following the start position
|
||||
try {
|
||||
|
||||
char prevChar= fDocument.getChar(Math.max(fOffset - 1, 0));
|
||||
|
||||
// search for opening peer character next to the activation point
|
||||
for (i= 0; i < fPairs.length; i= i + 2) {
|
||||
if (prevChar == fPairs[i]) {
|
||||
fStartPos= fOffset - 1;
|
||||
pairIndex1= i;
|
||||
}
|
||||
}
|
||||
|
||||
// search for closing peer character next to the activation point
|
||||
for (i= 1; i < fPairs.length; i= i + 2) {
|
||||
if (prevChar == fPairs[i]) {
|
||||
fEndPos= fOffset - 1;
|
||||
pairIndex2= i;
|
||||
}
|
||||
}
|
||||
|
||||
if (fEndPos > -1) {
|
||||
fAnchor= RIGHT;
|
||||
fStartPos= searchForOpeningPeer(fEndPos, fPairs[pairIndex2 - 1], fPairs[pairIndex2], fDocument);
|
||||
if (fStartPos > -1)
|
||||
return true;
|
||||
fEndPos= -1;
|
||||
} else if (fStartPos > -1) {
|
||||
fAnchor= LEFT;
|
||||
fEndPos= searchForClosingPeer(fStartPos, fPairs[pairIndex1], fPairs[pairIndex1 + 1], fDocument);
|
||||
if (fEndPos > -1)
|
||||
return true;
|
||||
fStartPos= -1;
|
||||
}
|
||||
|
||||
} catch (BadLocationException x) {
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
protected int searchForClosingPeer(int offset, char openingPeer, char closingPeer, IDocument document) throws BadLocationException {
|
||||
CHeuristicScanner scanner= new CHeuristicScanner(document, ICPartitions.C_PARTITIONING, TextUtilities.getContentType(document, ICPartitions.C_PARTITIONING, offset, false));
|
||||
return scanner.findClosingPeer(offset + 1, openingPeer, closingPeer);
|
||||
}
|
||||
|
||||
protected int searchForOpeningPeer(int offset, char openingPeer, char closingPeer, IDocument document) throws BadLocationException {
|
||||
CHeuristicScanner scanner= new CHeuristicScanner(document, ICPartitions.C_PARTITIONING, TextUtilities.getContentType(document, ICPartitions.C_PARTITIONING, offset, false));
|
||||
int peer= scanner.findOpeningPeer(offset - 1, openingPeer, closingPeer);
|
||||
if (peer == CHeuristicScanner.NOT_FOUND)
|
||||
return -1;
|
||||
return peer;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.eclipse.jface.dialogs.IDialogSettings;
|
|||
import org.eclipse.jface.preference.IPreferenceStore;
|
||||
import org.eclipse.jface.text.AbstractInformationControlManager;
|
||||
import org.eclipse.jface.text.DefaultInformationControl;
|
||||
import org.eclipse.jface.text.DefaultTextDoubleClickStrategy;
|
||||
import org.eclipse.jface.text.IAutoEditStrategy;
|
||||
import org.eclipse.jface.text.IDocument;
|
||||
import org.eclipse.jface.text.IInformationControl;
|
||||
|
@ -451,6 +452,14 @@ public class CSourceViewerConfiguration extends TextSourceViewerConfiguration {
|
|||
* @see SourceViewerConfiguration#getDoubleClickStrategy(ISourceViewer, String)
|
||||
*/
|
||||
public ITextDoubleClickStrategy getDoubleClickStrategy(ISourceViewer sourceViewer, String contentType) {
|
||||
if (ICPartitions.C_MULTI_LINE_COMMENT.equals(contentType) ||
|
||||
ICPartitions.C_SINGLE_LINE_COMMENT.equals(contentType))
|
||||
return new DefaultTextDoubleClickStrategy();
|
||||
else if (ICPartitions.C_STRING.equals(contentType) ||
|
||||
ICPartitions.C_CHARACTER.equals(contentType))
|
||||
return new CStringDoubleClickSelector(getConfiguredDocumentPartitioning(sourceViewer));
|
||||
else if (ICPartitions.C_PREPROCESSOR.equals(contentType))
|
||||
return new CStringDoubleClickSelector(getConfiguredDocumentPartitioning(sourceViewer), new CDoubleClickSelector());
|
||||
return new CDoubleClickSelector();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007 Wind River Systems, Inc. and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Anton Leherbauer (Wind River Systems) - initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.internal.ui.text;
|
||||
|
||||
import org.eclipse.jface.text.BadLocationException;
|
||||
import org.eclipse.jface.text.Document;
|
||||
import org.eclipse.jface.text.IDocument;
|
||||
import org.eclipse.jface.text.IRegion;
|
||||
import org.eclipse.jface.text.ITextDoubleClickStrategy;
|
||||
import org.eclipse.jface.text.ITextViewer;
|
||||
import org.eclipse.jface.text.ITypedRegion;
|
||||
import org.eclipse.jface.text.Region;
|
||||
import org.eclipse.jface.text.TextUtilities;
|
||||
|
||||
import org.eclipse.cdt.ui.text.ICPartitions;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.editor.CDocumentSetupParticipant;
|
||||
|
||||
/**
|
||||
* Double click strategy aware of string and character syntax rules.
|
||||
*
|
||||
* @since 4.0
|
||||
*/
|
||||
public class CStringDoubleClickSelector extends CDoubleClickSelector {
|
||||
|
||||
private String fPartitioning;
|
||||
private ITextDoubleClickStrategy fFallbackStrategy;
|
||||
|
||||
/**
|
||||
* Creates a new string double click selector for the given document partitioning.
|
||||
*
|
||||
* @param partitioning the document partitioning
|
||||
*/
|
||||
public CStringDoubleClickSelector(String partitioning) {
|
||||
this(partitioning, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new string double click selector for the given document partitioning.
|
||||
*
|
||||
* @param partitioning the document partitioning
|
||||
* @param doubleClickStrategy the fallback double click strategy
|
||||
*/
|
||||
public CStringDoubleClickSelector(String partitioning,
|
||||
ITextDoubleClickStrategy doubleClickStrategy) {
|
||||
fPartitioning= partitioning;
|
||||
fFallbackStrategy= doubleClickStrategy;
|
||||
}
|
||||
|
||||
/*
|
||||
* @see ITextDoubleClickStrategy#doubleClicked(ITextViewer)
|
||||
*/
|
||||
public void doubleClicked(ITextViewer textViewer) {
|
||||
int offset= textViewer.getSelectedRange().x;
|
||||
|
||||
if (offset < 0)
|
||||
return;
|
||||
|
||||
IDocument document= textViewer.getDocument();
|
||||
|
||||
IRegion region= matchString(document, offset);
|
||||
if (region != null) {
|
||||
if (region.getLength() >= 2) {
|
||||
textViewer.setSelectedRange(region.getOffset() + 1, region.getLength() - 2);
|
||||
}
|
||||
} else if (fFallbackStrategy != null) {
|
||||
fFallbackStrategy.doubleClicked(textViewer);
|
||||
} else {
|
||||
region= selectWord(document, offset);
|
||||
if (region != null) {
|
||||
textViewer.setSelectedRange(region.getOffset(), region.getLength());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IRegion matchString(IDocument document, int offset) {
|
||||
try {
|
||||
if ((document.getChar(offset) == '"') || (document.getChar(offset) == '\'') ||
|
||||
(document.getChar(offset - 1) == '"') || (document.getChar(offset - 1) == '\''))
|
||||
{
|
||||
ITypedRegion region= TextUtilities.getPartition(document, fPartitioning, offset, true);
|
||||
// little hack: in case this strategy is used in preprocessor partitions, the string
|
||||
// partition inside the preprocessor partition must be computed in an extra step
|
||||
if (ICPartitions.C_PREPROCESSOR.equals(region.getType())) {
|
||||
String ppDirective= document.get(region.getOffset(), region.getLength());
|
||||
int hashIdx= ppDirective.indexOf('#');
|
||||
document= new Document(ppDirective.substring(hashIdx+1));
|
||||
new CDocumentSetupParticipant().setup(document);
|
||||
int delta= region.getOffset() + hashIdx + 1;
|
||||
region= TextUtilities.getPartition(document, fPartitioning, offset - delta, true);
|
||||
return new Region(region.getOffset() + delta, region.getLength());
|
||||
}
|
||||
return region;
|
||||
}
|
||||
} catch (BadLocationException e) {
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue