11package processing .app .syntax ;
22
3+ import org .fife .ui .rsyntaxtextarea .RSyntaxDocument ;
34import org .fife .ui .rsyntaxtextarea .RSyntaxTextAreaEditorKit ;
45import org .fife .ui .rtextarea .RTextArea ;
56import org .fife .ui .rtextarea .RecordableTextAction ;
@@ -16,7 +17,8 @@ public class SketchTextAreaEditorKit extends RSyntaxTextAreaEditorKit {
1617 private static final Action [] defaultActions = {
1718 new DeleteNextWordAction (),
1819 new DeleteLineToCursorAction (),
19- new SelectWholeLineAction ()
20+ new SelectWholeLineAction (),
21+ new ToggleCommentAction ()
2022 };
2123
2224 @ Override
@@ -126,4 +128,103 @@ public final String getMacroID() {
126128
127129 }
128130
131+ public static class ToggleCommentAction extends RecordableTextAction {
132+
133+ public ToggleCommentAction () {
134+ super (rstaToggleCommentAction );
135+ }
136+
137+ @ Override
138+ public void actionPerformedImpl (ActionEvent e , RTextArea textArea ) {
139+
140+ if (!textArea .isEditable () || !textArea .isEnabled ()) {
141+ UIManager .getLookAndFeel ().provideErrorFeedback (textArea );
142+ return ;
143+ }
144+
145+ RSyntaxDocument doc = (RSyntaxDocument ) textArea .getDocument ();
146+ Element map = doc .getDefaultRootElement ();
147+ Caret c = textArea .getCaret ();
148+ int dot = c .getDot ();
149+ int mark = c .getMark ();
150+ int line1 = map .getElementIndex (dot );
151+ int line2 = map .getElementIndex (mark );
152+ int start = Math .min (line1 , line2 );
153+ int end = Math .max (line1 , line2 );
154+
155+ org .fife .ui .rsyntaxtextarea .Token t = doc .getTokenListForLine (start );
156+ int languageIndex = t != null ? t .getLanguageIndex () : 0 ;
157+ String [] startEnd = doc .getLineCommentStartAndEnd (languageIndex );
158+
159+ if (startEnd == null ) {
160+ UIManager .getLookAndFeel ().provideErrorFeedback (textArea );
161+ return ;
162+ }
163+
164+ // Don't toggle comment on last line if there is no
165+ // text selected on it.
166+ if (start != end ) {
167+ Element elem = map .getElement (end );
168+ if (Math .max (dot , mark ) == elem .getStartOffset ()) {
169+ end --;
170+ }
171+ }
172+
173+ textArea .beginAtomicEdit ();
174+ try {
175+ boolean add = getDoAdd (doc , map , start , end , startEnd );
176+ for (line1 = start ; line1 <= end ; line1 ++) {
177+ Element elem = map .getElement (line1 );
178+ handleToggleComment (elem , doc , startEnd , add );
179+ }
180+ } catch (BadLocationException ble ) {
181+ ble .printStackTrace ();
182+ UIManager .getLookAndFeel ().provideErrorFeedback (textArea );
183+ } finally {
184+ textArea .endAtomicEdit ();
185+ }
186+
187+ }
188+
189+ private boolean getDoAdd (Document doc , Element map , int startLine , int endLine , String [] startEnd ) throws BadLocationException {
190+ boolean doAdd = false ;
191+ for (int i = startLine ; i <= endLine ; i ++) {
192+ Element elem = map .getElement (i );
193+ int start = elem .getStartOffset ();
194+ String t = doc .getText (start , elem .getEndOffset () - start - 1 ).trim ();
195+ if (!t .startsWith (startEnd [0 ]) ||
196+ (startEnd [1 ] != null && !t .endsWith (startEnd [1 ]))) {
197+ doAdd = true ;
198+ break ;
199+ }
200+ }
201+ return doAdd ;
202+ }
203+
204+ private void handleToggleComment (Element elem , Document doc , String [] startEnd , boolean add ) throws BadLocationException {
205+ int start = elem .getStartOffset ();
206+ int end = elem .getEndOffset () - 1 ;
207+ if (add ) {
208+ doc .insertString (start , startEnd [0 ], null );
209+ if (startEnd [1 ] != null ) {
210+ doc .insertString (end + startEnd [0 ].length (), startEnd [1 ], null );
211+ }
212+ } else {
213+ String text = doc .getText (start , elem .getEndOffset () - start - 1 );
214+ start += text .indexOf (startEnd [0 ]);
215+ doc .remove (start , startEnd [0 ].length ());
216+ if (startEnd [1 ] != null ) {
217+ int temp = startEnd [1 ].length ();
218+ doc .remove (end - startEnd [0 ].length () - temp , temp );
219+ }
220+ }
221+ }
222+
223+ @ Override
224+ public final String getMacroID () {
225+ return rstaToggleCommentAction ;
226+ }
227+
228+ }
229+
129230}
0 commit comments