1 package acl2s.plugin.editors;
2
3 import java.io.File;
4 import java.util.ArrayList;
5 import java.util.Iterator;
6
7 import org.eclipse.core.runtime.IPath;
8 import org.eclipse.core.runtime.Path;
9 import org.eclipse.jface.text.BadLocationException;
10 import org.eclipse.jface.text.Document;
11 import org.eclipse.jface.text.IRegion;
12 import org.eclipse.jface.text.source.Annotation;
13 import org.eclipse.jface.text.source.AnnotationModel;
14 import org.eclipse.jface.text.source.IAnnotationModel;
15 import org.eclipse.swt.widgets.Display;
16 import org.eclipse.text.undo.DocumentUndoManagerRegistry;
17 import org.eclipse.text.undo.IDocumentUndoManager;
18 import org.eclipse.ui.IEditorInput;
19 import org.eclipse.ui.IFileEditorInput;
20 import org.eclipse.ui.IPathEditorInput;
21 import org.eclipse.ui.IURIEditorInput;
22 import org.eclipse.ui.texteditor.ResourceMarkerAnnotationModel;
23
24 import acl2s.lib.contentassist.WorkspaceDictionary;
25 import acl2s.plugin.Acl2sPlugin;
26 import acl2s.plugin.indent.DefaultLispIndent;
27 import acl2s.plugin.indent.ILispIndent;
28 import acl2s.plugin.parse.LispToken;
29 import acl2s.plugin.parse.LispTokens;
30
31
32 public abstract class A2sDocument extends Document {
33 protected final Display display = Display.getDefault();
34
35 protected LispTokens tokens;
36 protected MyDocumentProvider dp;
37 protected IEditorInput input = null;
38 protected AnnotationModel annotations = null;
39 protected String[] eols = null;
40 protected boolean startedDirty = false;
41 protected ILispIndent indent = null;
42
43 protected A2sDocument(MyDocumentProvider dp) {
44 super();
45 this.dp = dp;
46 annotations = new AnnotationModel();
47 WorkspaceDictionary.addFile(this, null);
48 }
49
50 public IPath getOSPath() {
51 if (input instanceof IFileEditorInput) {
52 return ((IFileEditorInput)input).getFile().getLocation();
53 } else if (input instanceof IPathEditorInput) {
54 return ((IPathEditorInput)input).getPath();
55 } else if (input instanceof IURIEditorInput) {
56 try {
57 return new Path(new File(((IURIEditorInput)input).getURI()).getAbsolutePath());
58 } catch (IllegalArgumentException e) {
59 return null;
60 }
61 } else {
62 return null;
63 }
64 }
65
66 public File getOSFile() {
67 if (input instanceof IFileEditorInput) {
68 return ((IFileEditorInput)input).getFile().getLocation().toFile();
69 } else if (input instanceof IPathEditorInput) {
70 return ((IPathEditorInput)input).getPath().toFile();
71 } else if (input instanceof IURIEditorInput) {
72 try {
73 return new File(((IURIEditorInput)input).getURI());
74 } catch (IllegalArgumentException e) {
75 return null;
76 }
77 } else {
|
Event null_literal: |
Using a literal null value. |
78 return null;
79 }
80 }
81
82 public IEditorInput getInput() { return input; }
83
84 @SuppressWarnings("unchecked") // stupid Eclipse API
85 public void setInput(IEditorInput i) {
86 input = i;
87 if (i instanceof IFileEditorInput) {
88 AnnotationModel old = annotations;
89 annotations = new ResourceMarkerAnnotationModel(((IFileEditorInput)i).getFile());
90 Iterator<Annotation> foo = old.getAnnotationIterator();
91 while (foo.hasNext()) {
92 Annotation a = foo.next();
93 annotations.addAnnotation(a,old.getPosition(a));
94 }
95 }
96 eols = getLegalLineDelimiters();
97 indent = new DefaultLispIndent(tokens, this);
98 }
99
100 public abstract MyDocumentProvider getProvider();
101
102 public void ensureDirty() {
103 if (input != null) {
104 getProvider().setCanSaveDocument(input);
105 } else {
106 startedDirty = true;
107 }
108 }
109
110 public boolean startedDirty() { return startedDirty; }
111
112 public boolean isDirty() {
113 return getProvider().canSaveDocument(input);
114 }
115
116
117 public IDocumentUndoManager getUndoManager() {
118 return DocumentUndoManagerRegistry.getDocumentUndoManager(this);
119 }
120
121 public void resetUndoStuff() {
122 IDocumentUndoManager m = getUndoManager();
123 if (m != null) m.reset();
124 }
125
126
127 public boolean isEOL(String txt) {
128 for (String s : eols) {
129 if (s.equals(txt)) {
130 return true;
131 }
132 }
133 return false;
134 }
135
136 public String get2(int offset, int len) {
137 try {
138 return get(offset,len);
139 } catch (BadLocationException e) {
140 Acl2sPlugin.logError("Bad document location.",e);
141 return "";
142 }
143 }
144
145 public char getChar2(int i) {
146 try {
147 return getChar(i);
148 } catch (BadLocationException e) {
149 Acl2sPlugin.logError("Bad document location.",e);
150 return '\0';
151 }
152 }
153
154 public void replace2(int offset, int len, String s) {
155 try {
156 replace(offset,len,s);
157 } catch (BadLocationException e) {
158 Acl2sPlugin.logError("Bad document location.",e);
159 }
160 }
161
162
163
164 public void replace(int pos, int length, String text) throws BadLocationException {
165 if (text == null) text = ""; // Eclipse will actually call with null in places!!!
166
167 if (allowReplace(pos, length, text)) {
168 super.replace(pos, length, text);
169 }
170 }
171
172 protected boolean allowReplace(int pos, int length, String text) {
173 return pos >= readOnlyPoint();
174 }
175
176 public abstract int readOnlyPoint();
177
178 public LispTokens getTokens() { return tokens; }
179
180 public IAnnotationModel getAnnotationModel() {
181 return annotations;
182 }
183
184 /* *************** INDENT ************* */
185
186 public ILispIndent getIndentStrategy() { return indent; }
187
188 public void indentRegion(IRegion region) {
189 try {
190 int start = region.getOffset();
191 int end = start + region.getLength();
192 start = Math.max(start,readOnlyPoint());
193 if (end > start) {
194 end--;
195 } else if (end < start) {
196 return;
197 }
198 int firstLine = getLineOfOffset(start);
199 int lastLine = getLineOfOffset(end);
200 for (int i = firstLine; i <= lastLine; i++) {
201 indent.indentLine(i);
202 }
203 } catch (BadLocationException e) {
204 e.printStackTrace();
205 }
206 }
207
208
209
210 /* ======= Sexp navigation/selection ======== */
211 public int fwdToplevelSexp(int fromOffset) {
212 int tIdx = tokens.getTokenIdxContaining(fromOffset);
213 LispToken tok = tokens.getToken(tIdx);
214 if (tok.ctx == null && tok.offset > fromOffset) {
215 return tok.offset;
216 }
217 for (;;) {
218 tIdx++;
219 if (tIdx >= tokens.getTokenCount()) break;
220 tok = tokens.getToken(tIdx);
221 if (tok.ctx == null) break;
222 }
223 return tok.offset;
224 }
225
226 public int backToplevelSexp(int fromOffset) {
227 int tIdx = tokens.getTokenIdxContaining(fromOffset);
228 LispToken tok = tokens.getToken(tIdx);
229 if (tok.ctx == null && tok.offset > fromOffset) {
230 tIdx--;
231 }
232 for (;;) {
233 if (tIdx < 0) break;
234 tok = tokens.getToken(tIdx);
235 if (tok.ctx == null) break;
236 tIdx--;
237 }
238 return tok.offset;
239 }
240
241
242
243 /* ====== Description Notification ====== */
244 protected abstract String doGetDescription();
245
246 protected final ArrayList<IDescriptionListener> descListeners = new ArrayList<IDescriptionListener>();
247
248 public void addDescriptionListener(IDescriptionListener l) {
249 if (!descListeners.contains(l)) {
250 descListeners.add(l);
251 updateDescriptions();
252 }
253 }
254
255 public void removeDescriptionListener(IDescriptionListener l) {
256 descListeners.remove(l);
257 }
258
259 protected void updateDescriptions() {
260 String desc = doGetDescription();
261 for (IDescriptionListener l : descListeners) {
262 l.descriptionChanged(desc);
263 }
264 }
265
266
267 }