View | Details | Raw Unified | Return to bug 40255 | Differences between
and this patch

Collapse All | Expand All

(-)Ant Editor/org/eclipse/ant/internal/ui/editor/AntEditorSourceViewerConfiguration.java (-8 / +28 lines)
Lines 17-22 Link Here
17
17
18
import org.eclipse.ant.internal.ui.editor.derived.HTMLTextPresenter;
18
import org.eclipse.ant.internal.ui.editor.derived.HTMLTextPresenter;
19
import org.eclipse.ant.internal.ui.editor.formatter.ContentFormatter3;
19
import org.eclipse.ant.internal.ui.editor.formatter.ContentFormatter3;
20
import org.eclipse.ant.internal.ui.editor.formatter.FormattingPreferences;
21
import org.eclipse.ant.internal.ui.editor.formatter.XmlCommentFormattingStrategy;
20
import org.eclipse.ant.internal.ui.editor.formatter.XmlDocumentFormattingStrategy;
22
import org.eclipse.ant.internal.ui.editor.formatter.XmlDocumentFormattingStrategy;
21
import org.eclipse.ant.internal.ui.editor.formatter.XmlElementFormattingStrategy;
23
import org.eclipse.ant.internal.ui.editor.formatter.XmlElementFormattingStrategy;
22
import org.eclipse.ant.internal.ui.editor.text.AntEditorPartitionScanner;
24
import org.eclipse.ant.internal.ui.editor.text.AntEditorPartitionScanner;
Lines 266-283 Link Here
266
    /* (non-Javadoc)
268
    /* (non-Javadoc)
267
     * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getContentFormatter(org.eclipse.jface.text.source.ISourceViewer)
269
     * @see org.eclipse.jface.text.source.SourceViewerConfiguration#getContentFormatter(org.eclipse.jface.text.source.ISourceViewer)
268
     */
270
     */
269
    public IContentFormatter getContentFormatter(ISourceViewer sourceViewer) {
271
public IContentFormatter getContentFormatter(ISourceViewer sourceViewer) {
270
        
272
271
        ContentFormatter3 formatter = new ContentFormatter3();
273
        ContentFormatter3 formatter = new ContentFormatter3();
272
        formatter.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
274
        formatter.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
273
        
275
        
274
        IFormattingStrategy indentationStrategy = new XmlDocumentFormattingStrategy(sourceViewer);
276
        IFormattingStrategy indentationStrategy = new XmlDocumentFormattingStrategy(sourceViewer);        
275
        IFormattingStrategy elementFormattingStrategy = new XmlElementFormattingStrategy(sourceViewer);        
276
        
277
        formatter.setFormattingStrategy(indentationStrategy);
277
        formatter.setFormattingStrategy(indentationStrategy);
278
        formatter.setFormattingStrategy(indentationStrategy,IDocument.DEFAULT_CONTENT_TYPE);
278
        formatter.setFormattingStrategy(indentationStrategy,
279
        formatter.setFormattingStrategy(elementFormattingStrategy,AntEditorPartitionScanner.XML_TAG);
279
                IDocument.DEFAULT_CONTENT_TYPE);
280
        
280
281
        // TODO This approach would make the formatter fun much more quickly
282
        // if these options aren't used; however this won't really work
283
        // since the content formatter is probably configured only once at
284
        // the start up of the editor. In order to make this work I'd need to
285
        // listen to further changes from the preferences store and reconfigure
286
        // the editor appropriately.
287
        //        FormattingPreferences fp = new FormattingPreferences();
288
        //        if (fp.formatElements()) {
289
        IFormattingStrategy elementFormattingStrategy = new XmlElementFormattingStrategy(
290
                sourceViewer);
291
        formatter.setFormattingStrategy(elementFormattingStrategy,
292
                AntEditorPartitionScanner.XML_TAG);
293
        //        }
294
        //        if(fp.formatComments()){
295
        IFormattingStrategy commentFormattingStrategy = new XmlCommentFormattingStrategy(
296
                sourceViewer);
297
        formatter.setFormattingStrategy(commentFormattingStrategy,
298
                AntEditorPartitionScanner.XML_COMMENT);
299
        //        }
300
281
        return formatter;
301
        return formatter;
282
    }
302
    }
