Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 11668 | Differences between
and this patch

Collapse All | Expand All

(-)plugin.properties (+2 lines)
Lines 152-157 Link Here
152
command.toggleOverwrite.name = Toggle Overwrite
152
command.toggleOverwrite.name = Toggle Overwrite
153
command.toggleInsertMode.description = Toggle insert mode
153
command.toggleInsertMode.description = Toggle insert mode
154
command.toggleInsertMode.name = Toggle Insert Mode
154
command.toggleInsertMode.name = Toggle Insert Mode
155
command.hippieCompletion.description = Context insensitive completion
156
command.hippieCompletion.name = Hippie Completion
155
command.windowEnd.description = Go to the end of the window
157
command.windowEnd.description = Go to the end of the window
156
command.windowEnd.name = Window End
158
command.windowEnd.name = Window End
157
command.windowStart.description = Go to the start of the window
159
command.windowStart.description = Go to the start of the window
(-)plugin.xml (+13 lines)
Lines 426-431 Link Here
426
            categoryId="org.eclipse.ui.category.edit"
426
            categoryId="org.eclipse.ui.category.edit"
427
            id="org.eclipse.ui.edit.text.toggleInsertMode">
427
            id="org.eclipse.ui.edit.text.toggleInsertMode">
428
      </command>
428
      </command>
429
      <command
430
            name="%command.hippieCompletion.name"
431
            description="%command.hippieCompletion.description"
432
            categoryId="org.eclipse.ui.category.edit"
433
            id="org.eclipse.ui.edit.text.hippieCompletion">
434
      </command>
435
      <!-- TODO Keybinding -->
436
      <keyBinding
437
            commandId="org.eclipse.ui.edit.text.hippieCompletion"
438
            contextId="org.eclipse.ui.textEditorScope"
439
            keySequence="Alt+/"
440
            keyConfigurationId="org.eclipse.ui.defaultAcceleratorConfiguration">
441
       </keyBinding>
429
	
442
	
430
	  <keyBinding
443
	  <keyBinding
431
	        commandId="org.eclipse.ui.edit.text.delete.line"
444
	        commandId="org.eclipse.ui.edit.text.delete.line"
(-)src/org/eclipse/ui/texteditor/AbstractTextEditor.java (+6 lines)
Lines 4272-4277 Link Here
4272
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.TOGGLE_INSERT_MODE);
4272
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.TOGGLE_INSERT_MODE);
4273
		setAction(ITextEditorActionConstants.TOGGLE_INSERT_MODE, action);
4273
		setAction(ITextEditorActionConstants.TOGGLE_INSERT_MODE, action);
4274
4274
4275
		action = new HippieCompleteAction(EditorMessages.getResourceBundle(), "Editor.HippieCompletion.", this); //$NON-NLS-1$
4276
		// TODO action.setHelpContextId(IAbstractTextEditorHelpContextIds.HIPPIE_COMPLETION_ACTION);
4277
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.HIPPIE_COMPLETION);
4278
		setAction(ITextEditorActionConstants.HIPPIE_COMPLETION, action);
4279
		
