1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

2004-09-07 Alain Magloire

Part of the uncoming work to supply formatting in CDT
	* src/org/eclipse/cdt/internal/corext/CodeFormatterUtil.java
	* src/org/eclipse/cdt/internal/ui/editor/CEditor.java
	* src/org/eclipse/cdt/internal/ui/text/CFormatingStrategy.java
	* src/org/eclipse/cdt/internal/ui/text/CSourceViewerConfiguration.java
	* plugin.properties
	* plugin.xml
This commit is contained in:
Alain Magloire 2004-09-07 20:25:17 +00:00
parent 08d72e6639
commit e452d260ff
8 changed files with 314 additions and 84 deletions

View file

@ -1,3 +1,13 @@
2004-09-07 Alain Magloire
Part of the uncoming work to supply formatting in CDT
* src/org/eclipse/cdt/internal/corext/CodeFormatterUtil.java
* src/org/eclipse/cdt/internal/ui/editor/CEditor.java
* src/org/eclipse/cdt/internal/ui/text/CFormatingStrategy.java
* src/org/eclipse/cdt/internal/ui/text/CSourceViewerConfiguration.java
* plugin.properties
* plugin.xml
2004-09-07 Chris Wiebe
comment out old class wizard

View file

@ -84,6 +84,9 @@ ActionDefinition.finddecl.description= Find Declaration
ActionDefinition.findrefs.name= Find References
ActionDefinition.findrefs.description= Find References
ActionDefinition.format.name=Format
ActionDefinition.format.description=Format Source Code
CEditor.name=C/C++ Editor
CPluginPreferencePage.name=C/C++
CPluginEditorPreferencePage.name=Editor

View file

@ -614,6 +614,18 @@
description="%category.source.description"
id="org.eclipse.cdt.ui.category.source">
</category>
<command
name="%ActionDefinition.format.name"
description="%ActionDefinition.format.description"
category="org.eclipse.cdt.ui.category.source"
id="org.eclipse.cdt.ui.edit.text.c.format">
</command>
<keyBinding
string="Ctrl+Shift+F"
scope="org.eclipse.cdt.ui.cEditorScope"
command="org.eclipse.cdt.ui.edit.text.c.format"
configuration="org.eclipse.ui.defaultAcceleratorConfiguration">
</keyBinding>
<command
name="%ActionDefinition.comment.name"
category="org.eclipse.cdt.ui.category.source"

View file

