mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-24 09:25:31 +02:00
Bug 241355 - Added format source code save action
Change-Id: I987dda03aae1fd6c8077e2d6cd930164acfaa783 Signed-off-by: Oliver Vinn <oliver@vinn.co.uk> Signed-off-by: Marco Stornelli <marco.stornelli@gmail.com> Reviewed-on: https://git.eclipse.org/r/21420 Reviewed-by: Elena Laskavaia <elaskavaia.cdt@gmail.com> Tested-by: Elena Laskavaia <elaskavaia.cdt@gmail.com>
This commit is contained in:
parent
67f46bce5b
commit
54607bd07f
7 changed files with 85 additions and 9 deletions
|
@ -2,7 +2,7 @@ Manifest-Version: 1.0
|
|||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: %pluginName
|
||||
Bundle-SymbolicName: org.eclipse.cdt.ui; singleton:=true
|
||||
Bundle-Version: 5.9.0.qualifier
|
||||
Bundle-Version: 5.10.0.qualifier
|
||||
Bundle-Activator: org.eclipse.cdt.ui.CUIPlugin
|
||||
Bundle-Vendor: %providerName
|
||||
Bundle-Localization: plugin
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<version>5.9.0-SNAPSHOT</version>
|
||||
<version>5.10.0-SNAPSHOT</version>
|
||||
<artifactId>org.eclipse.cdt.ui</artifactId>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
</project>
|
||||
|
|
|
@ -14,8 +14,10 @@ package org.eclipse.cdt.internal.ui.editor;
|
|||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.core.filebuffers.ITextFileBuffer;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
|
@ -34,14 +36,22 @@ import org.eclipse.core.runtime.jobs.ISchedulingRule;
|
|||
import org.eclipse.jface.preference.IPreferenceStore;
|
||||
import org.eclipse.jface.text.BadLocationException;
|
||||
import org.eclipse.jface.text.DefaultLineTracker;
|
||||
import org.eclipse.jface.text.DocumentRewriteSession;
|
||||
import org.eclipse.jface.text.DocumentRewriteSessionType;
|
||||
import org.eclipse.jface.text.IDocument;
|
||||
import org.eclipse.jface.text.IDocumentExtension;
|
||||
import org.eclipse.jface.text.IDocumentExtension3;
|
||||
import org.eclipse.jface.text.IDocumentExtension4;
|
||||
import org.eclipse.jface.text.ILineTracker;
|
||||
import org.eclipse.jface.text.IRegion;
|
||||
import org.eclipse.jface.text.ITypedRegion;
|
||||
import org.eclipse.jface.text.Position;
|
||||
import org.eclipse.jface.text.Region;
|
||||
import org.eclipse.jface.text.TextUtilities;
|
||||
import org.eclipse.jface.text.formatter.FormattingContext;
|
||||
import org.eclipse.jface.text.formatter.FormattingContextProperties;
|
||||
import org.eclipse.jface.text.formatter.IFormattingContext;
|
||||
import org.eclipse.jface.text.formatter.MultiPassContentFormatter;
|
||||
import org.eclipse.jface.text.source.Annotation;
|
||||
import org.eclipse.jface.text.source.AnnotationModelEvent;
|
||||
import org.eclipse.jface.text.source.IAnnotationModel;
|
||||
|
@ -69,6 +79,7 @@ import org.eclipse.ui.texteditor.MarkerUtilities;
|
|||
import org.eclipse.ui.texteditor.ResourceMarkerAnnotationModel;
|
||||
import org.eclipse.ui.texteditor.spelling.SpellingAnnotation;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.model.CoreModel;
|
||||
import org.eclipse.cdt.core.model.ICModelMarker;
|
||||
|
@ -85,6 +96,7 @@ import org.eclipse.cdt.ui.text.ICPartitions;
|
|||
|
||||
import org.eclipse.cdt.internal.core.model.TranslationUnit;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.text.CFormattingStrategy;
|
||||
import org.eclipse.cdt.internal.ui.text.IProblemRequestorExtension;
|
||||
import org.eclipse.cdt.internal.ui.text.spelling.CoreSpellingProblem;
|
||||
import org.eclipse.cdt.internal.ui.util.EditorUtility;
|
||||
|
@ -891,22 +903,27 @@ public class CDocumentProvider extends TextFileDocumentProvider {
|
|||
|
||||
if (resource instanceof IFile && !resource.exists()) {
|
||||
// The underlying resource has been deleted, just recreate the file, ignore the rest
|
||||
createFileFromDocument(monitor, (IFile) resource, document);
|
||||
createFileFromDocument(getSubProgressMonitor(monitor, 20), (IFile) resource, document);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
CoreException saveActionException= null;
|
||||
ICProject cproject = null;
|
||||
try {
|
||||
performSaveActions(info.fTextFileBuffer, getSubProgressMonitor(monitor, 20));
|
||||
// Project needed to obtain formatting preferences.
|
||||
if (resource != null) {
|
||||
cproject = CoreModel.getDefault().create(resource.getProject());
|
||||
}
|
||||
performSaveActions(cproject, info.fTextFileBuffer, getSubProgressMonitor(monitor, 20));
|
||||
} catch (CoreException e) {
|
||||
saveActionException = e;
|
||||
}
|
||||
|
||||
commitFileBuffer(monitor, info, overwrite);
|
||||
commitFileBuffer(getSubProgressMonitor(monitor, 20), info, overwrite);
|
||||
|
||||
if (saveActionException != null) {
|
||||
throw saveActionException;
|
||||
CUIPlugin.log(saveActionException);
|
||||
}
|
||||
} catch (CoreException x) {
|
||||
// Inform about the failure
|
||||
|
@ -946,17 +963,56 @@ public class CDocumentProvider extends TextFileDocumentProvider {
|
|||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private void formatCode(ICProject project, IDocument document) {
|
||||
DocumentRewriteSession fRewriteSession = null;
|
||||
|
||||
if (shouldStyleFormatCode() && project != null) {
|
||||
final IFormattingContext context = new FormattingContext();
|
||||
try {
|
||||
context.setProperty(FormattingContextProperties.CONTEXT_PREFERENCES, project.getOptions(true));
|
||||
context.setProperty(FormattingContextProperties.CONTEXT_DOCUMENT, Boolean.valueOf(true));
|
||||
|
||||
final MultiPassContentFormatter formatter= new MultiPassContentFormatter(ICPartitions.C_PARTITIONING, IDocument.DEFAULT_CONTENT_TYPE);
|
||||
formatter.setMasterStrategy(new CFormattingStrategy());
|
||||
|
||||
try {
|
||||
// Begin a single editing event
|
||||
if (document instanceof IDocumentExtension4) {
|
||||
IDocumentExtension4 extension= (IDocumentExtension4) document;
|
||||
fRewriteSession= extension.startRewriteSession(DocumentRewriteSessionType.SEQUENTIAL);
|
||||
} else if (document instanceof IDocumentExtension) {
|
||||
IDocumentExtension extension= (IDocumentExtension) document;
|
||||
extension.startSequentialRewrite(false);
|
||||
}
|
||||
formatter.format(document, context);
|
||||
} finally {
|
||||
if (fRewriteSession != null) {
|
||||
IDocumentExtension4 extension= (IDocumentExtension4) document;
|
||||
extension.stopRewriteSession(fRewriteSession);
|
||||
} else {
|
||||
IDocumentExtension extension= (IDocumentExtension)document;
|
||||
extension.stopSequentialRewrite();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
context.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes trailing whitespaces from changed lines and adds newline at the end of the file,
|
||||
* if the last line of the file was changed.
|
||||
* @throws BadLocationException
|
||||
*/
|
||||
private void performSaveActions(ITextFileBuffer buffer, IProgressMonitor monitor) throws CoreException {
|
||||
if (shouldRemoveTrailingWhitespace() || shouldAddNewlineAtEof()) {
|
||||
private void performSaveActions(ICProject project, ITextFileBuffer buffer, IProgressMonitor monitor) throws CoreException {
|
||||
if (shouldRemoveTrailingWhitespace() || shouldAddNewlineAtEof() || shouldStyleFormatCode()) {
|
||||
IRegion[] changedRegions= needsChangedRegions() ?
|
||||
EditorUtility.calculateChangedLineRegions(buffer, getSubProgressMonitor(monitor, 20)) :
|
||||
null;
|
||||
IDocument document = buffer.getDocument();
|
||||
formatCode(project, document);
|
||||
TextEdit edit = createSaveActionEdit(document, changedRegions);
|
||||
if (edit != null) {
|
||||
try {
|
||||
|
@ -979,6 +1035,11 @@ public class CDocumentProvider extends TextFileDocumentProvider {
|
|||
}
|
||||
}
|
||||
|
||||
private static boolean shouldStyleFormatCode() {
|
||||
return PreferenceConstants.getPreferenceStore().getBoolean(
|
||||
PreferenceConstants.FORMAT_SOURCE_CODE);
|
||||
}
|
||||
|
||||
private static boolean shouldAddNewlineAtEof() {
|
||||
return PreferenceConstants.getPreferenceStore().getBoolean(
|
||||
PreferenceConstants.ENSURE_NEWLINE_AT_EOF);
|
||||
|
|
|
@ -185,6 +185,7 @@ public final class PreferencesMessages extends NLS {
|
|||
public static String SaveActionsPreferencePage_inEditedLines;
|
||||
public static String SaveActionsPreferencePage_inAllLines;
|
||||
public static String SaveActionsPreferencePage_ensureNewline;
|
||||
public static String SaveActionsPreferencePage_formatSourceCode;
|
||||
|
||||
public static String SmartTypingConfigurationBlock_autoclose_title;
|
||||
public static String SmartTypingConfigurationBlock_autoindent_newlines;
|
||||
|
|
|
@ -116,6 +116,7 @@ SaveActionsPreferencePage_removeTrailingWhitespace=Remove trailing &whitespace
|
|||
SaveActionsPreferencePage_inEditedLines=In &edited lines
|
||||
SaveActionsPreferencePage_inAllLines=In a&ll lines
|
||||
SaveActionsPreferencePage_ensureNewline=Ensure &newline at the end of file
|
||||
SaveActionsPreferencePage_formatSourceCode=&Format source code
|
||||
|
||||
TemplatePreferencePage_Viewer_preview=Preview:
|
||||
|
||||
|
|
|
@ -46,6 +46,8 @@ public class SaveActionsPreferencePage extends AbstractPreferencePage {
|
|||
PreferenceConstants.REMOVE_TRAILING_WHITESPACE_LIMIT_TO_EDITED_LINES));
|
||||
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN,
|
||||
PreferenceConstants.ENSURE_NEWLINE_AT_EOF));
|
||||
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN,
|
||||
PreferenceConstants.FORMAT_SOURCE_CODE));
|
||||
|
||||
OverlayPreferenceStore.OverlayKey[] keys = new OverlayPreferenceStore.OverlayKey[overlayKeys.size()];
|
||||
overlayKeys.toArray(keys);
|
||||
|
@ -93,7 +95,10 @@ public class SaveActionsPreferencePage extends AbstractPreferencePage {
|
|||
|
||||
label = PreferencesMessages.SaveActionsPreferencePage_ensureNewline;
|
||||
addCheckBox(composite, label, PreferenceConstants.ENSURE_NEWLINE_AT_EOF, 0);
|
||||
|
||||
|
||||
label = PreferencesMessages.SaveActionsPreferencePage_formatSourceCode;
|
||||
addCheckBox(composite, label, PreferenceConstants.FORMAT_SOURCE_CODE, 0);
|
||||
|
||||
return composite;
|
||||
}
|
||||
|
||||
|
|
|
@ -989,6 +989,13 @@ public class PreferenceConstants {
|
|||
*/
|
||||
public final static String REMOVE_TRAILING_WHITESPACE_LIMIT_TO_EDITED_LINES = "removeTrailingWhitespaceEditedLines"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Style format code on save
|
||||
*
|
||||
* @since 5.10
|
||||
*/
|
||||
public final static String FORMAT_SOURCE_CODE = "formatSourceCode"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* A named preference that defines whether the hint to make hover sticky should be shown.
|
||||
*
|
||||
|
@ -2190,6 +2197,7 @@ public class PreferenceConstants {
|
|||
store.setDefault(REMOVE_TRAILING_WHITESPACE, true);
|
||||
store.setDefault(REMOVE_TRAILING_WHITESPACE_LIMIT_TO_EDITED_LINES, true);
|
||||
store.setDefault(ENSURE_NEWLINE_AT_EOF, true);
|
||||
store.setDefault(PreferenceConstants.FORMAT_SOURCE_CODE, false);
|
||||
|
||||
// Formatter profile
|
||||
store.setDefault(FORMATTER_PROFILE, FormatterProfileManager.DEFAULT_PROFILE);
|
||||
|
|
Loading…
Add table
Reference in a new issue