1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-07 17:56:01 +02:00

Fix for 180531: [editor] pasted text loses formatting

This commit is contained in:
Anton Leherbauer 2007-04-03 14:07:15 +00:00
parent f69868567c
commit 39d2e909be
5 changed files with 70 additions and 31 deletions

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2006 Wind River Systems, Inc. and others. * Copyright (c) 2006, 2007 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -26,12 +26,13 @@ import org.eclipse.jface.text.IAutoEditStrategy;
import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.TextUtilities; import org.eclipse.jface.text.TextUtilities;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.text.ICPartitions; import org.eclipse.cdt.ui.text.ICPartitions;
import org.eclipse.cdt.internal.formatter.DefaultCodeFormatterOptions;
import org.eclipse.cdt.internal.ui.text.CAutoIndentStrategy; import org.eclipse.cdt.internal.ui.text.CAutoIndentStrategy;
import org.eclipse.cdt.internal.ui.text.CCommentAutoIndentStrategy; import org.eclipse.cdt.internal.ui.text.CCommentAutoIndentStrategy;
import org.eclipse.cdt.internal.ui.text.CTextTools; import org.eclipse.cdt.internal.ui.text.CTextTools;
@ -228,6 +229,8 @@ public class CAutoIndentTest extends TestCase {
} }
} }
private HashMap fOptions;
/** /**
* @param name * @param name
@ -242,21 +245,28 @@ public class CAutoIndentTest extends TestCase {
protected void setUp() throws Exception { protected void setUp() throws Exception {
super.setUp(); super.setUp();
Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); // Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
shell.forceActive(); // shell.forceActive();
shell.forceFocus(); // shell.forceFocus();
fOptions= CCorePlugin.getOptions();
}
/*
* @see junit.framework.TestCase#tearDown()
*/
protected void tearDown() throws Exception {
CCorePlugin.setOptions(fOptions);
super.tearDown();
} }
private AutoEditTester createAutoEditTester() { private AutoEditTester createAutoEditTester() {
CTextTools textTools = CUIPlugin.getDefault().getTextTools(); CTextTools textTools = CUIPlugin.getDefault().getTextTools();
IDocument doc = new Document(); IDocument doc = new Document();
textTools.setupCDocument(doc); textTools.setupCDocument(doc);
AutoEditTester tester = new AutoEditTester(doc, textTools.getDocumentPartitioning()); AutoEditTester tester = new AutoEditTester(doc, ICPartitions.C_PARTITIONING);
tester.setAutoEditStrategy(IDocument.DEFAULT_CONTENT_TYPE, tester.setAutoEditStrategy(IDocument.DEFAULT_CONTENT_TYPE, new CAutoIndentStrategy(ICPartitions.C_PARTITIONING, null));
new CAutoIndentStrategy(textTools.getDocumentPartitioning(), null));
tester.setAutoEditStrategy(ICPartitions.C_MULTI_LINE_COMMENT, new CCommentAutoIndentStrategy()); tester.setAutoEditStrategy(ICPartitions.C_MULTI_LINE_COMMENT, new CCommentAutoIndentStrategy());
tester.setAutoEditStrategy(ICPartitions.C_PREPROCESSOR, tester.setAutoEditStrategy(ICPartitions.C_PREPROCESSOR, new CAutoIndentStrategy(ICPartitions.C_PARTITIONING, null));
new CAutoIndentStrategy(textTools.getDocumentPartitioning(), null));
return tester; return tester;
} }
@ -487,5 +497,22 @@ public class CAutoIndentTest extends TestCase {
tester.type("for (;;) /*class*/ {\n"); //$NON-NLS-1$ tester.type("for (;;) /*class*/ {\n"); //$NON-NLS-1$
assertEquals("for (;;) /*class*/ {\n\t\r\n}", tester.fDoc.get()); //$NON-NLS-1$ assertEquals("for (;;) /*class*/ {\n\t\r\n}", tester.fDoc.get()); //$NON-NLS-1$
} }
public void testSmartPasteWhitesmiths_Bug180531() throws Exception {
DefaultCodeFormatterOptions whitesmiths= DefaultCodeFormatterOptions.getWhitesmithsSettings();
CCorePlugin.setOptions(new HashMap(whitesmiths.getMap()));
AutoEditTester tester = createAutoEditTester(); //$NON-NLS-1$
tester.type("A::~A()\n{");
assertEquals("A::~A()\n {", tester.fDoc.get());
tester.type("\ndelete x;");
assertEquals("A::~A()\n {\n delete x;\n }", tester.fDoc.get());
tester.setCaretOffset(tester.fDoc.getLength());
tester.type('\n');
String copy= tester.fDoc.get();
tester.paste(copy);
assertEquals(copy+copy, tester.fDoc.get());
}
} }