@ -0,0 +1,134 @@
/*******************************************************************************
* Copyright (c) 2000, 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.corext.util;
import java.util.Map;
import org.eclipse.cdt.core.ToolFactory;
import org.eclipse.cdt.core.formatter.CodeFormatter;
import org.eclipse.cdt.internal.corext.Assert;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.BadPositionCategoryException;
import org.eclipse.jface.text.DefaultPositionUpdater;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.Position;
import org.eclipse.text.edits.DeleteEdit;
import org.eclipse.text.edits.InsertEdit;
import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.ReplaceEdit;
import org.eclipse.text.edits.TextEdit;
public class CodeFormatterUtil {
/**
* Evaluates the edit on the given string.
* @throws IllegalArgumentException If the positions are not inside the string, a
* IllegalArgumentException is thrown.
*/
public static String evaluateFormatterEdit(String string, TextEdit edit, Position[] positions) {
try {
Document doc= createDocument(string, positions);
edit.apply(doc, 0);
if (positions != null) {
for (int i= 0; i < positions.length; i++) {
Assert.isTrue(!positions[i].isDeleted, "Position got deleted"); //$NON-NLS-1$
}
}
return doc.get();
} catch (BadLocationException e) {
CUIPlugin.getDefault().log(e); // bug in the formatter
Assert.isTrue(false, "Fromatter created edits with wrong positions: " + e.getMessage()); //$NON-NLS-1$
}
return null;
}
/**
* Creates edits that describe how to format the given string. Returns <code>null</code> if the code could not be formatted for the given kind.
* @throws IllegalArgumentException If the offset and length are not inside the string, a
* IllegalArgumentException is thrown.
*/
public static TextEdit format(int kind, IDocument document, int offset, int length, int indentationLevel, String lineSeparator, Map options) {
if (offset < 0 || length < 0 || offset + length > document.getLength()) {
throw new IllegalArgumentException("offset or length outside of string. offset: " + offset + ", length: " + length + ", string size: " + document.getLength()); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
}
CodeFormatter formatter = ToolFactory.createCodeFormatter(options);
if (formatter != null) {
return formatter.format(kind, document, offset, length, indentationLevel, lineSeparator);
}
return null;
}
public static TextEdit format(int kind, IDocument document, int indentationLevel, String lineSeparator, Map options) {
return format(kind, document, 0, document.getLength(), indentationLevel, lineSeparator, options);
}
private static TextEdit shifEdit(TextEdit oldEdit, int diff) {
TextEdit newEdit;
if (oldEdit instanceof ReplaceEdit) {
ReplaceEdit edit= (ReplaceEdit) oldEdit;
newEdit= new ReplaceEdit(edit.getOffset() - diff, edit.getLength(), edit.getText());
} else if (oldEdit instanceof InsertEdit) {
InsertEdit edit= (InsertEdit) oldEdit;
newEdit= new InsertEdit(edit.getOffset() - diff, edit.getText());
} else if (oldEdit instanceof DeleteEdit) {
DeleteEdit edit= (DeleteEdit) oldEdit;
newEdit= new DeleteEdit(edit.getOffset() - diff, edit.getLength());
} else if (oldEdit instanceof MultiTextEdit) {
newEdit= new MultiTextEdit();
} else {
return null; // not supported
}
TextEdit[] children= oldEdit.getChildren();
for (int i= 0; i < children.length; i++) {
TextEdit shifted= shifEdit(children[i], diff);
if (shifted != null) {
newEdit.addChild(shifted);
}
}
return newEdit;
}
private static Document createDocument(String string, Position[] positions) throws IllegalArgumentException {
Document doc= new Document(string);
try {
if (positions != null) {
final String POS_CATEGORY= "myCategory"; //$NON-NLS-1$
doc.addPositionCategory(POS_CATEGORY);
doc.addPositionUpdater(new DefaultPositionUpdater(POS_CATEGORY) {
protected boolean notDeleted() {
if (fOffset < fPosition.offset && (fPosition.offset + fPosition.length < fOffset + fLength)) {
fPosition.offset= fOffset + fLength; // deleted positions: set to end of remove
return false;
}
return true;
}
});
for (int i= 0; i < positions.length; i++) {
try {
doc.addPosition(POS_CATEGORY, positions[i]);
} catch (BadLocationException e) {
throw new IllegalArgumentException("Position outside of string. offset: " + positions[i].offset + ", length: " + positions[i].length + ", string size: " + string.length()); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
}
}
}
} catch (BadPositionCategoryException cannotHappen) {
// can not happen: category is correctly set up
}
return doc;
}
}

View file

@ -668,6 +668,7 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS
addAction(menu, IContextMenuConstants.GROUP_GENERATE, "ContentAssistProposal"); //$NON-NLS-1$
addAction(menu, IContextMenuConstants.GROUP_GENERATE, "AddIncludeOnSelection"); //$NON-NLS-1$
addAction(menu, IContextMenuConstants.GROUP_GENERATE, "Format"); //$NON-NLS-1$
addAction(menu, IContextMenuConstants.GROUP_GENERATE, "ShowInCView"); //$NON-NLS-1$

View file

