Added Tabs to Spaces conversion and Source menu; fixed reindenter range bug
diff --git a/org.eclipse.photran.core.vpg/parser/org/eclipse/photran/core/IFortranAST.java b/org.eclipse.photran.core.vpg/parser/org/eclipse/photran/core/IFortranAST.java
index 92ce525..e2d0f18 100644
--- a/org.eclipse.photran.core.vpg/parser/org/eclipse/photran/core/IFortranAST.java
+++ b/org.eclipse.photran.core.vpg/parser/org/eclipse/photran/core/IFortranAST.java
@@ -41,6 +41,8 @@
public Iterator<Token> iterator();
public Token findTokenByStreamOffsetLength(int offset, int length);
public Token findFirstTokenOnLine(int line);
+ public Token findFirstTokenOnOrAfterLine(int line);
public Token findLastTokenOnLine(int line);
+ public Token findLastTokenOnOrBeforeLine(int line);
public Token findTokenByFileOffsetLength(IFile file, int offset, int length);
}
diff --git a/org.eclipse.photran.core.vpg/parser/org/eclipse/photran/internal/core/FortranAST.java b/org.eclipse.photran.core.vpg/parser/org/eclipse/photran/internal/core/FortranAST.java
index a757b41..9d601fe 100644
--- a/org.eclipse.photran.core.vpg/parser/org/eclipse/photran/internal/core/FortranAST.java
+++ b/org.eclipse.photran.core.vpg/parser/org/eclipse/photran/internal/core/FortranAST.java
@@ -130,9 +130,21 @@
return tokenList.findFirstTokenOnLine(line);
}
+ public Token findFirstTokenOnOrAfterLine(int line)
+ {
+ // Binary Search
+ return tokenList.findFirstTokenOnOrAfterLine(line);
+ }
+
public Token findLastTokenOnLine(int line)
{
// Binary Search
return tokenList.findLastTokenOnLine(line);
}
+
+ public Token findLastTokenOnOrBeforeLine(int line)
+ {
+ // Binary Search
+ return tokenList.findLastTokenOnOrBeforeLine(line);
+ }
}
\ No newline at end of file
diff --git a/org.eclipse.photran.core.vpg/src/org/eclipse/photran/internal/core/reindenter/Reindenter.java b/org.eclipse.photran.core.vpg/src/org/eclipse/photran/internal/core/reindenter/Reindenter.java
index 792e138..b9bb447 100644
--- a/org.eclipse.photran.core.vpg/src/org/eclipse/photran/internal/core/reindenter/Reindenter.java
+++ b/org.eclipse.photran.core.vpg/src/org/eclipse/photran/internal/core/reindenter/Reindenter.java
@@ -98,7 +98,7 @@
public static void reindent(int fromLine, int thruLine, IFortranAST ast, Strategy strategy)
{
- reindent(ast.findFirstTokenOnLine(fromLine), ast.findLastTokenOnLine(thruLine), ast, strategy);
+ reindent(ast.findFirstTokenOnOrAfterLine(fromLine), ast.findLastTokenOnOrBeforeLine(thruLine), ast, strategy);
}
private static void reindent(Token firstTokenInRegion, Token lastTokenInRegion, IFortranAST ast, Strategy strategy)
diff --git a/org.eclipse.photran.core/src/org/eclipse/photran/internal/core/preferences/FortranBooleanPreference.java b/org.eclipse.photran.core/src/org/eclipse/photran/internal/core/preferences/FortranBooleanPreference.java
index ef4b894..6e22615 100644
--- a/org.eclipse.photran.core/src/org/eclipse/photran/internal/core/preferences/FortranBooleanPreference.java
+++ b/org.eclipse.photran.core/src/org/eclipse/photran/internal/core/preferences/FortranBooleanPreference.java
@@ -48,6 +48,9 @@
*/
public boolean getValue()
{
- return getPreferenceStore().getBoolean(getName());
+ if (!getPreferenceStore().contains(getName()))
+ return defaultValue;
+ else
+ return getPreferenceStore().getBoolean(getName());
}
}
\ No newline at end of file
diff --git a/org.eclipse.photran.core/src/org/eclipse/photran/internal/core/preferences/FortranPreferences.java b/org.eclipse.photran.core/src/org/eclipse/photran/internal/core/preferences/FortranPreferences.java
index 4eb1573..d58cf53 100644
--- a/org.eclipse.photran.core/src/org/eclipse/photran/internal/core/preferences/FortranPreferences.java
+++ b/org.eclipse.photran.core/src/org/eclipse/photran/internal/core/preferences/FortranPreferences.java
@@ -50,6 +50,7 @@
public static final FortranStringPreference PREFERRED_DOM_PARSER = new FortranStringPreference("domparser", ""); //$NON-NLS-1$ //$NON-NLS-2$
public static final FortranIntegerPreference FIXED_FORM_COMMENT_COLUMN = new FortranIntegerPreference("fixedformcommentcolum", 72, FortranIntegerPreference.NO_LIMIT, 72); //$NON-NLS-1$
+ public static final FortranBooleanPreference CONVERT_TABS_TO_SPACES = new FortranBooleanPreference("converttabs", true); //$NON-NLS-1$
private FortranPreferences() {}
diff --git a/org.eclipse.photran.core/src/org/eclipse/photran/internal/core/preferences/FortranStringPreference.java b/org.eclipse.photran.core/src/org/eclipse/photran/internal/core/preferences/FortranStringPreference.java
index 66d2981..e4b51ad 100644
--- a/org.eclipse.photran.core/src/org/eclipse/photran/internal/core/preferences/FortranStringPreference.java
+++ b/org.eclipse.photran.core/src/org/eclipse/photran/internal/core/preferences/FortranStringPreference.java
@@ -48,6 +48,9 @@
*/
public String getValue()
{
- return getPreferenceStore().getString(getName());
+ if (!getPreferenceStore().contains(getName()))
+ return defaultValue;
+ else
+ return getPreferenceStore().getString(getName());
}
}
\ No newline at end of file
diff --git a/org.eclipse.photran.ui.vpg/plugin.xml b/org.eclipse.photran.ui.vpg/plugin.xml
index cc276b4..ff4fb59 100644
--- a/org.eclipse.photran.ui.vpg/plugin.xml
+++ b/org.eclipse.photran.ui.vpg/plugin.xml
@@ -353,7 +353,7 @@
id="org.eclipse.photran.ui.Reindenter">
<action
label="%action.label.reindent.0"
- menubarPath="edit/additions"
+ menubarPath="org.eclipse.photran.ui.source.menu/indentationActions"
definitionId="org.eclipse.photran.ui.ReindenterCommand"
class="org.eclipse.photran.internal.ui.actions.ReindentAction"
id="org.eclipse.photran.ui.ReindenterAction">
diff --git a/org.eclipse.photran.ui/META-INF/MANIFEST.MF b/org.eclipse.photran.ui/META-INF/MANIFEST.MF
index 026db4b..23d4bcf 100644
--- a/org.eclipse.photran.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.photran.ui/META-INF/MANIFEST.MF
@@ -28,6 +28,7 @@
org.eclipse.cdt.debug.ui,
org.eclipse.cdt.core,
org.eclipse.debug.ui,
- org.eclipse.rephraserengine.ui.refactoring;resolution:=optional
+ org.eclipse.rephraserengine.ui.refactoring;resolution:=optional,
+ org.eclipse.cdt.ui
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/org.eclipse.photran.ui/plugin.xml b/org.eclipse.photran.ui/plugin.xml
index 5a1306d..2ca57a7 100644
--- a/org.eclipse.photran.ui/plugin.xml
+++ b/org.eclipse.photran.ui/plugin.xml
@@ -73,7 +73,7 @@
id="org.eclipse.photran.ui.CommentUncomment">
<action
label="%action.label.0"
- menubarPath="edit/additions"
+ menubarPath="org.eclipse.photran.ui.source.menu/commentActions"
definitionId="org.eclipse.photran.ui.CommentCommand"
class="org.eclipse.photran.internal.ui.actions.FortranBlockCommentActionDelegate"
id="org.eclipse.photran.ui.BlockCommentAction">
@@ -153,6 +153,40 @@
</actionSetPartAssociation>
</extension>
+ <!--=============-->
+ <!-- Source Menu -->
+ <!--=============-->
+ <extension point="org.eclipse.ui.menus">
+ <menuContribution
+ locationURI="menu:org.eclipse.ui.main.menu?after=edit">
+ <menu
+ label="Source"
+ id="org.eclipse.photran.ui.source.menu">
+ <separator
+ name="commentActions">
+ </separator>
+ <!-- SEPARATOR --><separator name="separator1" visible="true" />
+ <command
+ commandId="org.eclipse.ui.edit.text.shiftRight"
+ label="Shift Right"
+ style="push">
+ </command>
+ <command
+ commandId="org.eclipse.ui.edit.text.shiftLeft"
+ label="Shift Left"
+ style="push">
+ </command>
+ <separator
+ name="indentationActions">
+ </separator>
+ <!-- SEPARATOR --><separator name="separator1" visible="true" />
+ <separator
+ name="additions">
+ </separator>
+ </menu>
+ </menuContribution>
+ </extension>
+
<!--===================================-->
<!-- Fortran-specific preference pages -->
<!--===================================-->
diff --git a/org.eclipse.photran.ui/src/org/eclipse/photran/internal/ui/editor/FortranEditor.java b/org.eclipse.photran.ui/src/org/eclipse/photran/internal/ui/editor/FortranEditor.java
index 370720a..3da125d 100644
--- a/org.eclipse.photran.ui/src/org/eclipse/photran/internal/ui/editor/FortranEditor.java
+++ b/org.eclipse.photran.ui/src/org/eclipse/photran/internal/ui/editor/FortranEditor.java
@@ -14,6 +14,8 @@
import java.util.HashMap;
import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.internal.ui.editor.CDocumentProvider;
+import org.eclipse.cdt.internal.ui.text.TabsToSpacesConverter;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
@@ -23,12 +25,14 @@
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.text.DefaultLineTracker;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.jface.text.IPaintPositionManager;
import org.eclipse.jface.text.IPainter;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.ITextViewerExtension2;
+import org.eclipse.jface.text.ITextViewerExtension7;
import org.eclipse.jface.text.MarginPainter;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.presentation.IPresentationReconciler;
@@ -79,12 +83,12 @@
import org.eclipse.ui.texteditor.WorkbenchChainedTextFontFieldEditor;
/**
- * Base class for the fixed and free-form Fortran editors
+ * Fortran editor
*
* @author Jeff Overbey
* @author Kurt Hendle - folding support
*/
-@SuppressWarnings("deprecation")
+@SuppressWarnings({ "deprecation", "restriction" })
public class FortranEditor extends CDTBasedTextEditor implements ISelectionChangedListener
{
///////////////////////////////////////////////////////////////////////////////////////////////
@@ -199,6 +203,37 @@
}
///////////////////////////////////////////////////////////////////////////////////////////////
+ // Tabs to Spaces Conversion
+ ///////////////////////////////////////////////////////////////////////////////////////////////
+
+ // See also FortranSourceViewer
+
+ @Override
+ protected boolean isTabsToSpacesConversionEnabled() {
+ return FortranPreferences.CONVERT_TABS_TO_SPACES.getValue();
+ }
+
+ @Override
+ protected void installTabsToSpacesConverter() {
+ ISourceViewer sourceViewer= getSourceViewer();
+ SourceViewerConfiguration config= getSourceViewerConfiguration();
+ if (config != null && sourceViewer instanceof ITextViewerExtension7) {
+ int tabWidth= config.getTabWidth(sourceViewer);
+ TabsToSpacesConverter tabToSpacesConverter= new TabsToSpacesConverter();
+ tabToSpacesConverter.setNumberOfSpacesPerTab(tabWidth);
+ IDocumentProvider provider= getDocumentProvider();
+ if (provider instanceof CDocumentProvider) {
+ CDocumentProvider cProvider= (CDocumentProvider) provider;
+ tabToSpacesConverter.setLineTracker(cProvider.createLineTracker(getEditorInput()));
+ } else {
+ tabToSpacesConverter.setLineTracker(new DefaultLineTracker());
+ }
+ ((ITextViewerExtension7) sourceViewer).setTabsToSpacesConverter(tabToSpacesConverter);
+ //updateIndentationMode();
+ }
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////////////////
// Context Menu Contribution
///////////////////////////////////////////////////////////////////////////////////////////////
@@ -206,7 +241,7 @@
@Override public void editorContextMenuAboutToShow(IMenuManager menu)
{
super.editorContextMenuAboutToShow(menu);
-
+
try
{
// Instantiate RefactorMenu using reflection since it's in an optional dependency
@@ -237,7 +272,7 @@
//fAnnotationAccess = createAnnotationAccess();
//fOverviewRuler = createOverviewRuler(getSharedColors());
- ISourceViewer sourceViewer = new ProjectionViewer(parent, ruler, getOverviewRuler(), isOverviewRulerVisible(), styles);
+ ISourceViewer sourceViewer = new FortranSourceViewer(parent, ruler, getOverviewRuler(), isOverviewRulerVisible(), styles);
getSourceViewerDecorationSupport(sourceViewer); // Ensure decoration support has been created and configured
diff --git a/org.eclipse.photran.ui/src/org/eclipse/photran/internal/ui/editor/FortranSourceViewer.java b/org.eclipse.photran.ui/src/org/eclipse/photran/internal/ui/editor/FortranSourceViewer.java
new file mode 100644
index 0000000..5187073
--- /dev/null
+++ b/org.eclipse.photran.ui/src/org/eclipse/photran/internal/ui/editor/FortranSourceViewer.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2009, 2010 QNX Software Systems 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:
+ * QNX Software Systems - initial API and implementation
+ * Sergey Prigogin, Google
+ * Anton Leherbauer (Wind River Systems)
+ * Markus Schorn (Wind River Systems)
+ * Jeff Overbey (UIUC) - Excerpted and modified CSourceViewer for Photran
+ *******************************************************************************/
+package org.eclipse.photran.internal.ui.editor;
+
+import org.eclipse.cdt.internal.ui.editor.IndentUtil;
+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.source.IOverviewRuler;
+import org.eclipse.jface.text.source.IVerticalRuler;
+import org.eclipse.jface.text.source.projection.ProjectionViewer;
+import org.eclipse.photran.internal.core.preferences.FortranPreferences;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Custom source viewer that uses spaces, rather than tabs, to implement the Shift Left
+ * and Shift Right actions if the corresponding workspace preference is enabled.
+ *
+ * @author Jeff Overbey based on CSourceViewer (see attributions in copyright header)
+ */
+@SuppressWarnings("restriction")
+public class FortranSourceViewer extends ProjectionViewer
+{
+ private static final int TAB_WIDTH = 4;
+
+ public FortranSourceViewer(
+ Composite parent,
+ IVerticalRuler ruler,
+ IOverviewRuler overviewRuler,
+ boolean showsAnnotationOverview,
+ int styles)
+ {
+ super(parent, ruler, overviewRuler, showsAnnotationOverview, styles);
+ }
+
+ @Override
+ protected void shift(boolean useDefaultPrefixes, boolean right, boolean ignoreWhitespace) {
+ if (!useDefaultPrefixes && FortranPreferences.CONVERT_TABS_TO_SPACES.getValue())
+ adjustIndent(right, TAB_WIDTH, true);
+ else
+ 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;
+ }
+}
diff --git a/org.eclipse.photran.ui/src/org/eclipse/photran/internal/ui/preferences/EditorPreferencePage.java b/org.eclipse.photran.ui/src/org/eclipse/photran/internal/ui/preferences/EditorPreferencePage.java
index 41f398c..ea88ae6 100644
--- a/org.eclipse.photran.ui/src/org/eclipse/photran/internal/ui/preferences/EditorPreferencePage.java
+++ b/org.eclipse.photran.ui/src/org/eclipse/photran/internal/ui/preferences/EditorPreferencePage.java
@@ -35,7 +35,11 @@
"Enable folding rather than ruler in fixed-form Fortran editors",
getFieldEditorParent()));
*/
-
+
+ addField(new BooleanFieldEditor(FortranPreferences.CONVERT_TABS_TO_SPACES.getName(),
+ "Convert tabs to spaces",
+ getFieldEditorParent()));
+
IntegerFieldEditor intEditor = new IntegerFieldEditor(FortranPreferences.FIXED_FORM_COMMENT_COLUMN.getName(),
Messages.EditorPreferencePage_FixedFormLineLength,
getFieldEditorParent());
diff --git a/org.eclipse.rephraserengine.core/src/org/eclipse/rephraserengine/core/util/TokenList.java b/org.eclipse.rephraserengine.core/src/org/eclipse/rephraserengine/core/util/TokenList.java
index 4607c48..a4797de 100644
--- a/org.eclipse.rephraserengine.core/src/org/eclipse/rephraserengine/core/util/TokenList.java
+++ b/org.eclipse.rephraserengine.core/src/org/eclipse/rephraserengine/core/util/TokenList.java
@@ -158,6 +158,20 @@
return array[index];
}
+ public T findFirstTokenOnOrAfterLine(int line)
+ {
+ T result = findFirstTokenOnLine(line);
+ if (result != null)
+ return result;
+ else
+ {
+ for (int index = 0; index < size; index++)
+ if (getLine(array[index]) >= line)
+ return array[index];
+ return null;
+ }
+ }
+
private int findIndexOfAnyTokenOnLine(int line)
{
int low = 0, high = size - 1;
@@ -182,6 +196,27 @@
index++;
return array[index];
}
+
+ public T findLastTokenOnOrBeforeLine(int line)
+ {
+ T result = findLastTokenOnLine(line);
+ if (result != null)
+ return result;
+ else
+ {
+ for (int index = 0; index < size; index++)
+ {
+ if (getLine(array[index]) > line)
+ {
+ if (index == 0)
+ return null;
+ else
+ return array[index-1];
+ }
+ }
+ return array[size-1];
+ }
+ }
public Iterator<T> iterator()
{
diff --git a/org.eclipse.rephraserengine.ui.refactoring/plugin.xml b/org.eclipse.rephraserengine.ui.refactoring/plugin.xml
index 86399a5..7dd13f4 100644
--- a/org.eclipse.rephraserengine.ui.refactoring/plugin.xml
+++ b/org.eclipse.rephraserengine.ui.refactoring/plugin.xml
@@ -16,7 +16,7 @@
<!-- ============================= -->
<!-- Always visible -->
<menuContribution
- locationURI="menu:org.eclipse.ui.main.menu?after=edit">
+ locationURI="menu:org.eclipse.ui.main.menu?before=navigate">
<!-- Menu mimicks org.eclipse.jdt.ui's (as does CDT's Refactor menu)
http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.jdt.ui/plugin.xml?view=markup -->
<menu