View file

@ -213,11 +213,11 @@ public class CAutoIndentStrategy extends DefaultIndentLineAutoEditStrategy {
scanner = new CHeuristicScanner(d, fPartitioning, ICPartitions.C_PREPROCESSOR); scanner = new CHeuristicScanner(d, fPartitioning, ICPartitions.C_PREPROCESSOR);
} }
// current line // current line
int line = d.getLineOfOffset(p); int line = d.getLineOfOffset(c.offset);
int lineOffset = d.getLineOffset(line); int lineOffset = d.getLineOffset(line);
// make sure we don't have any leading comments etc. // make sure we don't have any leading comments etc.
if (d.get(lineOffset, p - lineOffset).trim().length() != 0) if (d.get(lineOffset, c.offset - lineOffset).trim().length() != 0)
return; return;
// Line of last C code // Line of last C code

View file

@ -60,6 +60,7 @@ public final class CHeuristicScanner implements Symbols {
private static final char RANGLE= '>'; private static final char RANGLE= '>';
private static final char DOT= '.'; private static final char DOT= '.';
private static final char MINUS= '-'; private static final char MINUS= '-';
private static final char TILDE= '~';
/** /**
* Specifies the stop condition, upon which the <code>scanXXX</code> methods will decide whether * Specifies the stop condition, upon which the <code>scanXXX</code> methods will decide whether
@ -407,6 +408,8 @@ public final class CHeuristicScanner implements Symbols {
return TokenDOT; return TokenDOT;
case MINUS: case MINUS:
return TokenMINUS; return TokenMINUS;
case TILDE:
return TokenTILDE;
} }
// else // else
@ -754,8 +757,8 @@ public final class CHeuristicScanner implements Symbols {
/** /**
* Finds the highest position in <code>fDocument</code> such that the position is &lt;= <code>position</code> * Finds the highest position in <code>fDocument</code> such that the position is &lt;= <code>position</code>
* and &gt; <code>bound</code> and <code>fDocument.getChar(position) == ch</code> evaluates to <code>true</code> for at least one * and &gt; <code>bound</code> and <code>fDocument.getChar(position) == ch</code> evaluates to <code>true</code>
* ch in <code>chars</code> and the position is in the default partition. * and the position is in the default partition.
* *
* @param position the first character position in <code>fDocument</code> to be considered * @param position the first character position in <code>fDocument</code> to be considered
* @param bound the first position in <code>fDocument</code> to not consider any more, with <code>bound</code> &lt; <code>position</code>, or <code>UNBOUND</code> * @param bound the first position in <code>fDocument</code> to not consider any more, with <code>bound</code> &lt; <code>position</code>, or <code>UNBOUND</code>

View file

@ -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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -220,7 +220,7 @@ public final class CIndenter {
// ignore and return default // ignore and return default
} }
return true; return false;
} }
private int prefMethodDeclIndent() { private int prefMethodDeclIndent() {
@ -883,8 +883,8 @@ public final class CIndenter {
return matchCaseAlignment(); return matchCaseAlignment();
} }
// the only reliable way to get case labels aligned (due to many different styles of using braces in a block) // the only reliable way to get access specifiers aligned (due to many different styles of using braces in a block)
// is to go for another case statement, or the scope opening brace // is to go for another access specifier, or the scope opening brace
if (matchAccessSpecifier) { if (matchAccessSpecifier) {
return matchAccessSpecifierAlignment(); return matchAccessSpecifierAlignment();
} }
@ -1194,8 +1194,9 @@ public final class CIndenter {
} }
/** /**
* Returns as a reference any previous <code>switch</code> labels (<code>case</code> * Returns as a reference any previous access specifiers (<code>public</code>,
* or <code>default</code>) or the offset of the brace that scopes the class body. * <code>protected</code> or <code>default</code>) or the offset of the brace that
* scopes the class body.
* Sets <code>fIndent</code> to <code>prefAccessSpecifierIndent</code> upon * Sets <code>fIndent</code> to <code>prefAccessSpecifierIndent</code> upon
* a match. * a match.
* *
@ -1205,7 +1206,7 @@ public final class CIndenter {
while (true) { while (true) {
nextToken(); nextToken();
switch (fToken) { switch (fToken) {
// invalid cases: another case label or an LBRACE must come before a case // invalid cases: another access specifier or an LBRACE must come before an access specifier
// -> bail out with the current position // -> bail out with the current position
case Symbols.TokenLPAREN: case Symbols.TokenLPAREN:
case Symbols.TokenLBRACKET: case Symbols.TokenLBRACKET:
@ -1213,14 +1214,14 @@ public final class CIndenter {
return fPosition; return fPosition;
case Symbols.TokenLBRACE: case Symbols.TokenLBRACE:
// opening brace of switch statement // opening brace of class body
fIndent= fPrefs.prefAccessSpecifierIndent; fIndent= fPrefs.prefAccessSpecifierIndent;
return fPosition; return fPosition;
case Symbols.TokenPUBLIC: case Symbols.TokenPUBLIC:
case Symbols.TokenPROTECTED: case Symbols.TokenPROTECTED:
case Symbols.TokenPRIVATE: case Symbols.TokenPRIVATE:
// align with previous label // align with previous access specifier
fIndent= 0; fIndent= 0;
return fPosition; return fPosition;
@ -1634,9 +1635,7 @@ public final class CIndenter {
* Returns <code>true</code> if the current tokens look like a method * Returns <code>true</code> if the current tokens look like a method
* declaration header (i.e. only the return type and method name). The * declaration header (i.e. only the return type and method name). The
* heuristic calls <code>nextToken</code> and expects an identifier * heuristic calls <code>nextToken</code> and expects an identifier
* (method name) and a type declaration (an identifier with optional * (method name) and an optional retrun type declaration.
* brackets) which also covers the visibility modifier of constructors; it
* does not recognize package visible constructors.
* *
* @return <code>true</code> if the current position looks like a method * @return <code>true</code> if the current position looks like a method
* declaration header. * declaration header.
@ -1644,10 +1643,19 @@ public final class CIndenter {
private boolean looksLikeMethodDecl() { private boolean looksLikeMethodDecl() {
nextToken(); nextToken();
if (fToken == Symbols.TokenIDENT) { // method name if (fToken == Symbols.TokenIDENT) { // method name
do nextToken(); nextToken();
while (skipBrackets() || skipQualifiers()); // optional brackets for array valued return types // check destructor tilde
if (fToken == Symbols.TokenTILDE) {
return fToken == Symbols.TokenIDENT; // return type name return true;
}
if (skipQualifiers()) {
return true;
}
// optional brackets for array valued return types
while (skipBrackets()) {
nextToken();
}
return fToken == Symbols.TokenIDENT;
} }
return false; return false;

View file

@ -33,6 +33,7 @@ public interface Symbols {
int TokenGREATERTHAN= 14; int TokenGREATERTHAN= 14;
int TokenDOT= 15; int TokenDOT= 15;
int TokenMINUS= 16; int TokenMINUS= 16;
int TokenTILDE= 17;
int TokenIF= 109; int TokenIF= 109;
int TokenDO= 1010; int TokenDO= 1010;
int TokenFOR= 1011; int TokenFOR= 1011;