@ -81,6 +81,7 @@ public class CEditorActionContributor extends TextEditorActionContributor {
protected CEditor fCEditor;
protected RetargetTextEditorAction fContentAssist;
protected RetargetTextEditorAction fFormatter;
protected RetargetTextEditorAction fAddInclude;
protected RetargetTextEditorAction fOpenOnSelection;
protected SelectionAction fShiftLeft;
@ -107,6 +108,9 @@ public class CEditorActionContributor extends TextEditorActionContributor {
fContentAssist = new RetargetTextEditorAction(bundle, "ContentAssistProposal."); //$NON-NLS-1$
fContentAssist.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
fFormatter = new RetargetTextEditorAction(bundle, "Format."); //$NON-NLS-1$
fFormatter.setActionDefinitionId(ICEditorActionDefinitionIds.FORMAT);
fAddInclude = new RetargetTextEditorAction(bundle, "AddIncludeOnSelection."); //$NON-NLS-1$
fAddInclude.setActionDefinitionId(ICEditorActionDefinitionIds.ADD_INCLUDE);
@ -152,6 +156,7 @@ public class CEditorActionContributor extends TextEditorActionContributor {
editMenu.add(new Separator(IContextMenuConstants.GROUP_GENERATE));
editMenu.appendToGroup(IContextMenuConstants.GROUP_GENERATE, fContentAssist);
editMenu.appendToGroup(IContextMenuConstants.GROUP_GENERATE, fAddInclude);
editMenu.appendToGroup(IContextMenuConstants.GROUP_GENERATE, fFormatter);
editMenu.appendToGroup(IContextMenuConstants.GROUP_GENERATE, fOpenOnSelection);
}
}
@ -198,6 +203,7 @@ public class CEditorActionContributor extends TextEditorActionContributor {
fContentAssist.setAction(getAction(textEditor, "ContentAssistProposal")); //$NON-NLS-1$
fAddInclude.setAction(getAction(textEditor, "AddIncludeOnSelection")); //$NON-NLS-1$
fOpenOnSelection.setAction(getAction(textEditor, "OpenOnSelection")); //$NON-NLS-1$
fFormatter.setAction(getAction(textEditor, "Format")); //$NON-NLS-1$
}
/*

View file

@ -1,89 +1,162 @@
/*******************************************************************************
* Copyright (c) 2000, 2004 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
/*
* Created on Aug 16, 2004
*
* Contributors:
* QNX Software Systems - Initial API and implementation
*******************************************************************************/
* Copyright 2004, QNX Software Systems Ltd. All Rights Reserved.
*
* This source code may contain confidential information of QNX Software
* Systems Ltd. (QSSL) and its licensors. Any use, reproduction,
* modification, disclosure, distribution or transfer of this software,
* or any software which includes or is based upon any of this code, is
* prohibited unless expressly authorized by QSSL by written agreement. For
* more information (including whether this source code file has been
* published) please email licensing@qnx.com.
*/
package org.eclipse.cdt.internal.ui.text;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.filetype.ICFileType;
import org.eclipse.cdt.core.filetype.ICFileTypeConstants;
import org.eclipse.cdt.core.formatter.CodeFormatter;
import org.eclipse.cdt.core.formatter.CodeFormatterConstants;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.internal.corext.util.CodeFormatterUtil;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.jface.text.Assert;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.formatter.IFormattingStrategy;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jface.text.TypedPosition;
import org.eclipse.jface.text.formatter.ContextBasedFormattingStrategy;
import org.eclipse.jface.text.formatter.FormattingContextProperties;
import org.eclipse.jface.text.formatter.IFormattingContext;
import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
/**
* @author AChapiro
*/
public class CFormattingStrategy extends ContextBasedFormattingStrategy {
import org.eclipse.cdt.internal.formatter.CCodeFormatter;
/** Documents to be formatted by this strategy */
private final LinkedList fDocuments= new LinkedList();
/** Partitions to be formatted by this strategy */
private final LinkedList fPartitions= new LinkedList();
public class CFormattingStrategy implements IFormattingStrategy {
private String fInitialIndentation;
private ISourceViewer fViewer;
public CFormattingStrategy(ISourceViewer viewer) {
fViewer = viewer;
}
/**
* @see IFormattingStrategy#format(String, boolean, String, int[])
* Creates a new java formatting strategy.
*/
public CFormattingStrategy() {
super();
}
/*
* @see org.eclipse.jface.text.formatter.ContextBasedFormattingStrategy#format()
*/
public String format(String content, boolean isLineStart, String indentation, int[] positions) {
//ConfigurableOption[] options= CUIPlugin.getDefault().getCodeFormatterOptions();
CCodeFormatter formatter= new CCodeFormatter(/* null options */);
public void format() {
super.format();
//IDocument doc= fViewer.getDocument();
//String lineDelimiter= getLineDelimiterFor(doc);
//formatter.options.setLineSeparator(lineDelimiter);
final IDocument document= (IDocument)fDocuments.removeFirst();
final TypedPosition partition= (TypedPosition)fPartitions.removeFirst();
if (document != null && partition != null) {
Map options = getPreferences();
try {
//formatter.setPositionsToMap(positions);
return formatter.formatSourceString(content);
}
/**
* @see IFormattingStrategy#formatterStarts(String)
final TextEdit edit= CodeFormatterUtil.format(CodeFormatter.K_COMPILATION_UNIT,
document,
partition.getOffset(),
partition.getLength(),
0,
TextUtilities.getDefaultLineDelimiter(document),
getPreferences());
if (edit != null)
edit.apply(document);
} catch (MalformedTreeException exception) {
CUIPlugin.getDefault().log(exception);
} catch (BadLocationException exception) {
// Can only happen on concurrent document modification - log and bail out
CUIPlugin.getDefault().log(exception);
}
}
}
/*
* @see org.eclipse.jface.text.formatter.ContextBasedFormattingStrategy#formatterStarts(org.eclipse.jface.text.formatter.IFormattingContext)
*/
public void formatterStarts(String initialIndentation) {
fInitialIndentation= initialIndentation;
public void formatterStarts(final IFormattingContext context) {
prepareFormattingContext(context);
super.formatterStarts(context);
fPartitions.addLast(context.getProperty(FormattingContextProperties.CONTEXT_PARTITION));
fDocuments.addLast(context.getProperty(FormattingContextProperties.CONTEXT_MEDIUM));
}
/**
* @see IFormattingStrategy#formatterStops()
/*
* @see org.eclipse.jface.text.formatter.ContextBasedFormattingStrategy#formatterStops()
*/
public void formatterStops() {
super.formatterStops();
fPartitions.clear();
fDocuments.clear();
}
/**
* Embodies the policy which line delimiter to use when inserting into
* a document
*/
private static String getLineDelimiterFor(IDocument doc) {
String lineDelim= null;
try {
lineDelim= doc.getLineDelimiter(0);
} catch (BadLocationException e) {
}
if (lineDelim == null) {
String systemDelimiter= System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
String[] lineDelims= doc.getLegalLineDelimiters();
for (int i= 0; i < lineDelims.length; i++) {
if (lineDelims[i].equals(systemDelimiter)) {
lineDelim= systemDelimiter;
break;
}
private IFile getActiveFile() {
IFile file = null;
IEditorPart editor =
CUIPlugin.getDefault().getWorkbench().
getActiveWorkbenchWindow().
getActivePage().getActiveEditor();
IEditorInput input = editor.getEditorInput();
if(input instanceof IFileEditorInput) {
file = ((IFileEditorInput)input).getFile();
}
if (lineDelim == null) {
lineDelim= lineDelims.length > 0 ? lineDelims[0] : systemDelimiter;
}
}
return lineDelim;
return file;
}
private void prepareFormattingContext(final IFormattingContext context) {
Map preferences;
ParserLanguage language = ParserLanguage.CPP;
IFile activeFile = getActiveFile();
if(null != activeFile) {
IProject currentProject = activeFile.getProject();
Assert.isNotNull(currentProject);
// pick the language
if (CoreModel.hasCCNature(currentProject)) {
language = ParserLanguage.CPP;
} else {
// for C project try to guess.
ICFileType type = CCorePlugin.getDefault().getFileType(currentProject,
activeFile.getFullPath().lastSegment());
String lid = type.getLanguage().getId();
if(lid != null && lid.equals(ICFileTypeConstants.LANG_C))
language = ParserLanguage.C;
}
preferences= new HashMap(CoreModel.getDefault().create(
activeFile.getProject()).getOptions(true));
} else
preferences= new HashMap(CCorePlugin.getOptions());
preferences.put(CodeFormatterConstants.FORMATTER_LANGUAGE, language);
preferences.put(CodeFormatterConstants.FORMATTER_CURRENT_FILE, activeFile);
context.storeToMap(CUIPlugin.getDefault().getPreferenceStore(), preferences, false);
context.setProperty(FormattingContextProperties.CONTEXT_PREFERENCES, preferences);
return;
}
}

View file

@ -24,16 +24,14 @@ import org.eclipse.jface.text.ITextViewerExtension2;
import org.eclipse.jface.text.contentassist.ContentAssistant;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.contentassist.IContentAssistant;
import org.eclipse.jface.text.formatter.ContentFormatter;
import org.eclipse.jface.text.formatter.IContentFormatter;
import org.eclipse.jface.text.formatter.IFormattingStrategy;
import org.eclipse.jface.text.formatter.MultiPassContentFormatter;
import org.eclipse.jface.text.information.IInformationPresenter;
import org.eclipse.jface.text.presentation.IPresentationReconciler;
import org.eclipse.jface.text.presentation.PresentationReconciler;
import org.eclipse.jface.text.reconciler.IReconciler;
import org.eclipse.jface.text.reconciler.Reconciler;
import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
import org.eclipse.jface.text.rules.DefaultPartitioner;
import org.eclipse.jface.text.rules.RuleBasedScanner;
import org.eclipse.jface.text.source.IAnnotationHover;
import org.eclipse.jface.text.source.ISourceViewer;
@ -51,10 +49,6 @@ public class CSourceViewerConfiguration extends SourceViewerConfiguration {
/** Key used to look up display tab width */
public final static String PREFERENCE_TAB_WIDTH= "org.eclipse.cdt.editor.tab.width"; //$NON-NLS-1$
/** Key used to look up code formatter tab size */
private final static String CODE_FORMATTER_TAB_SIZE= "org.eclipse.cdt.formatter.tabulation.size"; //$NON-NLS-1$
/** Key used to look up code formatter tab character */
private final static String CODE_FORMATTER_TAB_CHAR= "org.eclipse.cdt.formatter.tabulation.char"; //$NON-NLS-1$
private CTextTools fTextTools;
private CEditor fEditor;
@ -364,18 +358,15 @@ public class CSourceViewerConfiguration extends SourceViewerConfiguration {
* @see SourceViewerConfiguration#getContentFormatter(ISourceViewer)
*/
public IContentFormatter getContentFormatter(ISourceViewer sourceViewer) {
String[] types= new String[] {
DefaultPartitioner.CONTENT_TYPES_CATEGORY
};
ContentFormatter formatter= new ContentFormatter();
IFormattingStrategy strategy= new CFormattingStrategy(sourceViewer);
formatter.setFormattingStrategy(strategy, IDocument.DEFAULT_CONTENT_TYPE);
formatter.enablePartitionAwareFormatting(false);
formatter.setPartitionManagingPositionCategories(types);
final MultiPassContentFormatter formatter =
new MultiPassContentFormatter(getConfiguredDocumentPartitioning(sourceViewer),
IDocument.DEFAULT_CONTENT_TYPE);
formatter.setMasterStrategy(new CFormattingStrategy());
return formatter;
}
protected IPreferenceStore getPreferenceStore() {