283
}
303
}
(-)Ant Editor/org/eclipse/ant/internal/ui/editor/formatter/FormattingPreferences.java (-1 / +22 lines)
Lines 41-44 Link Here
41
    public boolean useElementWrapping() {
41
    public boolean useElementWrapping() {
42
        return fPrefs.getBoolean(AntEditorPreferenceConstants.FORMATTER_WRAP_LONG);
42
        return fPrefs.getBoolean(AntEditorPreferenceConstants.FORMATTER_WRAP_LONG);
43
    }
43
    }
44
}
44
    
45
    public boolean alignElementCloseChar() {
46
        return fPrefs.getBoolean(AntEditorPreferenceConstants.FORMATTER_ALIGN);        
47
    }
48
49
    public boolean formatComments() {
50
        return fPrefs.getBoolean(AntEditorPreferenceConstants.FORMATTER_COMMENTS);
51
    }
52
    
53
    public boolean stripBlankLines() {
54
        return fPrefs.getBoolean(AntEditorPreferenceConstants.FORMATTER_DELETE_BLANK_LINES);
55
    }
56
57
    public boolean formatElements() {
58
        return fPrefs.getBoolean(AntEditorPreferenceConstants.FORMATTER_WRAP_LONG);
59
    }
60
61
	public int getTabWidth() {
62
		return fPrefs.getInt(AntEditorPreferenceConstants.FORMATTER_TAB_SIZE);
63
	}
64
}
65
(-)Ant Editor/org/eclipse/ant/internal/ui/editor/formatter/NonParsingXMLFormatter.java (-1 / +2 lines)
Lines 307-313 Link Here
307
                char c = (char) intChar;
307
                char c = (char) intChar;
308
308
309
                node.append(c);
309
                node.append(c);
310
310
                // TODO logic incorrectly assumes that " is quote character
311
                // when it could also be '
311
                if (c == '"') {
312
                if (c == '"') {
312
                    insideQuote = !insideQuote;
313
                    insideQuote = !insideQuote;
313
                }
314
                }
(-)Ant Editor/org/eclipse/ant/internal/ui/editor/formatter/XmlElementFormattingStrategy.java (-10 / +54 lines)
Lines 12-20 Link Here
12
12
13
package org.eclipse.ant.internal.ui.editor.formatter;
13
package org.eclipse.ant.internal.ui.editor.formatter;
14
14
15
import java.text.StringCharacterIterator;
15
import java.util.ArrayList;
16
import java.util.ArrayList;
16
import java.util.LinkedList;
17
import java.util.LinkedList;
17
import java.util.List;
18
import java.util.List;
19
import java.util.StringTokenizer;
18
20
19
import org.eclipse.jface.text.Assert;
21
import org.eclipse.jface.text.Assert;
20
import org.eclipse.jface.text.BadLocationException;
22
import org.eclipse.jface.text.BadLocationException;
Lines 38-43 Link Here
38
    /** The position sets to keep track of during formatting */
40
    /** The position sets to keep track of during formatting */
39
    private final LinkedList fPositions = new LinkedList();
41
    private final LinkedList fPositions = new LinkedList();
40
42
43
    /** access to the preferences store **/
44
    private final FormattingPreferences prefs = new FormattingPreferences();
45
    
41
    public XmlElementFormattingStrategy(ISourceViewer viewer) {
46
    public XmlElementFormattingStrategy(ISourceViewer viewer) {
42
        super(viewer);
47
        super(viewer);
43
    }
48
    }
Lines 57-63 Link Here
57
        IDocument document = getViewer().getDocument();
62
        IDocument document = getViewer().getDocument();
