Skip to content

Commit 765519a

Browse files
author
Federico Fissore
committed
New editor: ALT+ BACKSPACE deletes next word (OSX only). See #3098
1 parent 91da999 commit 765519a

File tree

4 files changed

+127
-32
lines changed

4 files changed

+127
-32
lines changed

app/src/processing/app/syntax/SketchTextArea.java

+35-32
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@
3535
import org.fife.ui.rsyntaxtextarea.Token;
3636
import org.fife.ui.rsyntaxtextarea.focusabletip.FocusableTip;
3737
import org.fife.ui.rtextarea.RTextArea;
38+
import org.fife.ui.rtextarea.RTextAreaUI;
3839
import org.fife.ui.rtextarea.RUndoManager;
39-
4040
import processing.app.*;
4141

4242
import javax.swing.*;
@@ -47,7 +47,6 @@
4747
import javax.swing.text.Document;
4848
import javax.swing.text.Segment;
4949
import javax.swing.undo.UndoManager;
50-
5150
import java.awt.*;
5251
import java.awt.event.KeyEvent;
5352
import java.awt.event.MouseEvent;
@@ -242,7 +241,7 @@ protected JPopupMenu createPopupMenu() {
242241
protected void configurePopupMenu(JPopupMenu popupMenu) {
243242
super.configurePopupMenu(popupMenu);
244243
}
245-
244+
246245
@Override
247246
protected RTAMouseListener createMouseListener() {
248247
return new SketchTextAreaMouseListener(this);
@@ -315,8 +314,8 @@ public HyperlinkEvent execute() {
315314
return null;
316315
}
317316
}
318-
319-
317+
318+
320319
/**
321320
* Handles http hyperlinks.
322321
* NOTE (@Ricardo JL Rufino): Workaround to enable hyperlinks by default: https://github.com/bobbylight/RSyntaxTextArea/issues/119
@@ -326,12 +325,12 @@ private class SketchTextAreaMouseListener extends RTextAreaMutableCaretEvent {
326325
private Insets insets;
327326
private boolean isScanningForLinks;
328327
private int hoveredOverLinkOffset = -1;
329-
328+
330329
protected SketchTextAreaMouseListener(RTextArea textArea) {
331330
super(textArea);
332331
insets = new Insets(0, 0, 0, 0);
333332
}
334-
333+
335334
/**
336335
* Notifies all listeners that have registered interest for notification
337336
* on this event type. The listener list is processed last to first.
@@ -344,22 +343,22 @@ private void fireHyperlinkUpdate(HyperlinkEvent e) {
344343
Object[] listeners = listenerList.getListenerList();
345344
// Process the listeners last to first, notifying
346345
// those that are interested in this event
347-
for (int i = listeners.length-2; i>=0; i-=2) {
348-
if (listeners[i]==HyperlinkListener.class) {
349-
((HyperlinkListener)listeners[i+1]).hyperlinkUpdate(e);
350-
}
346+
for (int i = listeners.length - 2; i >= 0; i -= 2) {
347+
if (listeners[i] == HyperlinkListener.class) {
348+
((HyperlinkListener) listeners[i + 1]).hyperlinkUpdate(e);
349+
}
351350
}
352351
}
353-
352+
354353
private HyperlinkEvent createHyperlinkEvent(MouseEvent e) {
355354
HyperlinkEvent he = null;
356-
355+
357356
Token t = viewToToken(e.getPoint());
358-
if (t!=null) {
357+
if (t != null) {
359358
// Copy token, viewToModel() unfortunately modifies Token
360359
t = new TokenImpl(t);
361360
}
362-
361+
363362
if (t != null && t.isHyperlink()) {
364363
URL url = null;
365364
String desc = null;
@@ -375,38 +374,38 @@ private HyperlinkEvent createHyperlinkEvent(MouseEvent e) {
375374
}
376375
he = new HyperlinkEvent(SketchTextArea.this, HyperlinkEvent.EventType.ACTIVATED, url, desc);
377376
}
378-
377+
379378
return he;
380379
}
381-
380+
382381
@Override
383382
public void mouseClicked(MouseEvent e) {
384383
if (getHyperlinksEnabled()) {
385384
HyperlinkEvent he = createHyperlinkEvent(e);
386-
if (he!=null) {
385+
if (he != null) {
387386
fireHyperlinkUpdate(he);
388387
}
389388
}
390389
}
391-
392-
@Override
390+
391+
@Override
393392
public void mouseMoved(MouseEvent e) {
394393

395394
super.mouseMoved(e);
396395

397396
if (!getHyperlinksEnabled()) {
398397
return;
399398
}
400-
399+
401400
// LinkGenerator linkGenerator = getLinkGenerator();
402-
401+
403402
// GitHub issue RSyntaxTextArea/#25 - links identified at "edges" of editor
404403
// should not be activated if mouse is in margin insets.
405404
insets = getInsets(insets);
406-
if (insets!=null) {
405+
if (insets != null) {
407406
int x = e.getX();
408407
int y = e.getY();
409-
if (x<=insets.left || y<insets.top) {
408+
if (x <= insets.left || y < insets.top) {
410409
if (isScanningForLinks) {
411410
stopScanningForLinks();
412411
}
@@ -416,14 +415,14 @@ public void mouseMoved(MouseEvent e) {
416415

417416
isScanningForLinks = true;
418417
Token t = viewToToken(e.getPoint());
419-
if (t!=null) {
418+
if (t != null) {
420419
// Copy token, viewToModel() unfortunately modifies Token
421420
t = new TokenImpl(t);
422421
}
423422
Cursor c2 = null;
424-
if (t!=null && t.isHyperlink()) {
425-
if (hoveredOverLinkOffset==-1 ||
426-
hoveredOverLinkOffset!=t.getOffset()) {
423+
if (t != null && t.isHyperlink()) {
424+
if (hoveredOverLinkOffset == -1 ||
425+
hoveredOverLinkOffset != t.getOffset()) {
427426
hoveredOverLinkOffset = t.getOffset();
428427
repaint();
429428
}
@@ -456,15 +455,15 @@ public void mouseMoved(MouseEvent e) {
456455
else {
457456
c2 = Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR);
458457
hoveredOverLinkOffset = -1;
459-
// linkGeneratorResult = null;
458+
// linkGeneratorResult = null;
460459
}
461-
if (getCursor()!=c2) {
460+
if (getCursor() != c2) {
462461
setCursor(c2);
463462
// TODO: Repaint just the affected line(s).
464463
repaint(); // Link either left or went into.
465-
}
464+
}
466465
}
467-
466+
468467
private void stopScanningForLinks() {
469468
if (isScanningForLinks) {
470469
Cursor c = getCursor();
@@ -478,4 +477,8 @@ private void stopScanningForLinks() {
478477

479478
}
480479

480+
@Override
481+
protected RTextAreaUI createRTextAreaUI() {
482+
return new SketchTextAreaUI(this);
483+
}
481484
}

app/src/processing/app/syntax/SketchTextAreaDefaultInputMap.java

+6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package processing.app.syntax;
22

33
import org.fife.ui.rsyntaxtextarea.RSyntaxTextAreaDefaultInputMap;
4+
import org.fife.ui.rtextarea.RTextArea;
45
import org.fife.ui.rtextarea.RTextAreaEditorKit;
56
import processing.app.PreferencesData;
67

@@ -23,5 +24,10 @@ public SketchTextAreaDefaultInputMap() {
2324
remove(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, alt));
2425
remove(KeyStroke.getKeyStroke(KeyEvent.VK_UP, alt));
2526
}
27+
28+
boolean isOSX = RTextArea.isOSX();
29+
if (isOSX) {
30+
put(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, alt), SketchTextAreaEditorKit.rtaDeleteNextWordAction);
31+
}
2632
}
2733
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package processing.app.syntax;
2+
3+
import org.fife.ui.rsyntaxtextarea.RSyntaxTextAreaEditorKit;
4+
import org.fife.ui.rtextarea.RTextArea;
5+
import org.fife.ui.rtextarea.RecordableTextAction;
6+
7+
import javax.swing.*;
8+
import javax.swing.text.BadLocationException;
9+
import javax.swing.text.TextAction;
10+
import javax.swing.text.Utilities;
11+
import java.awt.event.ActionEvent;
12+
13+
public class SketchTextAreaEditorKit extends RSyntaxTextAreaEditorKit {
14+
15+
public static final String rtaDeleteNextWordAction = "RTA.DeleteNextWordAction";
16+
17+
private static final Action[] defaultActions = {
18+
new DeleteNextWordAction()
19+
};
20+
21+
@Override
22+
public Action[] getActions() {
23+
return TextAction.augmentList(super.getActions(), SketchTextAreaEditorKit.defaultActions);
24+
}
25+
26+
public static class DeleteNextWordAction extends RecordableTextAction {
27+
28+
public DeleteNextWordAction() {
29+
super(rtaDeleteNextWordAction);
30+
}
31+
32+
@Override
33+
public void actionPerformedImpl(ActionEvent e, RTextArea textArea) {
34+
if (!textArea.isEditable() || !textArea.isEnabled()) {
35+
UIManager.getLookAndFeel().provideErrorFeedback(textArea);
36+
return;
37+
}
38+
try {
39+
int start = textArea.getSelectionStart();
40+
int end = getNextWordStart(textArea, start);
41+
if (end > start) {
42+
textArea.getDocument().remove(start, end - start);
43+
}
44+
} catch (BadLocationException ex) {
45+
UIManager.getLookAndFeel().provideErrorFeedback(textArea);
46+
}
47+
}
48+
49+
@Override
50+
public String getMacroID() {
51+
return rtaDeleteNextWordAction;
52+
}
53+
54+
/**
55+
* Returns the starting offset to delete. Exists so subclasses can
56+
* override.
57+
*/
58+
protected int getNextWordStart(RTextArea textArea, int end)
59+
throws BadLocationException {
60+
return Utilities.getNextWord(textArea, end);
61+
}
62+
63+
}
64+
65+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package processing.app.syntax;
2+
3+
import org.fife.ui.rsyntaxtextarea.RSyntaxTextAreaUI;
4+
5+
import javax.swing.*;
6+
import javax.swing.text.EditorKit;
7+
import javax.swing.text.JTextComponent;
8+
9+
public class SketchTextAreaUI extends RSyntaxTextAreaUI {
10+
11+
private static final EditorKit defaultKit = new SketchTextAreaEditorKit();
12+
13+
public SketchTextAreaUI(JComponent rSyntaxTextArea) {
14+
super(rSyntaxTextArea);
15+
}
16+
17+
@Override
18+
public EditorKit getEditorKit(JTextComponent tc) {
19+
return defaultKit;
20+
}
21+
}

0 commit comments

Comments
 (0)