4275
		PropertyDialogAction openProperties= new PropertyDialogAction(
4280
		PropertyDialogAction openProperties= new PropertyDialogAction(
4276
				getSite().getShell(),
4281
				getSite().getShell(),
4277
				new ISelectionProvider() {
4282
				new ISelectionProvider() {
Lines 4295-4300 Link Here
4295
		markAsContentDependentAction(ITextEditorActionConstants.FIND_PREVIOUS, true);
4300
		markAsContentDependentAction(ITextEditorActionConstants.FIND_PREVIOUS, true);
4296
		markAsContentDependentAction(ITextEditorActionConstants.FIND_INCREMENTAL, true);
4301
		markAsContentDependentAction(ITextEditorActionConstants.FIND_INCREMENTAL, true);
4297
		markAsContentDependentAction(ITextEditorActionConstants.FIND_INCREMENTAL_REVERSE, true);
4302
		markAsContentDependentAction(ITextEditorActionConstants.FIND_INCREMENTAL_REVERSE, true);
4303
        markAsContentDependentAction(ITextEditorActionConstants.HIPPIE_COMPLETION, true);
4298
		
4304
		
4299
		markAsSelectionDependentAction(ITextEditorActionConstants.CUT, true);
4305
		markAsSelectionDependentAction(ITextEditorActionConstants.CUT, true);
4300
		markAsSelectionDependentAction(ITextEditorActionConstants.COPY, true);
4306
		markAsSelectionDependentAction(ITextEditorActionConstants.COPY, true);
(-)src/org/eclipse/ui/texteditor/ITextEditorActionConstants.java (+7 lines)
Lines 517-520 Link Here
517
	 * @since 3.1
517
	 * @since 3.1
518
	 */
518
	 */
519
	static final String QUICKDIFF_TOGGLE= "QuickDiff.Toggle"; //$NON-NLS-1$
519
	static final String QUICKDIFF_TOGGLE= "QuickDiff.Toggle"; //$NON-NLS-1$
520
521
	/** 
522
	 * Name of the action for emacs style hippie completion. 
523
	 * Value: <code>"HIPPIE_COMPLETION"</code>
524
	 * @since 3.1
525
	 */
526
	static final String HIPPIE_COMPLETION= "HIPPIE_COMPLETION"; //$NON-NLS-1$
520
}
527
}
(-)src/org/eclipse/ui/texteditor/ITextEditorActionDefinitionIds.java (+7 lines)
Lines 485-488 Link Here
485
	 * @since 3.1
485
	 * @since 3.1
486
	 */
486
	 */
487
	static final String LINENUMBER_TOGGLE= "org.eclipse.ui.editors.lineNumberToggle"; //$NON-NLS-1$
487
	static final String LINENUMBER_TOGGLE= "org.eclipse.ui.editors.lineNumberToggle"; //$NON-NLS-1$
488
489
	/**
490
	 * Action definition ID of the edit -> text complete action
491
	 * Value: <code>"org.eclipse.ui.edit.text.hippieCompletion"</code>).
492
	 * @since 3.1
493
	 */
494
	public static final String HIPPIE_COMPLETION= "org.eclipse.ui.edit.text.hippieCompletion"; //$NON-NLS-1$
488
}
495
}
(-)src/org/eclipse/ui/texteditor/HippieCompleteAction.java (+516 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials 
4
 * are made available under the terms of the Common Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/cpl-v10.html
7
 * 
8
 * Contributors:
9
 *     Genady Beryozkin, me@genady.org - initial API and implementation
10
 *     IBM Corporation - fixes and cleaning
11
 *******************************************************************************/
12
package org.eclipse.ui.texteditor;
13
14
import java.util.ArrayList;
15
import java.util.HashSet;
16
import java.util.Iterator;
17
import java.util.LinkedList;
18
import java.util.List;
19
import java.util.ResourceBundle;
20
21
import org.eclipse.jface.text.BadLocationException;
22
import org.eclipse.jface.text.DocumentEvent;
23
import org.eclipse.jface.text.FindReplaceDocumentAdapter;
24
import org.eclipse.jface.text.IDocument;
25
import org.eclipse.jface.text.IDocumentListener;
26
import org.eclipse.jface.text.IRegion;
27
import org.eclipse.jface.text.ITextSelection;
28
import org.eclipse.jface.viewers.ISelectionChangedListener;
29
import org.eclipse.jface.viewers.ISelectionProvider;
30
import org.eclipse.jface.viewers.SelectionChangedEvent;
31
32
import org.eclipse.ui.IEditorInput;
33
import org.eclipse.ui.IEditorPart;
34
import org.eclipse.ui.IEditorReference;
35
import org.eclipse.ui.IWorkbenchWindow;
36
37
/**
38
 * This class implements the emacs style completion action.
39
 * Completion action is a stateful action, as the user may invoke
40
 * it several times in a row in order to scroll the possible completions.
41
 * 
42
 * TODO: Sort by editor type
43
 * TODO: Provide history option
44
 * 
45
 * @author Genady Beryozkin, me@genady.org
46
 */
47
public class HippieCompleteAction extends TextEditorAction {
48
49
    /**
50
     * Regular expression that is used to find words.
51
     */
52
    private static final String COMPLETION_WORD_REGEX= "\\w+"; //$NON-NLS-1$
53
    
54
    /**
55
     * Is completion case sensitive? Even if set to <code>false</code>, the case of the prefix
56
     * won't be changed.
57
     */
58
    private static final boolean CASE_SENSITIVE= true;
59
60
    /**
61
     * The document that will be manipulated
62
     */
63
	private IDocument fDocument;
64
    
65
    /**
66
     * The selection provider associated with the text editor. 
67
     */
68
    private ISelectionProvider fSelectionProvider;
69
70
	/** 
71
	 * The completion state that is used to continue the iteration over suggestions
72
	 */
73
	private CompletionState fLastCompletion= null;
74
	
75
    /**
76
     * Modification lock that will prevent invalidation of the completion state when the
77
     * completion action modifies the document
78
     */
79
	private boolean fModifyingLock= false;
80
	
81
	SelectionChangeListener fSelectionListener;
82
	DocumentChangeListener fContentListener;
83
84
	/* (non-Javadoc)
85
	 * @see org.eclipse.ui.texteditor.TextEditorAction#setEditor(org.eclipse.ui.texteditor.ITextEditor)
86
	 */
87
	public void setEditor(ITextEditor editor) {
88
		super.setEditor(editor);
89
90
		fSelectionListener= new SelectionChangeListener();
91
		fContentListener= new DocumentChangeListener();
92
	}
93
	
94
    /**
95
     * This class accompanies the {@link HippieCompleteAction#checkValidPosition()} method
96
     * to invalidate completion state when the selection changes.
97
     */
98
	class SelectionChangeListener implements ISelectionChangedListener {
99
		public void selectionChanged(SelectionChangedEvent event) {
100
			if (!fModifyingLock) {
101
				fLastCompletion= null;
102
			}
103
		}
104
	}
105
	
106
    /**
107
     * Invalidate the completion state when the document contents changes not
108
     * as the result of the completion action itself. This is needed since
109
     * the {@link HippieCompleteAction#update()} method is only called when the
110
     * {@link HippieCompleteAction#fModifyingLock} is already false.
111
     */
112
	class DocumentChangeListener implements IDocumentListener {
113
		public void documentAboutToBeChanged(DocumentEvent event) {
114
		}
115
116
		public void documentChanged(DocumentEvent event) {
117
			if (!fModifyingLock) {
118
				fLastCompletion= null;
119
			}
120
		}
121
	}	
122
	
123
	/**
124
	 * Perform the next completion.
125
	 */
126
	private void completeNext() {
127
		// we don't wish to receive events on our own changes
128
		fModifyingLock= true;
129
		
130
		try {
131
			fDocument.replace(fLastCompletion.startOffset, fLastCompletion.length, 
132
					fLastCompletion.suggestions[fLastCompletion.nextSuggestion]);
133
		} catch (BadLocationException e) {
134
			// we should never get here. different from other places to notify the user.
135
			throw new IllegalStateException(e.toString());
136
		}
137
138
		// advance the suggestion state
139
		fLastCompletion.advance();
140
141
		// move the cursor to the insertion point
142
		((AbstractTextEditor) getTextEditor()).getSourceViewer().setSelectedRange(fLastCompletion.startOffset+fLastCompletion.length, 0);
143
		
144
		// allow changes
145
		fModifyingLock= false;
146
	}
147
	
148
	/**
149
	 * This class represents the state of the last completion process.
150
	 * Each time the user moves to a new position and calls this action
151
	 * an instance of this inner classs is created  and saved in
152
	 * {@link #fLastCompletion}.
153
	 */
154
	private static class CompletionState {
155
				
156
		/** The list of suggestions that was computed when the completion
157
		 * action was first invoked 
158
		 */
159
		final String[] suggestions;
160
				
161
		/** The caret position at which we insert the suggestions */
162
		final int startOffset;
163
				
164
		/** The length of the last suggestion string */
165
		int length;
166
		
167
		/** The index of next suggestion (index into the suggestion array) */
168
		int nextSuggestion;
169
		
170
		CompletionState(String[] suggestions, int startOffset) {
171
			this.suggestions= suggestions;
172
			this.startOffset= startOffset;
173
			length= 0;
174
			nextSuggestion= 0;
175
		}
176
		
177
		public void advance() {
178
			length= suggestions[nextSuggestion].length();
179
			nextSuggestion= (nextSuggestion + 1) % suggestions.length;	
180
		}
181
	}
182
183
	/**
184
	 * @param bundle the resource bundle
185
	 * @param prefix a prefix to be prepended to the various resource keys
186
	 *   (described in <code>ResourceAction</code> constructor), or 
187
	 *   <code>null</code> if none
188
	 * @param editor the text editor
189
	 */
190
	protected HippieCompleteAction(ResourceBundle bundle, String prefix, ITextEditor editor) {
191
		super(bundle, prefix, editor);
192
	}
193
194
	/* (non-Javadoc)
195
	 * @see org.eclipse.jface.action.Action#run()
196
	 */
197
	public void run() {
198
        checkValidPosition();
199
		if (fLastCompletion != null) 
200
		{
201
			completeNext();
202
			return;
203
		} 
204
		String prefix= getCurrentPrefix();
205
		if (prefix == null) {
206
			getTextEditor().getSite().getShell().getDisplay().beep();
207
			return;
208
		}
209
		String[] suggestions= getSuggestions(prefix);
210
		
211
		// if it is single empty suggestion
212
		if (suggestions.length == 1) {
213
			getTextEditor().getSite().getShell().getDisplay().beep();
214
			return;
215
		}
216
		fLastCompletion= new CompletionState(suggestions, 
217
				((ITextSelection) getTextEditor().getSelectionProvider().getSelection()).getOffset());
218
		completeNext();
219
	}
220
221
    /**
222
     * Invalidate the completion state if the cursor is not located at
223
     * the expected position.
224
     */
225
    private void checkValidPosition() {
226
        if (fLastCompletion != null) {
227
            if (fLastCompletion.startOffset + fLastCompletion.length != 
228
                ((ITextSelection)fSelectionProvider.getSelection()).getOffset()) {
229
                fLastCompletion= null;
230
            }
231
        }
232
    }
233
	    
234
	/**
235
	 * Create the array of suggestions. It scan all open text editors
236
	 * and prefers suggestion from the currently open editor.
237
	 * It also addes the empty suggestion at the end.
238
	 * @param prefix the prefix to search for
239
	 * @return the list of all possible suggestions in the currently open editors
240
	 */
241
	public String[] getSuggestions(String prefix) {
242
		
243
		IWorkbenchWindow window= getTextEditor().getSite().getWorkbenchWindow();
244
        IEditorReference editorsArray[]= window.getActivePage().getEditorReferences();
245
       
246
		ArrayList documentsVector= new ArrayList();
247
		for (int i= 0; i < editorsArray.length; i++) {
248
			IEditorPart realEditor= editorsArray[i].getEditor(false);
249
			if (realEditor instanceof ITextEditor) {
250
                ITextEditor textEditor= (ITextEditor)realEditor;
251
                IEditorInput input= textEditor.getEditorInput();
252
                IDocument doc= textEditor.getDocumentProvider().getDocument(input);
253
254
				documentsVector.add(doc);
255
			}
256
		}
257
		documentsVector.remove(fDocument);
258
		
259
        ArrayList suggestions= createSuggestionsFromOpenDocument(prefix);
260
        suggestions.addAll(createSuggestions(prefix, documentsVector));
261
        // add the empty suggestion
262
        suggestions.add(""); //$NON-NLS-1$
263
264
        ArrayList uniqueSuggestions= getUnique(suggestions);
265
        
266
		return (String[]) uniqueSuggestions.toArray(new String[0]);
267
	}
268
269
    /**
270
     * Return the list of suggestions from the current document. First the document is searched
271
     * backwards from the caret position and then forwards. 
272
     * @param prefix the completion prefix
273
     * @return all possible completions that were found in the current document
274
     */
275
    private ArrayList createSuggestionsFromOpenDocument(String prefix) {
276
        ITextEditor editor= getTextEditor();
277
        ITextSelection selection= (ITextSelection) editor.getSelectionProvider().getSelection();
278
        
279
        ArrayList completions= new ArrayList();
280
        try {
281
            completions.addAll(getBackwardsSuggestions(fDocument, prefix, selection.getOffset()));
282
        } catch (BadLocationException e) {
283
            // TODO log the exception?
284
        }
285
        try {
286
            completions.addAll(getForwardSuggestions(fDocument, prefix, selection.getOffset()));
287
        } catch (BadLocationException e1) {
288
            // TODO log the exception?
289
        }
290
        
291
        return completions;
292
    }
293
294
    /**
295
     * Create the suggesions list based on the provided prefix and the documents list.
296
     * Suggestions will be sorted such that the first suggestions come from the first document, 
297
     * etc.
298
     * @param prefix the completion prefix
299
     * @param documentsVector {@link ArrayList} of {@link IDocument}s.
300
     * @return the list of completions, excluding the empty completion
301
     */
302
    public static List createSuggestions(String prefix, ArrayList documentsVector) {
303
        // collect the suggestions from all the documents
304
		LinkedList suggestions= new LinkedList();
305
        
306
        for (int i= 0; i < documentsVector.size(); i++) {
307
			IDocument doc= (IDocument) documentsVector.get(i);
308
            
309
			try {
310
				suggestions.addAll(getForwardSuggestions(doc, prefix));
311
			} catch (BadLocationException e) {
312
                // TODO log the exception?
313
			}
314
		}
315
        
316
        return suggestions;
317
    }
318
319
    /**
320
	 * Remove duplicate suggestions (excluding the prefix), leaving the closest to list head. 
321
	 * @param suggestions a list of suggestions.
322
     * @return a list of unique completion suggestions.
323
	 */
324
	public static ArrayList getUnique(List suggestions) {
325
		HashSet seenAlready= new HashSet();
326
        ArrayList uniqueSuggestions= new ArrayList();
327
		
328
		for (Iterator i= suggestions.iterator(); i.hasNext();) {
329
			String suggestion= (String) i.next();
330
			if (!seenAlready.contains(suggestion)) {
331
				seenAlready.add(suggestion);
332
                uniqueSuggestions.add(suggestion);
333
			}
334
		}
335
        return uniqueSuggestions;
336
	}
337
338
	/**
339
	 * Copied from {@link FindReplaceDocumentAdapter}.
340
	 * 
341
	 * Converts a non-regex string to a pattern
342
	 * that can be used with the regex search engine.
343
	 * 
344
	 * @param string the non-regex pattern
345
	 * @return the string converted to a regex pattern
346
	 */
347
	private static String asRegPattern(String string) {
348
		StringBuffer out= new StringBuffer(string.length());
349
		boolean quoting= false;
350
		
351
		for (int i= 0, length= string.length(); i < length; i++) {
352
			char ch= string.charAt(i);
353
			if (ch == '\\') {
354
				if (quoting) {
355
					out.append("\\E"); //$NON-NLS-1$
356
					quoting= false;
357
				}
358
				out.append("\\\\"); //$NON-NLS-1$
359
				continue;								
360
			}
361
			if (!quoting) {
362
				out.append("\\Q"); //$NON-NLS-1$
363
				quoting= true;
364
			}
365
			out.append(ch);
366
		}
367
		if (quoting)
368
			out.append("\\E"); //$NON-NLS-1$
369
		
370
		return out.toString();
371
	}
372
373
	
374
	/**
375
	 * Return the list of completion suggestions the correspond to the provided
376
	 * prefix
377
	 * 
378
	 * @param document the document to be scanned
379
	 * @param prefix the prefix to search for
380
	 * @param firstPosition the initial position in the document that
381
     *          the search will start from. In order to search from
382
     *          the beginning of the document use <code>firstPosition=0</code>.
383
	 * @return an {@link ArrayList} of possible completions, excluding the common prefix
384
	 * @throws BadLocationException if there is some error scanning the document.
385
     * 
386
     * @see #getForwardSuggestions(IDocument, String)
387
	 */
388
	public static ArrayList getForwardSuggestions(IDocument document, 
389
            String prefix, int firstPosition) throws BadLocationException {
390
		ArrayList res= new ArrayList();
391
	
392
		FindReplaceDocumentAdapter searcher= new FindReplaceDocumentAdapter(document);
393
		
394
		// search only at word boundaries 
395
		String searchPattern= "\\b" + asRegPattern(prefix); //$NON-NLS-1$
396
		
397
		IRegion reg= searcher.find(firstPosition, searchPattern, true, CASE_SENSITIVE, false, true);
398
		while (reg != null) {
399
			// try to complete to a word. case is irrelevant here.
400
			IRegion word= searcher.find(reg.getOffset(), COMPLETION_WORD_REGEX, true, true, false, true);
401
			if (word.getLength() > reg.getLength() ) { // empty suggestion will be added later
402
				String found= document.get(word.getOffset(), word.getLength());
403
				res.add(found.substring(prefix.length()));
404
			}
405
			int nextPos= word.getOffset() + word.getLength();
406
			if (nextPos >= document.getLength() ) {
407
				break;
408
			}
409
			reg= searcher.find(nextPos, searchPattern, true, CASE_SENSITIVE, false, true);
410
		}
411
				
412
		return res;
413
	}
414
    
415
    /**
416
     * Search for possible completions in the backward direction.
417
     * @param document the document to be scanned
418
     * @param prefix the completion prefix
419
     * @param firstPosition the caret position
420
     * @return a list of suggestions from the caret position to the beginning of the document.
421
     * @throws BadLocationException if any error occurs
422
     */
423
    public static ArrayList getBackwardsSuggestions(IDocument document, String prefix, int firstPosition) throws BadLocationException {
424
        ArrayList res= new ArrayList();
425
        
426
        FindReplaceDocumentAdapter searcher= new FindReplaceDocumentAdapter(document);
427
        
428
        // search only at word boundaries 
429
        String searchPattern= "\\b" + asRegPattern(prefix); //$NON-NLS-1$
430
        
431
        IRegion reg= searcher.find(firstPosition, searchPattern, false, CASE_SENSITIVE, false, true);
432
        while (reg != null) {
433
            // try to complete to a word. case is of no matter here
434
            IRegion word= searcher.find(reg.getOffset(), COMPLETION_WORD_REGEX, true, true, false, true);
435
            if (word.getLength() > reg.getLength() ) { // empty suggestion will be added later
436
                String found= document.get(word.getOffset(), word.getLength());
437
                res.add(found.substring(prefix.length()));
438
            }
439
            int nextPos= word.getOffset() - 1;
440
            if (nextPos < 0 ) {
441
                break;
442
            }
443
            reg= searcher.find(nextPos, searchPattern, false, CASE_SENSITIVE, false, true);
444
        }
445
                
446
        return res;
447
    }
448
449
    /**
450
     * The method is equivalent to <code>getForwardSuggestions(document, prefix, 0)</code> 
451
     * @param document the document to scan
452
     * @param prefix the completion prefix
453
     * @return the list of comletions that are result of this document scan.
454
     * @throws BadLocationException if some error occurs. Should not be ever thrown.
455
     * 
456
     * @see #getForwardSuggestions(IDocument, String, int)
457
     */
458
    public static ArrayList getForwardSuggestions(IDocument document, 
459
            String prefix) throws BadLocationException {
460
        return getForwardSuggestions(document, prefix, 0);
461
    }
462
463
	/**
464
	 * Return the part of a word before the caret.
465
	 * If the caret is not at a middle/end of a word, 
466
	 * returns null.
467
	 * @return the prefix at the current cursor position that 
468
     *      will be used in the search for possible completions
469
	 */
470
	private String getCurrentPrefix() {
471
		ITextSelection selection= (ITextSelection) getTextEditor().getSelectionProvider().getSelection();
472
		if (selection.getLength() > 0) {
473
			return null;
474
		}
475
		int pos= selection.getOffset();
476
        
477
        String docText= fDocument.get();
478
        int prevNonAlpha= pos;
479
        while (prevNonAlpha > 0 && 
480
        	    Character.isJavaIdentifierPart(docText.charAt(prevNonAlpha-1))) 
481
        {
482
        	prevNonAlpha--;
483
        }
484
        if (prevNonAlpha != pos) {
485
            return docText.substring(prevNonAlpha, pos);
486
        }
487
        return null;
488
	}
489
    
490
    /* (non-Javadoc)
491
     * @see org.eclipse.ui.texteditor.TextEditorAction#update()
492
     */
493
    public void update() {
494
        super.update();
495
        if (fDocument != null) {
496
            fDocument.removeDocumentListener(fContentListener);
497
        }
498
        if (fSelectionProvider != null) {
499
            fSelectionProvider.removeSelectionChangedListener(fSelectionListener);
500
        }
501
502
        ITextEditor editor= getTextEditor();
503
        IEditorInput input= editor.getEditorInput();
504
        
505
        fSelectionProvider= editor.getSelectionProvider(); 
506
        fSelectionProvider.addSelectionChangedListener(fSelectionListener);
507
        
508
        IDocument oldDocument= fDocument;
509
        fDocument= editor.getDocumentProvider().getDocument(input);
510
        fDocument.addDocumentListener(fContentListener);
511
        
512
        if (fDocument != oldDocument) {
513
            fLastCompletion= null; // invalidate completion state on editor reuse 
514
        }
515
    }
516
}

Return to bug 11668