58
63
59
        try {
64
        try {
60
            FormattingPreferences prefs = new FormattingPreferences();
65
61
            String formatted = formatElement(document, partition, lineIndent, prefs);
66
            String formatted = formatElement(document, partition, lineIndent, prefs);
62
67
63
            String partitionText = document.get(partition.getOffset(), partition.getLength());
68
            String partitionText = document.get(partition.getOffset(), partition.getLength());
Lines 77-82 Link Here
77
        StringBuffer formattedElement = null;
82
        StringBuffer formattedElement = null;
78
83
79
        // do we even need to think about wrapping?
84
        // do we even need to think about wrapping?
85
        
86
		// TODO fix this. If wrapping is all that this stategy does, this is a
87
		// very inefficient mechanism for avoiding the element format since this
88
        // format method will be called for every tag partition in the document.
89
        // What is really needed is for the editor itself to listen for changes 
90
        // to the preferences and reconfigure the editor's formatter to ommit 
91
        // this strategy.
92
        
93
        // TODO Always parse and create a model for the element since we may 
94
        // want to undo the formatting of a previously formatted element when
95
        // the prefences change
96
80
        if (prefs.useElementWrapping() && !partitionText.startsWith("</")) { //$NON-NLS-1$
97
        if (prefs.useElementWrapping() && !partitionText.startsWith("</")) { //$NON-NLS-1$
81
98
82
            IRegion line = document.getLineInformationOfOffset(partition.getOffset());
99
            IRegion line = document.getLineInformationOfOffset(partition.getOffset());
Lines 84-90 Link Here
84
            int partitionLineOffset = partition.getOffset() - line.getOffset();
101
            int partitionLineOffset = partition.getOffset() - line.getOffset();
85
102
86
            // do we have a good candidate for a wrap?
103
            // do we have a good candidate for a wrap?
87
            if (line.getLength() > prefs.getMaximumLineWidth()) {
104
            // chars need to be expanded using the preferences value           
105
            int tabCount = count('\t', document.get(line.getOffset(), line.getLength()));
106
                        
107
            if ((line.getLength() - tabCount) + (tabCount * prefs.getTabWidth())  
108
            		> prefs.getMaximumLineWidth()) {
88
109
89
                List attributes = getAttributes(partitionText);
110
                List attributes = getAttributes(partitionText);
90
                if (attributes.size() > 1) {
111
                if (attributes.size() > 1) {
Lines 93-115 Link Here
93
                    formattedElement.append(startTag);
114
                    formattedElement.append(startTag);
94
                    formattedElement.append(' ');
115
                    formattedElement.append(' ');
95
                    formattedElement.append(attributes.get(0));
116
                    formattedElement.append(attributes.get(0));
96
                    formattedElement.append("\n"); //$NON-NLS-1$
117
                    
97
                    
118
                    
98
                    for (int i = 1; i < attributes.size(); i++) {
119
                    for (int i = 1; i < attributes.size(); i++) {
120
                    	formattedElement.append("\n"); //$NON-NLS-1$
99
                        formattedElement.append(indentation);
121
                        formattedElement.append(indentation);
100
                        for (int j = 0; j < (partitionLineOffset - indentation
122
                        for (int j = 0; j < (partitionLineOffset - indentation
101
                                .length())
123
                                .length())
102
                                + startTag.length() + 1; j++) {
124
                                + startTag.length() + 1; j++) {
103
                            formattedElement.append(' ');
125
                            formattedElement.append(' ');
104
                        }
126
                        }
105
                        formattedElement.append(attributes.get(i));
127
                        formattedElement.append(attributes.get(i));                        
106
                        formattedElement.append("\n"); //$NON-NLS-1$
107
                    }
108
                    formattedElement.append(indentation);
109
                    for (int j = 0; j < (partitionLineOffset - indentation
110
                            .length()) + 1; j++) {
111
                        formattedElement.append(' ');
112
                    }
128
                    }
129
                    
130
					if (prefs.alignElementCloseChar()) {
131
						formattedElement.append("\n"); //$NON-NLS-1$
132
						formattedElement.append(indentation);
133
						for (int j = 0; j < (partitionLineOffset - indentation
134
								.length()) + 1; j++) {
135
							formattedElement.append(' ');
136
						}			
137
					}
138
					
113
                    if (partitionText.endsWith("/>")) { //$NON-NLS-1$
139
                    if (partitionText.endsWith("/>")) { //$NON-NLS-1$
114
                        formattedElement.append("/>"); //$NON-NLS-1$
140
                        formattedElement.append("/>"); //$NON-NLS-1$
115
                    } else if (partitionText.endsWith(">")) { //$NON-NLS-1$
141
                    } else if (partitionText.endsWith(">")) { //$NON-NLS-1$
Lines 134-139 Link Here
134
        int quotes = 0;
160
        int quotes = 0;
135
        StringBuffer attributePair = new StringBuffer();
161
        StringBuffer attributePair = new StringBuffer();
136
162
163
        // TODO logic for inside quotes incorrectly assumes that the quote
164
        // character will be " when it could also be '.
137
        for (int i = start; i < text.length(); i++) {
165
        for (int i = start; i < text.length(); i++) {
138
            char c = text.charAt(i);
166
            char c = text.charAt(i);
139
            switch (c) {
167
            switch (c) {
Lines 209-212 Link Here
209
        fPartitions.clear();
237
        fPartitions.clear();
210
        fPositions.clear();
238
        fPositions.clear();
211
    }
239
    }
240
241
	private int count(char searchChar, String inTargetString) {
242
		StringCharacterIterator iter = new StringCharacterIterator(
243
				inTargetString);
244
		int i = 0;
245
		if(iter.first() == searchChar) i++;
246
		while (iter.getIndex() < iter.getEndIndex()) {			
247
			if (iter.next() == searchChar)
248
				i++;
249
		}
250
		return i;
251
	}
252
253
254
255
    
212
}
256
}
(-)Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntCodeFormatterPreferencePage.java (-6 / +5 lines)
Lines 81-86 Link Here
81
	
81
	
82
	private OverlayPreferenceStore createOverlayStore() {
82
	private OverlayPreferenceStore createOverlayStore() {
83
		List overlayKeys= new ArrayList();
83
		List overlayKeys= new ArrayList();
84
		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AntEditorPreferenceConstants.FORMATTER_WRAP_LONG));
84
		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AntEditorPreferenceConstants.FORMATTER_ALIGN));
85
		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AntEditorPreferenceConstants.FORMATTER_ALIGN));
85
		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AntEditorPreferenceConstants.FORMATTER_COMMENTS));
86
		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AntEditorPreferenceConstants.FORMATTER_COMMENTS));
86
		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AntEditorPreferenceConstants.FORMATTER_DELETE_BLANK_LINES));
