Link Here
|
16 |
import java.util.List; |
16 |
import java.util.List; |
17 |
import java.util.ResourceBundle; |
17 |
import java.util.ResourceBundle; |
18 |
|
18 |
|
19 |
import org.eclipse.core.runtime.Assert; |
|
|
20 |
import org.eclipse.jface.text.BadLocationException; |
19 |
import org.eclipse.jface.text.BadLocationException; |
21 |
import org.eclipse.jface.text.BadPartitioningException; |
20 |
import org.eclipse.jface.text.BadPartitioningException; |
22 |
import org.eclipse.jface.text.IDocument; |
21 |
import org.eclipse.jface.text.IDocument; |
23 |
import org.eclipse.jface.text.IDocumentExtension3; |
22 |
import org.eclipse.jface.text.IDocumentExtension3; |
|
|
23 |
import org.eclipse.jface.text.IRegion; |
24 |
import org.eclipse.jface.text.ITextSelection; |
24 |
import org.eclipse.jface.text.ITextSelection; |
25 |
import org.eclipse.jface.text.ITypedRegion; |
25 |
import org.eclipse.jface.text.ITypedRegion; |
|
|
26 |
import org.eclipse.jface.text.Region; |
26 |
import org.eclipse.ui.texteditor.ITextEditor; |
27 |
import org.eclipse.ui.texteditor.ITextEditor; |
27 |
|
28 |
|
28 |
import org.eclipse.cdt.ui.text.ICPartitions; |
29 |
import org.eclipse.cdt.ui.text.ICPartitions; |
29 |
|
30 |
|
30 |
/** |
31 |
/** |
31 |
* Action that encloses the editor's current selection with Java block comment terminators |
32 |
* Action that encloses the editor's current selection with Java/C block comment terminators |
32 |
* (<code>/*</code> and <code>*/</code>). |
33 |
* (<code>/*</code> and <code>*/</code>). |
33 |
* |
34 |
* |
34 |
* @since 3.0 |
35 |
* @since 3.0 |
Link Here
|
51 |
* @see org.eclipse.jdt.internal.ui.actions.BlockCommentAction#runInternal(org.eclipse.jface.text.ITextSelection, org.eclipse.jface.text.IDocumentExtension3, org.eclipse.jdt.internal.ui.actions.BlockCommentAction.Edit.EditFactory) |
52 |
* @see org.eclipse.jdt.internal.ui.actions.BlockCommentAction#runInternal(org.eclipse.jface.text.ITextSelection, org.eclipse.jface.text.IDocumentExtension3, org.eclipse.jdt.internal.ui.actions.BlockCommentAction.Edit.EditFactory) |
52 |
*/ |
53 |
*/ |
53 |
@Override |
54 |
@Override |
54 |
protected void runInternal(ITextSelection selection, IDocumentExtension3 docExtension, Edit.EditFactory factory) throws BadLocationException, BadPartitioningException { |
55 |
protected void runInternal(ITextSelection selection, |
55 |
int selectionOffset= selection.getOffset(); |
56 |
IDocumentExtension3 docExtension, Edit.EditFactory factory) |
56 |
int selectionEndOffset= selectionOffset + selection.getLength(); |
57 |
throws BadLocationException, BadPartitioningException { |
|
|
58 |
|
59 |
if ( !(docExtension instanceof IDocument) ) return; |
60 |
|
57 |
List<Edit> edits= new LinkedList<Edit>(); |
61 |
List<Edit> edits= new LinkedList<Edit>(); |
58 |
ITypedRegion partition= docExtension.getPartition(ICPartitions.C_PARTITIONING, selectionOffset, false); |
|
|
59 |
|
60 |
handleFirstPartition(partition, edits, factory, selectionOffset); |
61 |
|
62 |
|
62 |
while (partition.getOffset() + partition.getLength() < selectionEndOffset) { |
63 |
ITypedRegion firstPartition = docExtension.getPartition(ICPartitions.C_PARTITIONING, |
63 |
partition= handleInteriorPartition(partition, edits, factory, docExtension); |
64 |
selection.getOffset(), false); |
|
|
65 |
ITypedRegion lastPartition = docExtension.getPartition(ICPartitions.C_PARTITIONING, |
66 |
selection.getOffset() + selection.getLength() - 1, false); |
67 |
|
68 |
int commentAreaStart = selection.getOffset(); |
69 |
int commentAreaEnd = selection.getOffset()+selection.getLength(); |
70 |
// Include special partitions fully in the comment area |
71 |
if (isSpecialPartition(firstPartition.getType())) { |
72 |
commentAreaStart = firstPartition.getOffset(); |
64 |
} |
73 |
} |
|
|
74 |
if (isSpecialPartition(lastPartition.getType())) { |
75 |
commentAreaEnd = lastPartition.getOffset() + lastPartition.getLength(); |
76 |
} |
77 |
Region estimatedCommentArea = new Region(commentAreaStart,commentAreaEnd-commentAreaStart); |
78 |
|
65 |
|
79 |
|
66 |
handleLastPartition(partition, edits, factory, selectionEndOffset); |
80 |
Region commentArea = handleEnclosingPartitions(estimatedCommentArea, lastPartition, |
|
|
81 |
(IDocument)docExtension, factory, edits); |
82 |
|
83 |
handleInteriorPartition(commentArea, firstPartition, docExtension, factory, edits); |
67 |
|
84 |
|
68 |
executeEdits(edits); |
85 |
executeEdits(edits); |
69 |
} |
86 |
} |
70 |
|
87 |
|
71 |
/** |
88 |
/** |
72 |
* Handle the first partition of the selected text. |
89 |
* Add enclosing comment tags for the whole area to be commented |
73 |
* |
90 |
* |
74 |
* @param partition |
91 |
* @param commentArea initial comment area which can be adjusted |
75 |
* @param edits |
92 |
* @param lastPartition last partition |
76 |
* @param factory |
93 |
* @param doc document |
77 |
* @param offset |
94 |
* @param factory Edit factory |
78 |
*/ |
95 |
* @param edits List of edits to update the document |
79 |
private void handleFirstPartition(ITypedRegion partition, List<Edit> edits, Edit.EditFactory factory, int offset) throws BadLocationException { |
96 |
* @return new possibly adjusted comment area |
80 |
|
97 |
* @throws BadLocationException |
81 |
int partOffset= partition.getOffset(); |
98 |
*/ |
82 |
String partType= partition.getType(); |
99 |
private Region handleEnclosingPartitions(Region commentArea, |
83 |
|
100 |
ITypedRegion lastPartition, IDocument doc, Edit.EditFactory factory, |
84 |
Assert.isTrue(partOffset <= offset, "illegal partition"); //$NON-NLS-1$ |
101 |
List<Edit> edits) throws BadLocationException { |
85 |
|
102 |
|
86 |
// first partition: mark start of comment |
103 |
int commentAreaStart = commentArea.getOffset(); |
87 |
if (partType == IDocument.DEFAULT_CONTENT_TYPE) { |
104 |
int commentAreaEnd = commentArea.getOffset() + commentArea.getLength(); |
88 |
// Java code: right where selection starts |
105 |
|
89 |
edits.add(factory.createEdit(offset, 0, getCommentStart())); |
106 |
String commentStartTag = getCommentStart(); // "/*" |
90 |
} else if (isSpecialPartition(partType)) { |
107 |
String commentEndTag = getCommentEnd(); // "*/" |
91 |
// special types: include the entire partition |
108 |
|
92 |
edits.add(factory.createEdit(partOffset, 0, getCommentStart())); |
109 |
String startLineEOL = doc.getLineDelimiter(doc.getLineOfOffset(commentAreaStart)); |
93 |
} // javadoc: no mark, will only start after comment |
110 |
if (startLineEOL==null) startLineEOL=""; //$NON-NLS-1$ |
|
|
111 |
String endLineEOL = doc.getLineDelimiter(doc.getLineOfOffset(commentAreaEnd-1)); |
112 |
if (endLineEOL==null) endLineEOL=""; //$NON-NLS-1$ |
113 |
|
114 |
boolean isLeftEol = commentAreaStart<startLineEOL.length() |
115 |
|| doc.get(commentAreaStart-startLineEOL.length(),startLineEOL.length()).equals(startLineEOL); |
116 |
boolean isRightEol = doc.get(commentAreaEnd-endLineEOL.length(),endLineEOL.length()).equals(endLineEOL); |
117 |
|
118 |
if (isLeftEol && isRightEol) { |
119 |
// Block of full lines found |
120 |
int areaStartLine = doc.getLineOfOffset(commentAreaStart+startLineEOL.length()); |
121 |
int areaEndLine = doc.getLineOfOffset(commentAreaEnd-endLineEOL.length()); |
122 |
if (areaStartLine!=areaEndLine) { |
123 |
// If multiple full lines arrange inserting comment tags on their own lines |
124 |
commentStartTag = getCommentStart()+startLineEOL; |
125 |
commentEndTag = getCommentEnd()+endLineEOL; |
126 |
} else { |
127 |
// If one full line insert end comment tag on the same line (before the EOL) |
128 |
commentAreaEnd = commentAreaEnd-endLineEOL.length(); |
129 |
} |
130 |
} else { |
131 |
if (lastPartition.getType()==ICPartitions.C_SINGLE_LINE_COMMENT) { |
132 |
// C++ comments "//" partition ends with EOL, insert end comment tag before it |
133 |
// on the same line, so we get something like /*// text*/ |
134 |
commentAreaEnd = commentAreaEnd-endLineEOL.length(); |
135 |
} |
136 |
} |
137 |
|
138 |
edits.add(factory.createEdit(commentAreaStart, 0, commentStartTag)); |
139 |
edits.add(factory.createEdit(commentAreaEnd, 0, commentEndTag)); |
94 |
|
140 |
|
|
|
141 |
return new Region(commentAreaStart,commentAreaEnd-commentAreaStart); |
95 |
} |
142 |
} |
96 |
|
143 |
|
97 |
/** |
144 |
/** |
98 |
* Handles the end of the given partition and the start of the next partition, which is returned. |
145 |
* Make all inside partitions join in one comment, in particular remove |
|
|
146 |
* all enclosing comment tokens of the inside partitions. |
99 |
* |
147 |
* |
100 |
* @param partition |
148 |
* @param commentArea comment area region |
101 |
* @param edits |
149 |
* @param partition first partition |
102 |
* @param factory |
150 |
* @param docExtension document |
103 |
* @param docExtension |
151 |
* @param factory EditFactory |
|
|
152 |
* @param List of edits to update the document |
104 |
* @throws BadLocationException |
153 |
* @throws BadLocationException |
105 |
* @throws BadPartitioningException |
154 |
* @throws BadPartitioningException |
106 |
* @return the region |
|
|
107 |
*/ |
155 |
*/ |
108 |
private ITypedRegion handleInteriorPartition(ITypedRegion partition, List<Edit> edits, Edit.EditFactory factory, IDocumentExtension3 docExtension) throws BadPartitioningException, BadLocationException { |
156 |
private void handleInteriorPartition(IRegion commentArea, |
109 |
|
157 |
ITypedRegion partition, IDocumentExtension3 docExtension, |
110 |
// end of previous partition |
158 |
Edit.EditFactory factory, List<Edit> edits) |
111 |
String partType= partition.getType(); |
159 |
throws BadLocationException, BadPartitioningException { |
112 |
int partEndOffset= partition.getOffset() + partition.getLength(); |
160 |
|
113 |
int tokenLength= getCommentStart().length(); |
161 |
int commentAreaEnd = commentArea.getOffset() + commentArea.getLength(); |
114 |
|
162 |
int prevPartitionEnd = -1; |
115 |
if (partType == ICPartitions.C_MULTI_LINE_COMMENT) { |
163 |
int partitionEnd = partition.getOffset()+partition.getLength(); |
116 |
// already in a comment - remove ending mark |
164 |
|
117 |
edits.add(factory.createEdit(partEndOffset - tokenLength, tokenLength, "")); //$NON-NLS-1$ |
165 |
final int startCommentTokenLength = getCommentStart().length(); |
118 |
} |
166 |
final int endCommentTokenLength = getCommentEnd().length(); |
119 |
|
167 |
|
120 |
// advance to next partition |
168 |
while (partitionEnd<=commentAreaEnd) { |
121 |
partition= docExtension.getPartition(ICPartitions.C_PARTITIONING, partEndOffset, false); |
169 |
if (partition.getType() == ICPartitions.C_MULTI_LINE_COMMENT) { |
122 |
partType= partition.getType(); |
170 |
// already in a comment - remove start/end tokens |
123 |
|
171 |
edits.add(factory.createEdit(partition.getOffset(), startCommentTokenLength, "")); //$NON-NLS-1$ |
124 |
// start of next partition |
172 |
edits.add(factory.createEdit(partitionEnd - endCommentTokenLength, endCommentTokenLength, "")); //$NON-NLS-1$ |
125 |
if (partType == ICPartitions.C_MULTI_LINE_COMMENT) { |
173 |
} |
126 |
// already in a comment - remove startToken |
174 |
// advance to next partition |
127 |
edits.add(factory.createEdit(partition.getOffset(), getCommentStart().length(), "")); //$NON-NLS-1$ |
175 |
prevPartitionEnd = partitionEnd; |
|
|
176 |
partition= docExtension.getPartition(ICPartitions.C_PARTITIONING, partitionEnd, false); |
177 |
partitionEnd = partition.getOffset() + partition.getLength(); |
178 |
|
179 |
// break the loop if we get stuck and no advance was made |
180 |
if (partitionEnd<=prevPartitionEnd) break; |
128 |
} |
181 |
} |
129 |
return partition; |
|
|
130 |
} |
131 |
|
132 |
/** |
133 |
* Handles the end of the last partition. |
134 |
* |
135 |
* @param partition |
136 |
* @param edits |
137 |
* @param factory |
138 |
* @param endOffset |
139 |
*/ |
140 |
private void handleLastPartition(ITypedRegion partition, List<Edit> edits, Edit.EditFactory factory, int endOffset) throws BadLocationException { |
141 |
|
142 |
String partType= partition.getType(); |
143 |
|
144 |
if (partType == IDocument.DEFAULT_CONTENT_TYPE) { |
145 |
// normal java: end comment where selection ends |
146 |
edits.add(factory.createEdit(endOffset, 0, getCommentEnd())); |
147 |
} else if (isSpecialPartition(partType)) { |
148 |
// special types: consume entire partition |
149 |
edits.add(factory.createEdit(partition.getOffset() + partition.getLength(), 0, getCommentEnd())); |
150 |
} |
151 |
|
152 |
} |
182 |
} |
153 |
|
183 |
|
154 |
/** |
184 |
/** |
Link Here
|
162 |
return partType == ICPartitions.C_CHARACTER |
192 |
return partType == ICPartitions.C_CHARACTER |
163 |
|| partType == ICPartitions.C_STRING |
193 |
|| partType == ICPartitions.C_STRING |
164 |
|| partType == ICPartitions.C_SINGLE_LINE_COMMENT |
194 |
|| partType == ICPartitions.C_SINGLE_LINE_COMMENT |
|
|
195 |
|| partType == ICPartitions.C_MULTI_LINE_COMMENT |
165 |
|| partType == ICPartitions.C_PREPROCESSOR; |
196 |
|| partType == ICPartitions.C_PREPROCESSOR; |
166 |
} |
197 |
} |
167 |
|
198 |
|