Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton Leherbauer2008-02-08 12:30:10 +0000
committerAnton Leherbauer2008-02-08 12:30:10 +0000
commit00091c99cbc7b0bc051c3005da3cbc280878a876 (patch)
tree782eb510e1bcd1c0fb2288153a2f4892838d282d
parent4c7161361eb522edadc9016cec6c589db4c3753e (diff)
downloadorg.eclipse.cdt-00091c99cbc7b0bc051c3005da3cbc280878a876.tar.gz
org.eclipse.cdt-00091c99cbc7b0bc051c3005da3cbc280878a876.tar.xz
org.eclipse.cdt-00091c99cbc7b0bc051c3005da3cbc280878a876.zip
Fix for 216437: [Formatter] Shift left/right incorrect in Mixed tab policy/indentation mode
-rw-r--r--core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/ShiftActionTest.java157
-rw-r--r--core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/TextTestSuite.java1
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/IndentAction.java50
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java39
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CSourceViewer.java139
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/IndentUtil.java45
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CSourceViewerConfiguration.java26
7 files changed, 408 insertions, 49 deletions
diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/ShiftActionTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/ShiftActionTest.java
new file mode 100644
index 00000000000..70e91f7b9d5
--- /dev/null
+++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/ShiftActionTest.java
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.ui.tests.text;
+
+import java.util.ListResourceBundle;
+
+import junit.extensions.TestSetup;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.source.SourceViewer;
+import org.eclipse.ui.texteditor.ShiftAction;
+
+import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.core.testplugin.CProjectHelper;
+import org.eclipse.cdt.ui.tests.BaseUITestCase;
+import org.eclipse.cdt.ui.tests.text.MarkOccurrenceTest.MarkOccurrenceTestSetup;
+
+import org.eclipse.cdt.internal.ui.editor.CEditor;
+
+/**
+ * Test the Shift left/right actions.
+ *
+ * @since 5.0
+ */
+public class ShiftActionTest extends BaseUITestCase {
+ private static final String PROJECT= "ShiftTests";
+ private static final String FILE = "shiftTest.c";
+
+ private static final class EmptyBundle extends ListResourceBundle {
+ protected Object[][] getContents() {
+ return new Object[0][];
+ }
+ }
+
+ protected static class ShiftTestSetup extends TestSetup {
+
+ private ICProject fCProject;
+
+ public ShiftTestSetup(Test test) {
+ super(test);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ fCProject= CProjectHelper.createCProject(PROJECT, null);
+ fCProject.setOption(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, DefaultCodeFormatterConstants.MIXED);
+ fCProject.setOption(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, String.valueOf(8));
+ fCProject.setOption(DefaultCodeFormatterConstants.FORMATTER_INDENTATION_SIZE, String.valueOf(4));
+ IFile file= EditorTestHelper.createFile(fCProject.getProject(), FILE, "", new NullProgressMonitor());
+ }
+
+ protected void tearDown () throws Exception {
+ EditorTestHelper.closeAllEditors();
+ if (fCProject != null) {
+ CProjectHelper.delete(fCProject);
+ }
+ super.tearDown();
+ }
+ }
+
+ private static final Class THIS= ShiftActionTest.class;
+ public static Test suite() {
+ return new ShiftTestSetup(new TestSuite(THIS));
+ }
+
+ private CEditor fEditor;
+ private SourceViewer fSourceViewer;
+ private IDocument fDocument;
+ private MarkOccurrenceTestSetup fProjectSetup;
+
+ /*
+ * @see junit.framework.TestCase#setUp()
+ */
+ protected void setUp() throws Exception {
+ if (!ResourcesPlugin.getWorkspace().getRoot().exists(new Path(PROJECT))) {
+ fProjectSetup= new MarkOccurrenceTestSetup(this);
+ fProjectSetup.setUp();
+ }
+ fEditor= (CEditor) EditorTestHelper.openInEditor(ResourceTestHelper.findFile(PROJECT + '/' + FILE), true);
+ fSourceViewer= EditorTestHelper.getSourceViewer(fEditor);
+ fDocument= fSourceViewer.getDocument();
+ super.setUp();
+ }
+
+ /*
+ * @see junit.framework.TestCase#tearDown()
+ */
+ protected void tearDown() throws Exception {
+ if (fProjectSetup != null) {
+ fProjectSetup.tearDown();
+ }
+ super.tearDown();
+ }
+
+ private void shiftLeft() throws Exception {
+ new ShiftAction(new EmptyBundle(), "prefix", fEditor, SourceViewer.SHIFT_LEFT).run();
+ }
+
+ private void shiftRight() throws Exception {
+ new ShiftAction(new EmptyBundle(), "prefix", fEditor, SourceViewer.SHIFT_RIGHT).run();
+ }
+
+ private void selectAll() {
+ fSourceViewer.setSelectedRange(0, fDocument.getLength());
+ }
+
+ //void f() {
+ // for(;;) {
+ //}
+
+ // void f() {
+ // for(;;) {
+ // }
+ public void testShiftRight() throws Exception {
+ StringBuffer[] contents= getContentsForTest(2);
+ String before= contents[0].toString();
+ String after= contents[1].toString();
+ fDocument.set(before);
+ selectAll();
+ shiftRight();
+ assertEquals(after, fDocument.get());
+ }
+
+ // void f() {
+ // for(;;) {
+ // }
+
+ //void f() {
+ // for(;;) {
+ //}
+ public void testShiftLeft() throws Exception {
+ StringBuffer[] contents= getContentsForTest(2);
+ String before= contents[0].toString();
+ String after= contents[1].toString();
+ fDocument.set(before);
+ selectAll();
+ shiftLeft();
+ assertEquals(after, fDocument.get());
+ }
+
+}
diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/TextTestSuite.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/TextTestSuite.java
index d794ea94819..e19bb822035 100644
--- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/TextTestSuite.java
+++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/TextTestSuite.java
@@ -33,6 +33,7 @@ public class TextTestSuite extends TestSuite {
addTest(BracketInserterTest.suite());
addTest(IndentActionTest.suite());
addTest(FormatActionTest.suite());
+ addTest(ShiftActionTest.suite());
addTest(CodeFormatterTest.suite());
addTest(CIndenterTest.suite());
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/IndentAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/IndentAction.java
index e1d414ba23a..547bb9437ac 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/IndentAction.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/actions/IndentAction.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * Copyright (c) 2000, 2008 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
@@ -269,11 +269,12 @@ public class IndentAction extends TextEditorAction {
String currentIndent= document.get(offset, length);
// if we are right before the text start / line end, and already after the insertion point
- // then just insert a tab.
+ // then just shift to the right
if (fIsTabAction && caret == end && whiteSpaceLength(currentIndent) >= whiteSpaceLength(indent)) {
- String tab= getTabEquivalent();
- document.replace(caret, 0, tab);
- fCaretOffset= caret + tab.length();
+ int indentWidth= whiteSpaceLength(currentIndent) + getIndentSize();
+ String replacement= IndentUtil.changePrefix(currentIndent.trim(), indentWidth, getTabSize(), useSpaces());
+ document.replace(offset, length, replacement);
+ fCaretOffset= offset + replacement.length();
return true;
}
@@ -329,36 +330,17 @@ public class IndentAction extends TextEditorAction {
private int whiteSpaceLength(String indent) {
if (indent == null)
return 0;
- else {
- int size= 0;
- int l= indent.length();
- int tabSize= getTabSize();
-
- for (int i= 0; i < l; i++)
- size += indent.charAt(i) == '\t' ? tabSize : 1;
- return size;
- }
+ return IndentUtil.computeVisualLength(indent, getTabSize());
}
/**
- * Returns a tab equivalent, either as a tab character or as spaces, depending on the editor and
+ * Returns whether spaces should be used exclusively for indentation, depending on the editor and
* formatter preferences.
*
- * @return a string representing one tab in the editor, never <code>null</code>
+ * @return <code>true</code> if only spaces should be used
*/
- private String getTabEquivalent() {
- String tab;
- if (CCorePlugin.SPACE.equals(getCoreFormatterOption(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR))) {
- int size= getTabSize();
- StringBuffer buf= new StringBuffer();
- for (int i= 0; i< size; i++)
- buf.append(' ');
- tab= buf.toString();
- } else {
- tab= "\t"; //$NON-NLS-1$
- }
-
- return tab;
+ private boolean useSpaces() {
+ return CCorePlugin.SPACE.equals(getCoreFormatterOption(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR));
}
/**
@@ -372,6 +354,16 @@ public class IndentAction extends TextEditorAction {
}
/**
+ * Returns the indent size used by the editor, which is deduced from the
+ * formatter preferences.
+ *
+ * @return the indent size as defined in the current formatter preferences
+ */
+ private int getIndentSize() {
+ return getCoreFormatterOption(DefaultCodeFormatterConstants.FORMATTER_INDENTATION_SIZE, 4);
+ }
+
+ /**
* Returns <code>true</code> if empty lines should be indented, <code>false</code> otherwise.
*
* @return <code>true</code> if empty lines should be indented, <code>false</code> otherwise
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java
index 5de7312cb03..133c728683e 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java
@@ -175,6 +175,7 @@ import org.eclipse.cdt.ui.text.ICPartitions;
import org.eclipse.cdt.ui.text.folding.ICFoldingStructureProvider;
import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable;
+import org.eclipse.cdt.internal.corext.util.CodeFormatterUtil;
import org.eclipse.cdt.internal.ui.CPluginImages;
import org.eclipse.cdt.internal.ui.ICHelpContextIds;
@@ -1093,8 +1094,6 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
public static final String INACTIVE_CODE_ENABLE = "inactiveCodeEnable"; //$NON-NLS-1$
/** Preference key for inactive code painter color */
public static final String INACTIVE_CODE_COLOR = "inactiveCodeColor"; //$NON-NLS-1$
- /** Preference key for inserting spaces rather than tabs */
- public final static String SPACES_FOR_TABS = DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR;
/** Preference key for automatically closing strings */
private final static String CLOSE_STRINGS = PreferenceConstants.EDITOR_CLOSE_STRINGS;
/** Preference key for automatically closing brackets and parenthesis */
@@ -1211,6 +1210,13 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
if (fCEditorErrorTickUpdater != null) {
fCEditorErrorTickUpdater.updateEditorImage(getInputCElement());
}
+
+ ICElement element= getInputCElement();
+ if (element instanceof ITranslationUnit) {
+ fBracketMatcher.configure(((ITranslationUnit)element).getLanguage());
+ } else {
+ fBracketMatcher.configure(null);
+ }
}
/**
@@ -1342,14 +1348,6 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
return;
}
- if (SPACES_FOR_TABS.equals(property)) {
- if (isTabsToSpacesConversionEnabled())
- installTabsToSpacesConverter();
- else
- uninstallTabsToSpacesConverter();
- return;
- }
-
if (PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS.equals(property))
updateHoverBehavior();
@@ -1392,7 +1390,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
uninstallTabsToSpacesConverter();
installTabsToSpacesConverter();
} else {
- updateIndentPrefixes();
+ updateIndentationMode();
}
return;
}
@@ -1723,8 +1721,21 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
} else
tabToSpacesConverter.setLineTracker(new DefaultLineTracker());
((ITextViewerExtension7)sourceViewer).setTabsToSpacesConverter(tabToSpacesConverter);
- updateIndentPrefixes();
+ updateIndentationMode();
+ }
+ }
+
+ private void updateIndentationMode() {
+ ISourceViewer sourceViewer= getSourceViewer();
+ if (sourceViewer instanceof CSourceViewer) {
+ CSourceViewer cSourceVieer= (CSourceViewer) sourceViewer;
+ ICElement element= getInputCElement();
+ ICProject project= element == null ? null : element.getCProject();
+ final int indentWidth= CodeFormatterUtil.getIndentWidth(project);
+ final boolean useSpaces= isTabsToSpacesConversionEnabled();
+ cSourceVieer.configureIndentation(indentWidth, useSpaces);
}
+ super.updateIndentPrefixes();
}
/*
@@ -1736,9 +1747,9 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
ICProject project= element == null ? null : element.getCProject();
String option;
if (project == null)
- option= CCorePlugin.getOption(SPACES_FOR_TABS);
+ option= CCorePlugin.getOption(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR);
else
- option= project.getOption(SPACES_FOR_TABS, true);
+ option= project.getOption(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, true);
return CCorePlugin.SPACE.equals(option);
}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CSourceViewer.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CSourceViewer.java
index 2ee2a2b5c44..006f736fc70 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CSourceViewer.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CSourceViewer.java
@@ -18,7 +18,11 @@ import java.util.ArrayList;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceConverter;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DocumentRewriteSession;
+import org.eclipse.jface.text.DocumentRewriteSessionType;
import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentExtension4;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextPresentationListener;
import org.eclipse.jface.text.Region;
@@ -35,6 +39,7 @@ import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
@@ -51,11 +56,11 @@ import org.eclipse.cdt.internal.ui.text.CSourceViewerConfiguration;
public class CSourceViewer extends ProjectionViewer implements IPropertyChangeListener {
/** Show outline operation id. */
- public static final int SHOW_OUTLINE = 101;
+ public static final int SHOW_OUTLINE= 101;
/** Show type hierarchy operation id. */
- public static final int SHOW_HIERARCHY = 102;
+ public static final int SHOW_HIERARCHY= 102;
/** Show macro explorer operation id. */
- public static final int SHOW_MACRO_EXPLORER = 103;
+ public static final int SHOW_MACRO_EXPLORER= 103;
/** Presents outline. */
private IInformationPresenter fOutlinePresenter;
@@ -111,6 +116,15 @@ public class CSourceViewer extends ProjectionViewer implements IPropertyChangeLi
* Workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=195808
*/
private boolean fWasProjectionMode;
+
+ /**
+ * The configured indent width.
+ */
+ private int fIndentWidth= 4;
+ /**
+ * Flag indicating whether to use spaces exclusively for indentation.
+ */
+ private boolean fUseSpaces;
/**
* Creates new source viewer.
@@ -152,6 +166,7 @@ public class CSourceViewer extends ProjectionViewer implements IPropertyChangeLi
}
super.configure(configuration);
+
if (configuration instanceof CSourceViewerConfiguration) {
CSourceViewerConfiguration cConfiguration= (CSourceViewerConfiguration)configuration;
fOutlinePresenter= cConfiguration.getOutlinePresenter(this);
@@ -164,6 +179,12 @@ public class CSourceViewer extends ProjectionViewer implements IPropertyChangeLi
if (fMacroExplorationPresenter != null) {
fMacroExplorationPresenter.install(this);
}
+ String[] defaultIndentPrefixes= (String[])fIndentChars.get(IDocument.DEFAULT_CONTENT_TYPE);
+ if (defaultIndentPrefixes != null && defaultIndentPrefixes.length > 0) {
+ final int indentWidth= cConfiguration.getIndentWidth(this);
+ final boolean useSpaces= cConfiguration.useSpacesOnly(this);
+ configureIndentation(indentWidth, useSpaces);
+ }
}
if (fPreferenceStore != null) {
fPreferenceStore.addPropertyChangeListener(this);
@@ -290,7 +311,7 @@ public class CSourceViewer extends ProjectionViewer implements IPropertyChangeLi
* @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent)
*/
public void propertyChange(PropertyChangeEvent event) {
- String property = event.getProperty();
+ String property= event.getProperty();
if (AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND.equals(property)
|| AbstractTextEditor.PREFERENCE_COLOR_FOREGROUND_SYSTEM_DEFAULT.equals(property)
|| AbstractTextEditor.PREFERENCE_COLOR_BACKGROUND.equals(property)
@@ -468,4 +489,114 @@ public class CSourceViewer extends ProjectionViewer implements IPropertyChangeLi
enableProjection();
}
}
+
+
+ /**
+ * Configure the indentation mode for this viewer.
+ *
+ * @param indentWidth the indentation width
+ * @param useSpaces if <code>true</code>, only spaces are used for indentation
+ */
+ public void configureIndentation(int indentWidth, boolean useSpaces) {
+ fIndentWidth= indentWidth;
+ fUseSpaces= useSpaces;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.TextViewer#shift(boolean, boolean, boolean)
+ */
+ protected void shift(boolean useDefaultPrefixes, boolean right, boolean ignoreWhitespace) {
+ if (!useDefaultPrefixes) {
+ // simple shift case
+ adjustIndent(right, fIndentWidth, fUseSpaces);
+ return;
+ }
+ super.shift(useDefaultPrefixes, right, ignoreWhitespace);
+ }
+
+ /**
+ * Increase/decrease indentation of current selection.
+ *
+ * @param increase if <code>true</code>, indent is increased by one unit
+ * @param shiftWidth width in spaces of one indent unit
+ * @param useSpaces if <code>true</code>, only spaces are used for indentation
+ */
+ protected void adjustIndent(boolean increase, int shiftWidth, boolean useSpaces) {
+ if (fUndoManager != null) {
+ fUndoManager.beginCompoundChange();
+ }
+ IDocument d= getDocument();
+ DocumentRewriteSession rewriteSession= null;
+ try {
+ if (d instanceof IDocumentExtension4) {
+ IDocumentExtension4 extension= (IDocumentExtension4) d;
+ rewriteSession= extension.startRewriteSession(DocumentRewriteSessionType.SEQUENTIAL);
+ }
+
+ Point selection= getSelectedRange();
+
+ // perform the adjustment
+ int tabWidth= getTextWidget().getTabs();
+ int startLine= d.getLineOfOffset(selection.x);
+ int endLine= selection.y == 0 ? startLine : d.getLineOfOffset(selection.x + selection.y - 1);
+ for (int line= startLine; line <= endLine; ++line) {
+ IRegion lineRegion= d.getLineInformation(line);
+ String indent= IndentUtil.getCurrentIndent(d, line, false);
+ int indentWidth= IndentUtil.computeVisualLength(indent, tabWidth);
+ int newIndentWidth= Math.max(0, indentWidth + (increase ? shiftWidth : -shiftWidth));
+ String newIndent= IndentUtil.changePrefix(indent.trim(), newIndentWidth, tabWidth, useSpaces);
+ int commonLen= getCommonPrefixLength(indent, newIndent);
+ if (commonLen < Math.max(indent.length(), newIndent.length())) {
+ if (commonLen > 0) {
+ indent= indent.substring(commonLen);
+ newIndent= newIndent.substring(commonLen);
+ }
+ final int offset= lineRegion.getOffset() + commonLen;
+ if (!increase && newIndent.length() > indent.length() && indent.length() > 0) {
+ d.replace(offset, indent.length(), ""); //$NON-NLS-1$
+ d.replace(offset, 0, newIndent);
+ } else {
+ d.replace(offset, indent.length(), newIndent);
+ }
+ }
+ }
+
+ } catch (BadLocationException x) {
+ // ignored
+ } finally {
+ if (rewriteSession != null) {
+ ((IDocumentExtension4)d).stopRewriteSession(rewriteSession);
+ }
+ if (fUndoManager != null) {
+ fUndoManager.endCompoundChange();
+ }
+ }
+ }
+
+ /**
+ * Compute the length of the common prefix of two strings.
+ *
+ * @param s1
+ * @param s2
+ * @return the length of the common prefix
+ */
+ private static int getCommonPrefixLength(String s1, String s2) {
+ final int l1= s1.length();
+ final int l2= s2.length();
+ int i= 0;
+ while (i < l1 && i < l2 && s1.charAt(i) == s2.charAt(i)) {
+ ++i;
+ }
+ return i;
+ }
+
+ /*
+ * work around for memory leak in TextViewer$WidgetCommand
+ */
+ protected void updateTextListeners(WidgetCommand cmd) {
+ super.updateTextListeners(cmd);
+ cmd.preservedText= null;
+ cmd.event= null;
+ cmd.text= null;
+ }
}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/IndentUtil.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/IndentUtil.java
index d2093314ae4..75f44c92906 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/IndentUtil.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/IndentUtil.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2008 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
@@ -8,6 +8,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
* Sergey Prigogin, Google
+ * Anton Leherbauer (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.ui.editor;
@@ -618,4 +619,46 @@ public final class IndentUtil {
return computed.toString();
}
+ /**
+ * Extends the string with whitespace to match displayed width.
+ * @param prefix add to this string
+ * @param displayedWidth the desired display width
+ * @param tabWidth the configured tab width
+ * @param useSpaces whether to use spaces only
+ */
+ public static String changePrefix(String prefix, int displayedWidth, int tabWidth, boolean useSpaces) {
+ int column = computeVisualLength(prefix, tabWidth);
+ if (column > displayedWidth) {
+ return prefix;
+ }
+ final StringBuffer buffer = new StringBuffer(prefix);
+ appendIndent(buffer, displayedWidth, tabWidth, useSpaces, column);
+ return buffer.toString();
+ }
+
+ /**
+ * Appends whitespace to given buffer such that its visual length equals the given width.
+ * @param buffer the buffer to add whitespace to
+ * @param width the desired visual indent width
+ * @param tabWidth the configured tab width
+ * @param useSpaces whether tabs should be substituted by spaces
+ * @param startColumn the column where to start measurement
+ * @return StringBuffer
+ */
+ private static StringBuffer appendIndent(StringBuffer buffer, int width, int tabWidth, boolean useSpaces, int startColumn) {
+ assert tabWidth > 0;
+ int tabStop = startColumn - startColumn % tabWidth;
+ int tabs = useSpaces ? 0 : (width-tabStop) / tabWidth;
+ for (int i = 0; i < tabs; ++i) {
+ buffer.append('\t');
+ tabStop += tabWidth;
+ startColumn = tabStop;
+ }
+ int spaces = width - startColumn;
+ for (int i = 0; i < spaces; ++i) {
+ buffer.append(' ');
+ }
+ return buffer;
+ }
+
}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CSourceViewerConfiguration.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CSourceViewerConfiguration.java
index fd83c63a055..7f0a8ca7f5f 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CSourceViewerConfiguration.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CSourceViewerConfiguration.java
@@ -531,6 +531,31 @@ public class CSourceViewerConfiguration extends TextSourceViewerConfiguration {
}
/**
+ * Returns the configured indent width for this viewer.
+ * @param sourceViewer
+ * @return the indent width
+ */
+ public int getIndentWidth(ISourceViewer sourceViewer) {
+ return CodeFormatterUtil.getIndentWidth(getProject());
+ }
+
+ /**
+ * Returns whether spaces should be used exclusively for indentation.
+ *
+ * @param sourceViewer
+ * @return <code>true</code> if spaces should be used for indentation
+ */
+ public boolean useSpacesOnly(ISourceViewer sourceViewer) {
+ ICProject project= getProject();
+ String option;
+ if (project == null)
+ option= CCorePlugin.getOption(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR);
+ else
+ option= project.getOption(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, true);
+ return CCorePlugin.SPACE.equals(option);
+ }
+
+ /**
* @see SourceViewerConfiguration#getAnnotationHover(ISourceViewer)
*/
public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
@@ -874,5 +899,4 @@ public class CSourceViewerConfiguration extends TextSourceViewerConfiguration {
return conrolCreator;
}
-
}

Back to the top