87
		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AntEditorPreferenceConstants.FORMATTER_DELETE_BLANK_LINES));
Lines 88-93 Link Here
88
		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AntEditorPreferenceConstants.FORMATTER_TAB_CHAR));
89
		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, AntEditorPreferenceConstants.FORMATTER_TAB_CHAR));
89
		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.INT, AntEditorPreferenceConstants.FORMATTER_TAB_SIZE));
90
		overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.INT, AntEditorPreferenceConstants.FORMATTER_TAB_SIZE));
90
		
91
		
92
		
93
		
91
		OverlayPreferenceStore.OverlayKey[] keys= new OverlayPreferenceStore.OverlayKey[overlayKeys.size()];
94
		OverlayPreferenceStore.OverlayKey[] keys= new OverlayPreferenceStore.OverlayKey[overlayKeys.size()];
92
		overlayKeys.toArray(keys);
95
		overlayKeys.toArray(keys);
93
		return new OverlayPreferenceStore(getPreferenceStore(), keys);
96
		return new OverlayPreferenceStore(getPreferenceStore(), keys);
Lines 140-154 Link Here
140
		labelText= AntPreferencesMessages.getString("AntCodeFormatterPreferencePage.4"); //$NON-NLS-1$
143
		labelText= AntPreferencesMessages.getString("AntCodeFormatterPreferencePage.4"); //$NON-NLS-1$
141
		addCheckBox(indentationGroup, labelText, AntEditorPreferenceConstants.FORMATTER_TAB_CHAR, 1);
144
		addCheckBox(indentationGroup, labelText, AntEditorPreferenceConstants.FORMATTER_TAB_CHAR, 1);
142
		
145
		
143
		labelText= AntPreferencesMessages.getString("AntCodeFormatterPreferencePage.5"); //$NON-NLS-1$
144
		addCheckBox(indentationGroup, labelText, AntEditorPreferenceConstants.FORMATTER_ALIGN, 1);
145
		
146
		Group wrappingGroup= createGroup(numColumns, result, AntPreferencesMessages.getString("AntCodeFormatterPreferencePage.6")); //$NON-NLS-1$
146
		Group wrappingGroup= createGroup(numColumns, result, AntPreferencesMessages.getString("AntCodeFormatterPreferencePage.6")); //$NON-NLS-1$
147
		labelText= AntPreferencesMessages.getString("AntCodeFormatterPreferencePage.7"); //$NON-NLS-1$
147
		labelText= AntPreferencesMessages.getString("AntCodeFormatterPreferencePage.7"); //$NON-NLS-1$
148
		errorMessages= new String[]{AntPreferencesMessages.getString("AntCodeFormatterPreferencePage.8"), AntPreferencesMessages.getString("AntCodeFormatterPreferencePage.9")}; //$NON-NLS-1$ //$NON-NLS-2$
