forked from microsoft/copilot-for-eclipse
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathUndoableTextViewer.java
More file actions
104 lines (92 loc) · 3.16 KB
/
Copy pathUndoableTextViewer.java
File metadata and controls
104 lines (92 loc) · 3.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
package com.microsoft.copilot.eclipse.ui.chat;
import org.eclipse.jface.text.ITextOperationTarget;
import org.eclipse.jface.text.IUndoManager;
import org.eclipse.jface.text.TextViewer;
import org.eclipse.jface.text.TextViewerUndoManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.widgets.Composite;
/**
* A TextViewer with built-in undo/redo support.
*
* <p>This base class provides:
* <ul>
* <li>Undo manager configuration with a configurable history size</li>
* <li>Key bindings for undo (Cmd+Z/Ctrl+Z) and redo (Cmd+Shift+Z/Ctrl+Y)</li>
* <li>Compound change management for word-by-word and line-by-line undo</li>
* <li>Proper cleanup on disposal</li>
* </ul>
*/
public class UndoableTextViewer extends TextViewer {
private static final int DEFAULT_UNDO_HISTORY_SIZE = 25;
private IUndoManager undoManager;
/**
* Constructs a new UndoableTextViewer.
*
* @param parent the parent composite
* @param styles the SWT style bits
*/
public UndoableTextViewer(Composite parent, int styles) {
super(parent, styles);
}
/**
* Configures the undo manager for this text viewer. Call this method after setting the document.
*/
protected void configureUndoManager() {
configureUndoManager(DEFAULT_UNDO_HISTORY_SIZE);
}
/**
* Configures the undo manager for this text viewer with a custom history size. Call this method after setting the
* document.
*
* @param historySize the number of undo steps to keep in history
*/
protected void configureUndoManager(int historySize) {
this.undoManager = new TextViewerUndoManager(historySize);
this.setUndoManager(this.undoManager);
this.undoManager.connect(this);
// Disconnect undo manager on disposal to prevent memory leaks
this.getTextWidget().addDisposeListener(e -> {
if (this.undoManager != null) {
this.undoManager.disconnect();
}
});
}
/**
* Handles undo/redo key events.
*
* @param e the key event
* @return true if the event was handled, false otherwise
*/
protected boolean handleUndoRedoKeyEvent(KeyEvent e) {
// Handle undo (Cmd+Z on macOS, Ctrl+Z on other platforms)
if (e.keyCode == 'z' && (e.stateMask & SWT.MOD1) != 0 && (e.stateMask & SWT.SHIFT) == 0) {
if (canDoOperation(ITextOperationTarget.UNDO)) {
doOperation(ITextOperationTarget.UNDO);
}
e.doit = false;
return true;
}
// Handle redo (Cmd+Shift+Z on macOS, Ctrl+Y on other platforms)
if ((e.keyCode == 'z' && (e.stateMask & SWT.MOD1) != 0 && (e.stateMask & SWT.SHIFT) != 0)
|| (e.keyCode == 'y' && (e.stateMask & SWT.MOD1) != 0)) {
if (canDoOperation(ITextOperationTarget.REDO)) {
doOperation(ITextOperationTarget.REDO);
}
e.doit = false;
return true;
}
return false;
}
/**
* Ends the current compound change in the undo manager. Call this to create undo boundaries (e.g., after whitespace
* or newlines).
*/
protected void endCompoundChange() {
if (undoManager != null) {
undoManager.endCompoundChange();
}
}
}