mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-14 20:45:22 +02:00
Sort Lines command.
This commit is contained in:
parent
0ae94097b3
commit
d6c48415c3
13 changed files with 614 additions and 15 deletions
|
@ -0,0 +1,190 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010 Google, 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:
|
||||
* Sergey Prigogin (Google) - 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.BadLocationException;
|
||||
import org.eclipse.jface.text.IDocument;
|
||||
import org.eclipse.jface.text.source.SourceViewer;
|
||||
|
||||
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.testplugin.EditorTestHelper;
|
||||
import org.eclipse.cdt.ui.testplugin.ResourceTestHelper;
|
||||
import org.eclipse.cdt.ui.tests.BaseUITestCase;
|
||||
import org.eclipse.cdt.internal.ui.editor.CEditor;
|
||||
import org.eclipse.cdt.internal.ui.editor.SortLinesAction;
|
||||
|
||||
/**
|
||||
* Tests for the SortLinesAction.
|
||||
*
|
||||
* @since 5.2
|
||||
*/
|
||||
public class SortLinesTest extends BaseUITestCase {
|
||||
private static final String PROJECT = "SortLinesTest";
|
||||
private static final String FILE = "test.cpp";
|
||||
|
||||
private static final class EmptyBundle extends ListResourceBundle {
|
||||
@Override
|
||||
protected Object[][] getContents() {
|
||||
return new Object[0][];
|
||||
}
|
||||
}
|
||||
|
||||
protected static class SortLinesTestSetup extends TestSetup {
|
||||
private ICProject fCProject;
|
||||
|
||||
public SortLinesTestSetup(Test test) {
|
||||
super(test);
|
||||
}
|
||||
|
||||
@Override
|
||||
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());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown () throws Exception {
|
||||
EditorTestHelper.closeAllEditors();
|
||||
if (fCProject != null) {
|
||||
CProjectHelper.delete(fCProject);
|
||||
}
|
||||
super.tearDown();
|
||||
}
|
||||
}
|
||||
|
||||
private static final Class<?> THIS= SortLinesTest.class;
|
||||
public static Test suite() {
|
||||
return new SortLinesTestSetup(new TestSuite(THIS));
|
||||
}
|
||||
|
||||
private CEditor fEditor;
|
||||
private SourceViewer fSourceViewer;
|
||||
private IDocument fDocument;
|
||||
private SortLinesTestSetup fProjectSetup;
|
||||
|
||||
/*
|
||||
* @see junit.framework.TestCase#setUp()
|
||||
*/
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
if (!ResourcesPlugin.getWorkspace().getRoot().exists(new Path(PROJECT))) {
|
||||
fProjectSetup= new SortLinesTestSetup(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()
|
||||
*/
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
if (fProjectSetup != null) {
|
||||
fProjectSetup.tearDown();
|
||||
}
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
private void sortLines() throws Exception {
|
||||
new SortLinesAction(fEditor).run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects part of the document.
|
||||
*
|
||||
* @param startLine First line of the selection. Zero based.
|
||||
* @param startPosition Start position of the selection in startLine. Zero based.
|
||||
* @param endLine Last line of the selection. Zero based.
|
||||
* @param endPosition Position after the end of the selection in endLine. Zero based.
|
||||
*/
|
||||
private void select(int startLine, int startPosition, int endLine, int endPosition)
|
||||
throws BadLocationException {
|
||||
int offset = fDocument.getLineOffset(startLine) + startPosition;
|
||||
fSourceViewer.setSelectedRange(offset, fDocument.getLineOffset(endLine) + endPosition - offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects the whole document.
|
||||
*/
|
||||
private void selectAll() {
|
||||
fSourceViewer.setSelectedRange(0, fDocument.getLength());
|
||||
}
|
||||
|
||||
// // e.h
|
||||
// #include "e.h"
|
||||
// #include "bbb.h"
|
||||
// #include "dd.h"
|
||||
// /*
|
||||
// * ccccc.h
|
||||
// */
|
||||
// #include "ccccc.h"
|
||||
// #include "aaaa.h"
|
||||
|
||||
// #include "aaaa.h"
|
||||
// #include "bbb.h"
|
||||
// /*
|
||||
// * ccccc.h
|
||||
// */
|
||||
// #include "ccccc.h"
|
||||
// #include "dd.h"
|
||||
// // e.h
|
||||
// #include "e.h"
|
||||
public void testSortLinesMixed() throws Exception {
|
||||
StringBuffer[] contents= getContentsForTest(2);
|
||||
String before= contents[0].toString();
|
||||
String after= contents[1].toString();
|
||||
fDocument.set(before);
|
||||
selectAll();
|
||||
sortLines();
|
||||
assertEquals(after, fDocument.get());
|
||||
}
|
||||
|
||||
// /*
|
||||
// * Ganymede
|
||||
// * Europa
|
||||
// * Callisto
|
||||
// */
|
||||
|
||||
// /*
|
||||
// * Europa
|
||||
// * Ganymede
|
||||
// * Callisto
|
||||
// */
|
||||
public void testSortLinesCommentsOnly() throws Exception {
|
||||
StringBuffer[] contents= getContentsForTest(2);
|
||||
String before= contents[0].toString();
|
||||
String after= contents[1].toString();
|
||||
fDocument.set(before);
|
||||
select(1, 0, 3, 0);
|
||||
sortLines();
|
||||
assertEquals(after, fDocument.get());
|
||||
}
|
||||
}
|
|
@ -72,9 +72,10 @@ public class TextTestSuite extends TestSuite {
|
|||
// compare tests
|
||||
addTest(CStructureCreatorTest.suite());
|
||||
|
||||
// block comment tests
|
||||
// source manipulation tests
|
||||
addTest(AddBlockCommentTest.suite());
|
||||
addTest(RemoveBlockCommentTest.suite());
|
||||
addTest(SortLinesTest.suite());
|
||||
|
||||
// add include
|
||||
addTest(AddIncludeTest.suite());
|
||||
|
|
|
@ -170,7 +170,7 @@ Refactoring.extractLocalVariable.label=Extract &Local Variable
|
|||
Refactoring.extractFunction.label=Extract &Function...
|
||||
Refactoring.hideMethod.label=Hide Method...
|
||||
Refactoring.implementMethod.label=Impl&ement Method...
|
||||
Refactoring.gettersAndSetters.label=Generate Getters and Setters...
|
||||
Refactoring.gettersAndSetters.label=Gene&rate Getters and Setters...
|
||||
|
||||
Source.menu.label = &Source
|
||||
|
||||
|
@ -253,10 +253,14 @@ OpenTypeAction.tooltip= Open Element
|
|||
ActionDefinition.openType.name= Open Element
|
||||
ActionDefinition.openType.description= Open an element in an Editor
|
||||
|
||||
#Add include
|
||||
#Add Include
|
||||
ActionDefinition.addInclude.name= Add Include
|
||||
ActionDefinition.addInclude.description= Create include statement on selection
|
||||
|
||||
#Sort Lines
|
||||
ActionDefinition.sortLines.name= Sort Lines
|
||||
ActionDefinition.sortLines.description= Sort selected lines alphabetically
|
||||
|
||||
#Show outline dialog
|
||||
ActionDefinition.showOutline.name= Show outline
|
||||
ActionDefinition.showOutline.description= Shows outline
|
||||
|
@ -555,6 +559,7 @@ renameParticipant.name = Source Folder Rename
|
|||
FormatAction.label= &Format
|
||||
IndentAction.label= Correct &Indentation
|
||||
AddIncludeAction.label= A&dd Include
|
||||
SortLinesAction.label= Sor&t Lines
|
||||
CommentAction.label= Co&mment
|
||||
UncommentAction.label= &Uncomment
|
||||
ToggleCommentAction.label= Togg&le Comment
|
||||
|
|
|
@ -1334,6 +1334,13 @@
|
|||
retarget="true">
|
||||
</action>
|
||||
<!-- Import Group -->
|
||||
<action
|
||||
definitionId="org.eclipse.cdt.ui.edit.text.c.sort.lines"
|
||||
label="%SortLinesAction.label"
|
||||
retarget="true"
|
||||
menubarPath="org.eclipse.jdt.ui.source.menu/importGroup"
|
||||
id="org.eclipse.cdt.ui.actions.SortLines">
|
||||
</action>
|
||||
<action
|
||||
definitionId="org.eclipse.cdt.ui.edit.text.c.add.include"
|
||||
label="%AddIncludeAction.label"
|
||||
|
@ -1805,6 +1812,11 @@
|
|||
contextId="org.eclipse.cdt.ui.cEditorScope"
|
||||
commandId="org.eclipse.cdt.ui.edit.text.c.add.include"
|
||||
schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"/>
|
||||
<key
|
||||
sequence="M1+M2+S"
|
||||
contextId="org.eclipse.cdt.ui.cEditorScope"
|
||||
commandId="org.eclipse.cdt.ui.edit.text.c.sort.lines"
|
||||
schemeId="org.eclipse.ui.defaultAcceleratorConfiguration"/>
|
||||
<key
|
||||
sequence="M1+O"
|
||||
contextId="org.eclipse.cdt.ui.cEditorScope"
|
||||
|
@ -2253,6 +2265,12 @@
|
|||
categoryId="org.eclipse.cdt.ui.category.source"
|
||||
id="org.eclipse.cdt.ui.edit.text.c.add.include">
|
||||
</command>
|
||||
<command
|
||||
name="%ActionDefinition.sortLines.name"
|
||||
description="%ActionDefinition.sortLines.description"
|
||||
categoryId="org.eclipse.cdt.ui.category.source"
|
||||
id="org.eclipse.cdt.ui.edit.text.c.sort.lines">
|
||||
</command>
|
||||
<command
|
||||
name="%ActionDefinition.showOutline.name"
|
||||
description="%ActionDefinition.showOutline.description"
|
||||
|
|
|
@ -378,7 +378,6 @@ public class Strings {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Concatenate the given strings into one strings using the passed line delimiter as a
|
||||
* delimiter. No delimiter is added to the last line.
|
||||
|
@ -397,9 +396,10 @@ public class Strings {
|
|||
if (s.length() != c.length)
|
||||
return false;
|
||||
|
||||
for (int i = c.length; --i >= 0;)
|
||||
for (int i = c.length; --i >= 0;) {
|
||||
if (s.charAt(i) != c[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -422,6 +422,31 @@ public class Strings {
|
|||
return text.substring(0, end);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts tabs to spaces in a line of text.
|
||||
* @param line The line of text.
|
||||
* @param tabWidth Tabulation size.
|
||||
* @return The line with tab characters replaced by spaces.
|
||||
*/
|
||||
public static String convertTabsToSpaces(String line, int tabWidth) {
|
||||
StringBuilder buf = null;
|
||||
for (int i = 0; i < line.length(); i++) {
|
||||
char c = line.charAt(i);
|
||||
if (c == '\t') {
|
||||
if (buf == null) {
|
||||
buf = new StringBuilder(line.length() * tabWidth);
|
||||
buf.append(line.subSequence(0, i));
|
||||
}
|
||||
for (int k = tabWidth - i % tabWidth; --k >= 0;) {
|
||||
buf.append(' ');
|
||||
}
|
||||
} else if (buf != null) {
|
||||
buf.append(c);
|
||||
}
|
||||
}
|
||||
return buf != null ? buf.toString() : line;
|
||||
}
|
||||
|
||||
public static String removeMnemonicIndicator(String string) {
|
||||
return LegacyActionTools.removeMnemonics(string);
|
||||
}
|
||||
|
|
|
@ -2191,6 +2191,12 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
|||
setAction("Format", action); //$NON-NLS-1$
|
||||
markAsStateDependentAction("Format", true); //$NON-NLS-1$
|
||||
|
||||
action = new SortLinesAction(this);
|
||||
action.setActionDefinitionId(ICEditorActionDefinitionIds.SORT_LINES);
|
||||
setAction("SortLines", action); //$NON-NLS-1$
|
||||
markAsStateDependentAction("SortLines", true); //$NON-NLS-1$
|
||||
markAsSelectionDependentAction("SortLines", true); //$NON-NLS-1$
|
||||
|
||||
action = new ContentAssistAction(bundle, "ContentAssistProposal.", this); //$NON-NLS-1$
|
||||
action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
|
||||
setAction("ContentAssistProposal", action); //$NON-NLS-1$
|
||||
|
|
|
@ -196,6 +196,7 @@ public class CEditorActionContributor extends TextEditorActionContributor {
|
|||
bars.setGlobalActionHandler(CdtActionConstants.REMOVE_BLOCK_COMMENT, getAction(textEditor, "RemoveBlockComment")); //$NON-NLS-1$
|
||||
bars.setGlobalActionHandler(CdtActionConstants.INDENT, getAction(textEditor, "Indent")); //$NON-NLS-1$
|
||||
bars.setGlobalActionHandler(CdtActionConstants.ADD_INCLUDE, getAction(textEditor, "AddIncludeOnSelection")); //$NON-NLS-1$
|
||||
bars.setGlobalActionHandler(CdtActionConstants.SORT_LINES, getAction(textEditor, "SortLines")); //$NON-NLS-1$
|
||||
|
||||
IAction action= getAction(textEditor, ITextEditorActionConstants.REFRESH);
|
||||
bars.setGlobalActionHandler(ITextEditorActionConstants.REFRESH, action);
|
||||
|
|
|
@ -17,6 +17,10 @@ AddIncludeOnSelection.description=Add include statement for selected name
|
|||
AddIncludeOnSelection.label=Add Include
|
||||
AddIncludeOnSelection.tooltip=Add Include Statement for Selected Name
|
||||
|
||||
SortLines.description=Sort selected lines alphabetically
|
||||
SortLines.label=Sort Lines
|
||||
SortLines.tooltip=Sort Selected Lines Alphabetically
|
||||
|
||||
OpenOutline.label= Quick Out&line
|
||||
OpenOutline.tooltip= Shows the Quick Outline of Editor Input
|
||||
OpenOutline.description= Shows the quick outline for the editor input
|
||||
|
|
|
@ -235,11 +235,17 @@ public interface ICEditorActionDefinitionIds extends ITextEditorActionDefinition
|
|||
*/
|
||||
public static final String TOGGLE_MARK_OCCURRENCES= "org.eclipse.cdt.ui.edit.text.c.toggleMarkOccurrences"; //$NON-NLS-1$
|
||||
|
||||
|
||||
/**
|
||||
* Action definition ID of the open macro explorer quick view action
|
||||
* (value <code>"org.eclipse.cdt.ui.edit.open.quick.macro.explorer"</code>).
|
||||
* @since 5.0
|
||||
*/
|
||||
public static final String OPEN_QUICK_MACRO_EXPLORER = "org.eclipse.cdt.ui.edit.open.quick.macro.explorer"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Action definition id of sort lines action.
|
||||
* (value: <code>"org.eclipse.cdt.ui.edit.text.c.sort.lines"</code>).
|
||||
* @since 5.2
|
||||
*/
|
||||
public static final String SORT_LINES = "org.eclipse.cdt.ui.edit.text.c.sort.lines"; //$NON-NLS-1$
|
||||
}
|
||||
|
|
|
@ -0,0 +1,329 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010 Google, 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:
|
||||
* Sergey Prigogin (Google) - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.ui.editor;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.eclipse.jface.text.BadLocationException;
|
||||
import org.eclipse.jface.text.IDocument;
|
||||
import org.eclipse.jface.text.IRegion;
|
||||
import org.eclipse.jface.text.ITextSelection;
|
||||
import org.eclipse.jface.text.ITypedRegion;
|
||||
import org.eclipse.jface.text.Region;
|
||||
import org.eclipse.jface.text.TextSelection;
|
||||
import org.eclipse.jface.text.TextUtilities;
|
||||
import org.eclipse.jface.viewers.ISelection;
|
||||
import org.eclipse.text.edits.ReplaceEdit;
|
||||
import org.eclipse.text.undo.DocumentUndoManagerRegistry;
|
||||
import org.eclipse.text.undo.IDocumentUndoManager;
|
||||
import org.eclipse.ui.IEditorInput;
|
||||
import org.eclipse.ui.texteditor.ITextEditor;
|
||||
import org.eclipse.ui.texteditor.TextEditorAction;
|
||||
|
||||
import com.ibm.icu.text.Collator;
|
||||
|
||||
import org.eclipse.cdt.core.model.ICProject;
|
||||
import org.eclipse.cdt.ui.CUIPlugin;
|
||||
import org.eclipse.cdt.ui.text.ICPartitions;
|
||||
|
||||
import org.eclipse.cdt.internal.corext.util.CodeFormatterUtil;
|
||||
import org.eclipse.cdt.internal.corext.util.Strings;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.util.EditorUtility;
|
||||
|
||||
/**
|
||||
* Sorts selected lines in alphabetical order. If both, comment and non-comment lines
|
||||
* are selected, the non-comment lines are sorted, and the comments are moved together
|
||||
* with the non-comment lines they precede.
|
||||
*
|
||||
* @since 5.2
|
||||
*/
|
||||
public final class SortLinesAction extends TextEditorAction {
|
||||
|
||||
public SortLinesAction(ITextEditor editor) {
|
||||
super(CEditorMessages.getBundleForConstructedKeys(), "SortLines.", editor); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts selected lines.
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
ITextEditor editor= getTextEditor();
|
||||
if (editor == null)
|
||||
return;
|
||||
|
||||
ISelection selection = editor.getSelectionProvider().getSelection();
|
||||
if (!(selection instanceof ITextSelection))
|
||||
return;
|
||||
|
||||
ITextSelection textSelection= (ITextSelection) selection;
|
||||
if (textSelection.getStartLine() < 0 || textSelection.getEndLine() < 0)
|
||||
return;
|
||||
|
||||
IEditorInput editorInput = editor.getEditorInput();
|
||||
ICProject cProject = EditorUtility.getCProject(editorInput);
|
||||
IDocument document= editor.getDocumentProvider().getDocument(editorInput);
|
||||
try {
|
||||
IRegion block= getTextBlockFromSelection(textSelection, document);
|
||||
SortElement[] elements = createSortElements(block, document,
|
||||
CodeFormatterUtil.getTabWidth(cProject));
|
||||
if (elements.length <= 1)
|
||||
return;
|
||||
if (!validateEditorInputState())
|
||||
return;
|
||||
|
||||
Arrays.sort(elements);
|
||||
StringBuilder buf = new StringBuilder();
|
||||
for (SortElement element : elements) {
|
||||
buf.append(document.get(element.getOffset(), element.getLength()));
|
||||
if (!isLastLineTerminated(element, document)) {
|
||||
buf.append(TextUtilities.getDefaultLineDelimiter(document));
|
||||
}
|
||||
}
|
||||
ReplaceEdit edit = new ReplaceEdit(block.getOffset(), block.getLength(), buf.toString());
|
||||
IDocumentUndoManager manager= DocumentUndoManagerRegistry.getDocumentUndoManager(document);
|
||||
manager.beginCompoundChange();
|
||||
edit.apply(document);
|
||||
editor.getSelectionProvider().setSelection(new TextSelection(block.getOffset(), buf.length()));
|
||||
manager.endCompoundChange();
|
||||
} catch (BadLocationException e) {
|
||||
CUIPlugin.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a region describing the text block (something that consists of full lines)
|
||||
* completely containing the current selection.
|
||||
*
|
||||
* @param selection The selection to use
|
||||
* @param document The document
|
||||
* @return the region describing the text block comprising the given selection
|
||||
*/
|
||||
private IRegion getTextBlockFromSelection(ITextSelection selection, IDocument document) {
|
||||
try {
|
||||
IRegion firstLine= document.getLineInformationOfOffset(selection.getOffset());
|
||||
int selectionEnd = selection.getOffset() + selection.getLength();
|
||||
IRegion lastLine= document.getLineInformationOfOffset(selectionEnd);
|
||||
int length = lastLine.getOffset() - firstLine.getOffset();
|
||||
if (selectionEnd > lastLine.getOffset()) {
|
||||
// Last line is included with the line delimiter.
|
||||
length += document.getLineLength(document.getLineOfOffset(selectionEnd));
|
||||
}
|
||||
return new Region(firstLine.getOffset(), length);
|
||||
} catch (BadLocationException e) {
|
||||
CUIPlugin.log(e); // Should not happen
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private SortElement[] createSortElements(IRegion block, IDocument document, int tabWidth)
|
||||
throws BadLocationException {
|
||||
ITypedRegion[] regions= TextUtilities.computePartitioning(document, ICPartitions.C_PARTITIONING,
|
||||
block.getOffset(), block.getLength(), false);
|
||||
|
||||
int numLines = document.getNumberOfLines(block.getOffset(), block.getLength());
|
||||
if (endOf(block) <= document.getLineInformationOfOffset(endOf(block)).getOffset()) {
|
||||
numLines--; // Last line is excluded
|
||||
}
|
||||
LineInfo[] lineDescriptors = new LineInfo[numLines];
|
||||
int numNonCommentLines = 0;
|
||||
int i = 0;
|
||||
int k = 0;
|
||||
int line = document.getLineOfOffset(block.getOffset());
|
||||
int endLine = line + numLines;
|
||||
for (; line < endLine; line++) {
|
||||
LineInfo lineInfo = new LineInfo(document, line);
|
||||
lineDescriptors[k++] = lineInfo;
|
||||
while (i < regions.length && endOf(regions[i]) <= lineInfo.getTrimmedOffset())
|
||||
i++;
|
||||
for (; i < regions.length && regions[i].getOffset() < lineInfo.getTrimmedEndOffset(); i++) {
|
||||
ITypedRegion region = regions[i];
|
||||
if (region.getType() != ICPartitions.C_MULTI_LINE_COMMENT &&
|
||||
region.getType() != ICPartitions.C_MULTI_LINE_DOC_COMMENT &&
|
||||
region.getType() != ICPartitions.C_SINGLE_LINE_COMMENT &&
|
||||
region.getType() != ICPartitions.C_SINGLE_LINE_DOC_COMMENT) {
|
||||
lineInfo.nonComment = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (lineInfo.nonComment) {
|
||||
numNonCommentLines++;
|
||||
}
|
||||
}
|
||||
SortElement[] elements;
|
||||
if (numNonCommentLines > 1) {
|
||||
elements = new SortElement[numNonCommentLines];
|
||||
k = 0;
|
||||
int offset = block.getOffset();
|
||||
for (int j = 0; j < lineDescriptors.length; j++) {
|
||||
LineInfo lineInfo = lineDescriptors[j];
|
||||
if (lineInfo.nonComment) {
|
||||
int endOffset = k < numNonCommentLines - 1 ?
|
||||
lineInfo.getEndOffset() : block.getOffset() + block.getLength();
|
||||
elements[k++] = new SortElement(new Region(offset, endOffset - offset), lineInfo,
|
||||
document, tabWidth);
|
||||
offset = lineInfo.getEndOffset();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
elements = new SortElement[numLines];
|
||||
for (int j = 0; j < lineDescriptors.length; j++) {
|
||||
LineInfo lineInfo = lineDescriptors[j];
|
||||
elements[j] = new SortElement(lineInfo, lineInfo, document, tabWidth);
|
||||
}
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns end offset of a region.
|
||||
*/
|
||||
private int endOf(IRegion region) {
|
||||
return region.getOffset() + region.getLength();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <code>true</code> if the given region is terminated by a line delimiter.
|
||||
*/
|
||||
private static boolean isLastLineTerminated(IRegion region, IDocument document) throws BadLocationException {
|
||||
int offset = region.getOffset() + region.getLength();
|
||||
IRegion nextLine = document.getLineInformationOfOffset(offset);
|
||||
return nextLine.getOffset() == offset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
if (!canModifyEditor()) {
|
||||
setEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Enable if two or more lines are selected.
|
||||
boolean enabled = false;
|
||||
ITextEditor editor = getTextEditor();
|
||||
if (editor != null) {
|
||||
ISelection selection = editor.getSelectionProvider().getSelection();
|
||||
if (selection instanceof ITextSelection) {
|
||||
ITextSelection textSelection= (ITextSelection) selection;
|
||||
int startLine = textSelection.getStartLine();
|
||||
int endLine = textSelection.getEndLine();
|
||||
if (startLine >= 0 && endLine > startLine) {
|
||||
if (endLine == startLine + 1) {
|
||||
IDocument document= editor.getDocumentProvider().getDocument(editor.getEditorInput());
|
||||
try {
|
||||
if (textSelection.getOffset() + textSelection.getLength() > document.getLineOffset(endLine)) {
|
||||
enabled = true;
|
||||
}
|
||||
} catch (BadLocationException e) {
|
||||
CUIPlugin.log(e);
|
||||
}
|
||||
} else {
|
||||
enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
setEnabled(enabled);
|
||||
}
|
||||
|
||||
/*
|
||||
* @see TextEditorAction#setEditor(ITextEditor)
|
||||
*/
|
||||
@Override
|
||||
public void setEditor(ITextEditor editor) {
|
||||
super.setEditor(editor);
|
||||
}
|
||||
|
||||
private static class SortElement implements Comparable<SortElement>, IRegion {
|
||||
private static final Collator collator = Collator.getInstance();
|
||||
private final IRegion region;
|
||||
private final String collationKey;
|
||||
|
||||
public SortElement(IRegion region, IRegion collationLine, IDocument document, int tabWidth)
|
||||
throws BadLocationException {
|
||||
super();
|
||||
this.region = region;
|
||||
this.collationKey = Strings.convertTabsToSpaces(Strings.trimTrailingTabsAndSpaces(
|
||||
document.get(collationLine.getOffset(), collationLine.getLength())), tabWidth);
|
||||
}
|
||||
|
||||
public int compareTo(SortElement other) {
|
||||
return collator.compare(collationKey, other.collationKey);
|
||||
}
|
||||
|
||||
public int getOffset() {
|
||||
return region.getOffset();
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return region.getLength();
|
||||
}
|
||||
}
|
||||
|
||||
private static class LineInfo implements IRegion {
|
||||
final int offset;
|
||||
final int length;
|
||||
final int trimmedOffset;
|
||||
final int trimmedEndOffset;
|
||||
boolean nonComment;
|
||||
|
||||
LineInfo(IDocument document, int line) throws BadLocationException {
|
||||
offset = document.getLineOffset(line);
|
||||
length = document.getLineLength(line);
|
||||
int begin = offset;
|
||||
int end = offset + length;
|
||||
while (--end >= begin && Character.isWhitespace(document.getChar(end))) {
|
||||
}
|
||||
end++;
|
||||
while (begin < end && Character.isWhitespace(document.getChar(begin))) {
|
||||
begin++;
|
||||
}
|
||||
trimmedOffset = begin;
|
||||
trimmedEndOffset = end;
|
||||
}
|
||||
|
||||
/**
|
||||
* Offset of the line in the document.
|
||||
*/
|
||||
public int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Length of the line including line delimiter.
|
||||
*/
|
||||
public int getLength() {
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* End offset of the line including line delimiter.
|
||||
*/
|
||||
public int getEndOffset() {
|
||||
return offset + length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Document offset of the first non-whitespace character of the line.
|
||||
*/
|
||||
public int getTrimmedOffset() {
|
||||
return trimmedOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Document offset after the last non-whitespace character of the line.
|
||||
*/
|
||||
public int getTrimmedEndOffset() {
|
||||
return trimmedEndOffset;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -139,6 +139,13 @@ public class CdtActionConstants {
|
|||
*/
|
||||
public static final String ADD_INCLUDE= "org.eclipse.cdt.ui.actions.AddInclude"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Source menu: name of standard Sort Lines global action
|
||||
* (value <code>"org.eclipse.cdt.ui.actions.SortLines"</code>).
|
||||
* @since 5.2
|
||||
*/
|
||||
public static final String SORT_LINES= "org.eclipse.cdt.ui.actions.SortLines"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Source menu: name of standard Sort Members global action (value
|
||||
* <code>"org.eclipse.cdt.ui.actions.SortMembers"</code>).
|
||||
|
|
|
@ -52,6 +52,7 @@ import org.eclipse.cdt.internal.ui.actions.CDTQuickMenuCreator;
|
|||
import org.eclipse.cdt.internal.ui.editor.AddIncludeOnSelectionAction;
|
||||
import org.eclipse.cdt.internal.ui.editor.CEditor;
|
||||
import org.eclipse.cdt.internal.ui.editor.ICEditorActionDefinitionIds;
|
||||
import org.eclipse.cdt.internal.ui.editor.SortLinesAction;
|
||||
|
||||
/**
|
||||
* Action group that adds the source and generate actions to a part's context
|
||||
|
@ -129,6 +130,7 @@ public class GenerateActionGroup extends ActionGroup implements ISelectionChange
|
|||
//
|
||||
// private OrganizeIncludesAction fOrganizeIncludes;
|
||||
// private SortMembersAction fSortMembers;
|
||||
private SortLinesAction fSortLines;
|
||||
// private FormatAllAction fFormatAll;
|
||||
// private CopyQualifiedNameAction fCopyQualifiedNameAction;
|
||||
//
|
||||
|
@ -161,7 +163,11 @@ public class GenerateActionGroup extends ActionGroup implements ISelectionChange
|
|||
// fSortMembers= new SortMembersAction(editor);
|
||||
// fSortMembers.setActionDefinitionId(ICEditorActionDefinitionIds.SORT_MEMBERS);
|
||||
// editor.setAction("SortMembers", fSortMembers); //$NON-NLS-1$
|
||||
//
|
||||
|
||||
fSortLines= new SortLinesAction(editor);
|
||||
fSortLines.setActionDefinitionId(ICEditorActionDefinitionIds.SORT_LINES);
|
||||
editor.setAction("SortLines", fSortLines); //$NON-NLS-1$
|
||||
|
||||
// IAction pastAction= editor.getAction(ITextEditorActionConstants.PASTE);//IWorkbenchActionDefinitionIds.PASTE);
|
||||
// fCopyQualifiedNameAction= new CopyQualifiedNameAction(editor, null, pastAction);
|
||||
// fCopyQualifiedNameAction.setActionDefinitionId(CopyQualifiedNameAction.JAVA_EDITOR_ACTION_DEFINITIONS_ID);
|
||||
|
@ -412,6 +418,7 @@ public class GenerateActionGroup extends ActionGroup implements ISelectionChange
|
|||
added+= addAction(source, fAddInclude);
|
||||
// added+= addAction(source, fOrganizeIncludes);
|
||||
// added+= addAction(source, fSortMembers);
|
||||
added+= addAction(source, fSortLines);
|
||||
// added+= addAction(source, fCleanUp);
|
||||
source.add(new Separator(GROUP_GENERATE));
|
||||
// added+= addAction(source, fOverrideMethods);
|
||||
|
|
Loading…
Add table
Reference in a new issue