148
		errorMessages= new String[]{AntPreferencesMessages.getString("AntCodeFormatterPreferencePage.8"), AntPreferencesMessages.getString("AntCodeFormatterPreferencePage.9")}; //$NON-NLS-1$ //$NON-NLS-2$
149
		addTextField(wrappingGroup, labelText, AntEditorPreferenceConstants.FORMATTER_MAX_LINE_LENGTH, 3, 0, errorMessages);
149
		addTextField(wrappingGroup, labelText, AntEditorPreferenceConstants.FORMATTER_MAX_LINE_LENGTH, 3, 0, errorMessages);
150
		labelText= AntPreferencesMessages.getString("AntCodeFormatterPreferencePage.10"); //$NON-NLS-1$
150
		labelText= AntPreferencesMessages.getString("AntCodeFormatterPreferencePage.10"); //$NON-NLS-1$
151
		addCheckBox(wrappingGroup, labelText, AntEditorPreferenceConstants.FORMATTER_WRAP_LONG, 1);
151
		addCheckBox(wrappingGroup, labelText, AntEditorPreferenceConstants.FORMATTER_WRAP_LONG, 1);
152
		labelText= AntPreferencesMessages.getString("AntCodeFormatterPreferencePage.5"); //$NON-NLS-1$
153
		addCheckBox(wrappingGroup, labelText, AntEditorPreferenceConstants.FORMATTER_ALIGN, 1);
152
		
154
		
153
		Group whiteSpaceGroup= createGroup(numColumns, result, AntPreferencesMessages.getString("AntCodeFormatterPreferencePage.11")); //$NON-NLS-1$
155
		Group whiteSpaceGroup= createGroup(numColumns, result, AntPreferencesMessages.getString("AntCodeFormatterPreferencePage.11")); //$NON-NLS-1$
154
		labelText= AntPreferencesMessages.getString("AntCodeFormatterPreferencePage.12"); //$NON-NLS-1$
156
		labelText= AntPreferencesMessages.getString("AntCodeFormatterPreferencePage.12"); //$NON-NLS-1$
Lines 227-235 Link Here
227
		return group;
229
		return group;
228
	}
230
	}
229
231
230
	/* (non-Javadoc)
231
	 * @see org.eclipse.jface.preference.PreferencePage#performDefaults()
232
	 */
233
	/* (non-Javadoc)
232
	/* (non-Javadoc)
234
	 * @see org.eclipse.jface.preference.PreferencePage#performDefaults()
233
	 * @see org.eclipse.jface.preference.PreferencePage#performDefaults()
235
	 */
234
	 */
(-)Ant Tools Support/org/eclipse/ant/internal/ui/preferences/AntPreferencesMessages.properties (-1 / +1 lines)
Lines 151-157 Link Here
151
AntCodeFormatterPreferencePage.1=Tab si&ze:
151
AntCodeFormatterPreferencePage.1=Tab si&ze:
152
AntCodeFormatterPreferencePage.2=No tab size specified
152
AntCodeFormatterPreferencePage.2=No tab size specified
153
AntCodeFormatterPreferencePage.3=Invalid tab size specified
153
AntCodeFormatterPreferencePage.3=Invalid tab size specified
154
AntCodeFormatterPreferencePage.4=U&se tab charater
154
AntCodeFormatterPreferencePage.4=U&se tab charater instead of spaces
155
AntCodeFormatterPreferencePage.5=Ali&gn final '>' in multi-line element tags
155
AntCodeFormatterPreferencePage.5=Ali&gn final '>' in multi-line element tags
156
AntCodeFormatterPreferencePage.6=Line Wrapping
156
AntCodeFormatterPreferencePage.6=Line Wrapping
157
AntCodeFormatterPreferencePage.7=Ma&ximum line width:
157
AntCodeFormatterPreferencePage.7=Ma&ximum line width:
(-)Ant (+289 lines)
Added Link Here
1
/*
2
 * Created on Feb 5, 2004
3
 *
4
 * To change the template for this generated file go to
5
 * Window - Preferences - Java - Code Generation - Code and Comments
6
 */
