1 12 package org.eclipse.ui.texteditor; 13 14 import java.util.ArrayList ; 15 import java.util.List ; 16 import java.util.ResourceBundle ; 17 18 import org.eclipse.jface.text.BadLocationException; 19 import org.eclipse.jface.text.IDocument; 20 import org.eclipse.jface.text.IRewriteTarget; 21 import org.eclipse.jface.text.ITextSelection; 22 import org.eclipse.jface.text.source.ISourceViewer; 23 24 import org.eclipse.core.runtime.Assert; 25 import org.eclipse.core.runtime.IStatus; 26 import org.eclipse.core.runtime.Status; 27 import org.eclipse.ui.IEditorInput; 28 import org.eclipse.ui.IEditorPart; 29 import org.eclipse.ui.IEditorReference; 30 import org.eclipse.ui.IWorkbenchWindow; 31 import org.eclipse.ui.internal.texteditor.CompoundEditExitStrategy; 32 import org.eclipse.ui.internal.texteditor.HippieCompletionEngine; 33 import org.eclipse.ui.internal.texteditor.ICompoundEditListener; 34 import org.eclipse.ui.internal.texteditor.TextEditorPlugin; 35 36 47 final class HippieCompleteAction extends TextEditorAction { 48 49 55 private static class CompletionState { 56 57 58 int length; 59 60 61 int nextSuggestion; 62 63 64 final int startOffset; 65 66 70 final String [] suggestions; 71 72 79 CompletionState(String [] suggestions, int startOffset) { 80 this.suggestions= suggestions; 81 this.startOffset= startOffset; 82 length= 0; 83 nextSuggestion= 0; 84 } 85 86 89 public void advance() { 90 length= suggestions[nextSuggestion].length(); 91 nextSuggestion= (nextSuggestion + 1) % suggestions.length; 92 } 93 } 94 95 98 private IDocument fDocument; 99 100 104 private CompletionState fLastCompletion= null; 105 106 109 private final HippieCompletionEngine fEngine= new HippieCompletionEngine(); 110 111 112 private final CompoundEditExitStrategy fExitStrategy= new CompoundEditExitStrategy(ITextEditorActionDefinitionIds.HIPPIE_COMPLETION); 113 114 123 HippieCompleteAction(ResourceBundle bundle, String prefix, ITextEditor editor) { 124 super(bundle, prefix, editor); 125 fExitStrategy.addCompoundListener(new ICompoundEditListener() { 126 public void endCompoundEdit() { 127 clearState(); 128 } 129 }); 130 } 131 132 136 private void clearState() { 137 fLastCompletion= null; 138 139 ITextEditor editor= getTextEditor(); 140 141 if (editor != null) { 142 IRewriteTarget target= (IRewriteTarget) editor.getAdapter(IRewriteTarget.class); 143 if (target != null) { 144 fExitStrategy.disarm(); 145 target.endCompoundChange(); 146 } 147 } 148 149 fDocument= null; 150 } 151 152 155 private void completeNext() { 156 try { 157 fDocument.replace(fLastCompletion.startOffset, fLastCompletion.length, fLastCompletion.suggestions[fLastCompletion.nextSuggestion]); 158 } catch (BadLocationException e) { 159 log(e); 161 clearState(); 162 return; 163 } 164 165 fLastCompletion.advance(); 167 168 ISourceViewer sourceViewer= ((AbstractTextEditor) getTextEditor()).getSourceViewer(); 170 sourceViewer.setSelectedRange(fLastCompletion.startOffset + fLastCompletion.length, 0); 171 sourceViewer.revealRange(fLastCompletion.startOffset, fLastCompletion.length); 172 173 fExitStrategy.arm(((AbstractTextEditor) getTextEditor()).getSourceViewer()); 174 } 175 176 184 private ArrayList createSuggestionsFromOpenDocument(String prefix) throws BadLocationException { 185 int selectionOffset= getSelectionOffset(); 186 187 ArrayList completions= new ArrayList (); 188 completions.addAll(fEngine.getCompletionsBackwards(fDocument, prefix, selectionOffset)); 189 completions.addAll(fEngine.getCompletionsForward(fDocument, prefix, selectionOffset - prefix.length(), true)); 190 191 return completions; 192 } 193 194 201 private IDocument getCurrentDocument() { 202 ITextEditor editor= getTextEditor(); 203 if (editor == null) 204 return null; 205 IDocumentProvider provider= editor.getDocumentProvider(); 206 if (provider == null) 207 return null; 208 209 IDocument document= provider.getDocument(editor.getEditorInput()); 210 return document; 211 } 212 213 221 private String getCurrentPrefix() throws BadLocationException { 222 ITextSelection selection= (ITextSelection) getTextEditor().getSelectionProvider().getSelection(); 223 if (selection.getLength() > 0) { 224 return null; 225 } 226 return fEngine.getPrefixString(fDocument, selection.getOffset()); 227 } 228 229 234 private int getSelectionOffset() { 235 return ((ITextSelection) getTextEditor().getSelectionProvider().getSelection()).getOffset(); 236 } 237 238 248 private String [] getSuggestions(String prefix) throws BadLocationException { 249 250 ArrayList suggestions= createSuggestionsFromOpenDocument(prefix); 251 252 IWorkbenchWindow window= getTextEditor().getSite().getWorkbenchWindow(); 253 IEditorReference editorsArray[]= window.getActivePage().getEditorReferences(); 254 255 for (int i= 0; i < editorsArray.length; i++) { 256 IEditorPart realEditor= editorsArray[i].getEditor(false); 257 if (realEditor instanceof ITextEditor && 258 !realEditor.equals(getTextEditor())) { ITextEditor textEditor= (ITextEditor)realEditor; 260 IEditorInput input= textEditor.getEditorInput(); 261 IDocument doc= textEditor.getDocumentProvider().getDocument(input); 262 263 suggestions.addAll(fEngine.getCompletionsForward(doc, prefix, 0, false)); 264 } 265 } 266 suggestions.add(""); 269 List uniqueSuggestions= fEngine.makeUnique(suggestions); 270 271 return (String []) uniqueSuggestions.toArray(new String [0]); 272 } 273 274 281 private boolean isStateValid() { 282 return fDocument != null 283 && fDocument.equals(getCurrentDocument()) 284 && fLastCompletion != null 285 && fLastCompletion.startOffset + fLastCompletion.length == getSelectionOffset(); 286 } 287 288 291 private void notifyUser() { 292 getTextEditor().getSite().getShell().getDisplay().beep(); 294 } 295 296 299 public void run() { 300 if (!validateEditorInputState()) 301 return; 302 303 if (!isStateValid()) 304 updateState(); 305 306 if (isStateValid()) 307 completeNext(); 308 } 309 310 313 public boolean isEnabled() { 314 return canModifyEditor(); 315 } 316 317 320 public void setEditor(ITextEditor editor) { 321 clearState(); super.setEditor(editor); 323 } 324 325 332 private void updateState() { 333 Assert.isNotNull(getTextEditor()); 334 335 clearState(); 336 337 IDocument document= getCurrentDocument(); 338 if (document != null) { 339 fDocument= document; 340 341 String [] suggestions; 342 try { 343 String prefix= getCurrentPrefix(); 344 if (prefix == null) { 345 notifyUser(); 346 return; 347 } 348 suggestions= getSuggestions(prefix); 349 } catch (BadLocationException e) { 350 log(e); 351 return; 352 } 353 354 if (suggestions.length == 1) { 356 notifyUser(); 357 return; 358 } 359 360 IRewriteTarget target= (IRewriteTarget) getTextEditor().getAdapter(IRewriteTarget.class); 361 if (target != null) 362 target.beginCompoundChange(); 363 364 fLastCompletion= new CompletionState(suggestions, getSelectionOffset()); 365 } 366 } 367 368 373 private void log(BadLocationException e) { 374 String msg= e.getLocalizedMessage(); 375 if (msg == null) 376 msg= "unable to access the document"; TextEditorPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, TextEditorPlugin.PLUGIN_ID, IStatus.OK, msg, e)); 378 } 379 } 380 | Popular Tags |