7
package org.eclipse.ant.internal.ui.editor.formatter;
8
9
import java.util.Arrays;
10
import java.util.LinkedList;
11
12
import org.eclipse.jface.text.BadLocationException;
13
import org.eclipse.jface.text.IDocument;
14
import org.eclipse.jface.text.Position;
15
import org.eclipse.jface.text.formatter.ContextBasedFormattingStrategy;
16
import org.eclipse.jface.text.formatter.FormattingContext;
17
import org.eclipse.jface.text.formatter.FormattingContextProperties;
18
import org.eclipse.jface.text.formatter.IFormattingContext;
19
import org.eclipse.jface.text.source.ISourceViewer;
20
import org.eclipse.jface.util.Assert;
21
22
/**
23
 * @author shacjo
24
 * 
25
 * To change the template for this generated type comment go to Window -
26
 * Preferences - Java - Code Generation - Code and Comments
27
 */
28
public class XmlCommentFormattingStrategy extends
29
        ContextBasedFormattingStrategy {
30
31
    /**
32
     */
33
    private static class CommentPartitionDecorator {
34
35
        public static CommentPartitionDecorator decorate(IDocument document,
36
                Position partition) {
37
            return new CommentPartitionDecorator(document, partition);
38
        }
39
40
        private IDocument document;
41
42
        private Position partition;
43
44
        /**
45
         * @param document
46
         * @param partition
47
         */
48
        public CommentPartitionDecorator(IDocument document, Position partition) {
49
        }
50
51
        /**
52
         * @param p1
53
         *            the partition with the low offset
54
         * @param p2
55
         *            the partition with the high offset
56
         * @return true of both partitions are to be formatted as a single unit
57
         */
58
        private boolean formatTogether(Position p1, Position p2)
59
                throws BadLocationException {
60
61
            Assert.isTrue(p1.offset < p2.offset);
62
            String interveningText = textBetween(p1, p2);
63
64
            if (interveningText.trim().length() == 0
65
                    && interveningText.indexOf('\n') == -1
66
                    && interveningText.indexOf('\r') == -1) {
67
                return true;
68
            } else {
69
                return false;
70
            }
71
        }
72
73
        public boolean formatWith(Position partition)
74
                throws BadLocationException {
75
76
            Assert.isNotNull(this.document);
77
            Assert.isNotNull(this.partition);
78
79
            if (this.partition.offset < partition.offset) {
80
                return formatTogether(this.partition, partition);
81
            } else if (this.partition.offset > partition.offset) {
82
                return formatTogether(partition, this.partition);
83
            } else {
84
                // I wouldn't expect both partitions to
85
                // start at the same spot.
86
                return false;
87
            }
88
        }
89
90
        /**
91
         * @return {@link Position#getLength()}
92
         */
93
        public int getLength() {
94
            return partition.getLength();
95
        }
96
97
        /**
98
         * @return {@link Position#getOffset()}
99
         */
100
        public int getOffset() {
101
            return partition.getOffset();
102
        }
103
104
        public String getText() throws BadLocationException {
105
            return textOf(this.partition);
106
        }
107
108
        /**
109
         * @param string
110
         */
111
        public void replaceWith(String text) throws BadLocationException {
112
113
            if (text != null && !text.equals(this.getText()))
114
                    document.replace(this.getOffset(), this.getLength(), text);
115
116
        }
117
118
        /**
119
         * @param p1
120
         *            the partition with the low offset
121
         * @param p2
122
         *            the partition with the high offset
123
         * @return text between the end of the first positions and start of the
124
         *         second
125
         */
126
        private String textBetween(Position p1, Position p2)
127
                throws BadLocationException {
128
            return document.get(p1.offset + p1.length, p2.offset
129
                    - (p1.offset + p1.length));
130
        }
131
132
        private String textOf(Position partition) throws BadLocationException {
133
            return this.document.get(partition.offset, partition.length);
134
        }
135
    }
136
137
    /**
138
     */
139
    private abstract static class Normalizer {
140
141
        abstract protected boolean isApplicableFor(String commentText);
142
143
        abstract protected String normalize(String commentText);
144
145
        public String safelyNormalize(String commentText) {
146
            if (isApplicableFor(commentText))
147
                return normalize(commentText);
148
            else
149
                return commentText;
150
        }
151
    }
152
153
    private static class SeparartorCommentNormalizer extends Normalizer {
154
155
        /*
156
         * (non-Javadoc)
157
         * 
158
         * @see org.eclipse.ant.internal.ui.editor.format.XmlCommentFormattingStrategy.Normalizer#isApplicableFor(java.lang.String)
159
         */
160
        protected boolean isApplicableFor(String commentText) {
161
            // TODO Auto-generated method stub
162
            return false;
163
        }
164
165
        /*
166
         * (non-Javadoc)
167
         * 
168
         * @see org.eclipse.ant.internal.ui.editor.format.XmlCommentFormattingStrategy.Normalizer#normalize(java.lang.String)
169
         */
170
        protected String normalize(String commentText) {
171
            // TODO Auto-generated method stub
172
            return null;
173
        }
174
    }
175
176
    private class TextCommentNormalizer extends Normalizer {
177
178
        private String actualText(String comment) {
179
            return comment.substring(4, comment.length() - 3).trim();
180
        }
181
182
        /*
183
         * (non-Javadoc)
184
         * 
185
         * @see org.eclipse.ant.internal.ui.editor.format.XmlCommentFormattingStrategy.Normalizer#isApplicableFor(java.lang.String)
186
         */
187
        protected boolean isApplicableFor(String commentText) {
188
189
            return Character.isLetterOrDigit(actualText(commentText).charAt(0))
190
                    && commentText.indexOf('\n') == -1
191
                    && commentText.indexOf('\r') == -1;
192
        }
193
194
        /*
195
         * (non-Javadoc)
196
         * 
197
         * @see org.eclipse.ant.internal.ui.editor.format.XmlCommentFormattingStrategy.Normalizer#normalize(java.lang.String)
198
         */
199
        protected String normalize(String comment) {
200
201
            String text = comment.substring(4, comment.length() - 3).trim();
202
            
203
            // TODO assumes text length < fCommentWidth which isn't necessarily the case
204
            char[] whitespace = new char[fCommentWidth - (text.length() + 7)];
205
            Arrays.fill(whitespace,' ');
206
207
            return "<!-- " + actualText(comment) + String.valueOf(whitespace)
208
                    + "-->";
209
        }
210
    }
211
212
	private final int fCommentWidth = 40; 
213
214
    /** Indentations to use by this strategy */
215
    private final LinkedList fIndentations;
216
217
    /** Normalizers for handling partition formatting */
218
    private final Normalizer[] fNormalizers;
219
220
    /** Partitions to be formatted by this strategy */
221
    private final LinkedList fPartitions;
222
223
    /**
224
     * @param viewer
225
     */
226
    public XmlCommentFormattingStrategy(ISourceViewer viewer) {
227
        super(viewer);
228
        fIndentations = new LinkedList();
229
        fPartitions = new LinkedList();
230
        fNormalizers = new Normalizer[] {};
231
    }
232
233
    /*
234
     * (non-Javadoc)
235
     * 
236
     * @see org.eclipse.jface.text.formatter.IFormattingStrategyExtension#format()
237
     */
238
    public void format() {
239
        super.format();
240
        Assert.isLegal(fPartitions.size() > 0);
241
        Assert.isLegal(fIndentations.size() > 0);
242
243
        final String indent = fIndentations.removeFirst().toString();
244
        final CommentPartitionDecorator partition = (CommentPartitionDecorator) fPartitions
245
                .removeFirst();
246
247
        // normalize length
248
        // normalize char pattern
249
        // format text
250
        // normalize
251
252
        try {
253
254
            for (int i = 0; i < fNormalizers.length; i++) {
255
                partition.replaceWith(fNormalizers[i].safelyNormalize(partition
256
                        .getText()));
257
            }
258
259
        } catch (BadLocationException e) {
260
            // TODO Auto-generated catch block
261
            e.printStackTrace();
262
        }
263
264
    }
265
266
    /*
267
     * @see org.eclipse.jface.text.formatter.ContextBasedFormattingStrategy#formatterStarts(org.eclipse.jface.text.formatter.IFormattingContext)
268
     */
269
    public void formatterStarts(IFormattingContext context) {
270
        super.formatterStarts(context);
271
272
        final FormattingContext current = (FormattingContext) context;
273
        fIndentations.addLast(current
274
                .getProperty(FormattingContextProperties.CONTEXT_INDENTATION));
275
276
        fPartitions.addLast(CommentPartitionDecorator.decorate(this.getViewer()
277
                .getDocument(), (Position) current
278
                .getProperty(FormattingContextProperties.CONTEXT_PARTITION)));
279
    }
280
281
    /*
282
     * @see org.eclipse.jface.text.formatter.ContextBasedFormattingStrategy#formatterStops()
283
     */
284
    public void formatterStops() {
285
        super.formatterStops();
286
        fIndentations.clear();
287
        fPartitions.clear();
288
    }
289
}

Return to bug 40255