Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 17032 Details for
Bug 11668
Add emacs-style "Alt-/" hippie auto completion
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
[patch]
HippieCompletion.diff against org.eclipse.ui.workbench.texteditor
HippieCompletion.diff (text/plain), 15.89 KB, created by
Tom Hofmann
on 2005-01-10 11:13:04 EST
(
hide
)
Description:
HippieCompletion.diff against org.eclipse.ui.workbench.texteditor
Filename:
MIME Type:
Creator:
Tom Hofmann
Created:
2005-01-10 11:13:04 EST
Size:
15.89 KB
patch
obsolete
>Index: plugin.properties >=================================================================== >RCS file: /home/eclipse/org.eclipse.ui.workbench.texteditor/plugin.properties,v >retrieving revision 1.27 >diff -u -r1.27 plugin.properties >--- plugin.properties 7 Jan 2005 15:53:43 -0000 1.27 >+++ plugin.properties 10 Jan 2005 16:04:34 -0000 >@@ -152,6 +152,8 @@ > command.toggleOverwrite.name = Toggle Overwrite > command.toggleInsertMode.description = Toggle insert mode > command.toggleInsertMode.name = Toggle Insert Mode >+command.emacsCompletion.description = Context insensitive completion >+command.emacsCompletion.name = Text Completion > command.windowEnd.description = Go to the end of the window > command.windowEnd.name = Window End > command.windowStart.description = Go to the start of the window >Index: plugin.xml >=================================================================== >RCS file: /home/eclipse/org.eclipse.ui.workbench.texteditor/plugin.xml,v >retrieving revision 1.61 >diff -u -r1.61 plugin.xml >--- plugin.xml 7 Jan 2005 15:53:43 -0000 1.61 >+++ plugin.xml 10 Jan 2005 16:04:34 -0000 >@@ -426,6 +426,18 @@ > categoryId="org.eclipse.ui.category.edit" > id="org.eclipse.ui.edit.text.toggleInsertMode"> > </command> >+ <command >+ name="%command.emacsCompletion.name" >+ description="%command.emacsCompletion.description" >+ categoryId="org.eclipse.ui.category.edit" >+ id="org.eclipse.ui.edit.text.emacsCompletion"> >+ </command> >+ <keyBinding >+ commandId="org.eclipse.ui.edit.text.emacsCompletion" >+ contextId="org.eclipse.ui.textEditorScope" >+ keySequence="Alt+/" >+ keyConfigurationId="org.eclipse.ui.defaultAcceleratorConfiguration"> >+ </keyBinding> > > <keyBinding > commandId="org.eclipse.ui.edit.text.delete.line" >Index: src/org/eclipse/ui/texteditor/AbstractTextEditor.java >=================================================================== >RCS file: /home/eclipse/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/AbstractTextEditor.java,v >retrieving revision 1.154 >diff -u -r1.154 AbstractTextEditor.java >--- src/org/eclipse/ui/texteditor/AbstractTextEditor.java 5 Jan 2005 16:59:48 -0000 1.154 >+++ src/org/eclipse/ui/texteditor/AbstractTextEditor.java 10 Jan 2005 16:04:35 -0000 >@@ -4282,6 +4282,11 @@ > action.setActionDefinitionId(ITextEditorActionDefinitionIds.TOGGLE_INSERT_MODE); > setAction(ITextEditorActionConstants.TOGGLE_INSERT_MODE, action); > >+ action = new EmacsCompleteAction(EditorMessages.getResourceBundle(), "Editor.EmacsCompletion.", this); //$NON-NLS-1$ >+ // TODO action.setHelpContextId(IAbstractTextEditorHelpContextIds.EMACS_COMPLETION_ACTION); >+ action.setActionDefinitionId(ITextEditorActionDefinitionIds.EMACS_COMPLETION); >+ setAction(ITextEditorActionConstants.EMACS_COMPLETION, action); >+ > PropertyDialogAction openProperties= new PropertyDialogAction( > getSite().getShell(), > new ISelectionProvider() { >Index: src/org/eclipse/ui/texteditor/ITextEditorActionConstants.java >=================================================================== >RCS file: /home/eclipse/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/ITextEditorActionConstants.java,v >retrieving revision 1.19 >diff -u -r1.19 ITextEditorActionConstants.java >--- src/org/eclipse/ui/texteditor/ITextEditorActionConstants.java 8 Dec 2004 15:06:02 -0000 1.19 >+++ src/org/eclipse/ui/texteditor/ITextEditorActionConstants.java 10 Jan 2005 16:04:35 -0000 >@@ -517,4 +517,11 @@ > * @since 3.1 > */ > static final String QUICKDIFF_TOGGLE= "QuickDiff.Toggle"; //$NON-NLS-1$ >+ >+ /** >+ * Name of the action for emacs style completion. >+ * Value: <code>"EMACS_COMPLETION"</code> >+ * @since 3.1 >+ */ >+ static final String EMACS_COMPLETION= "EMACS_COMPLETION"; //$NON-NLS-1$ > } >Index: src/org/eclipse/ui/texteditor/ITextEditorActionDefinitionIds.java >=================================================================== >RCS file: /home/eclipse/org.eclipse.ui.workbench.texteditor/src/org/eclipse/ui/texteditor/ITextEditorActionDefinitionIds.java,v >retrieving revision 1.18 >diff -u -r1.18 ITextEditorActionDefinitionIds.java >--- src/org/eclipse/ui/texteditor/ITextEditorActionDefinitionIds.java 8 Dec 2004 15:06:02 -0000 1.18 >+++ src/org/eclipse/ui/texteditor/ITextEditorActionDefinitionIds.java 10 Jan 2005 16:04:35 -0000 >@@ -485,4 +485,11 @@ > * @since 3.1 > */ > static final String LINENUMBER_TOGGLE= "org.eclipse.ui.editors.lineNumberToggle"; //$NON-NLS-1$ >+ >+ /** >+ * Action definition ID of the edit -> text complete action >+ * Value: <code>"org.eclipse.ui.edit.text.emacsCompletion"</code>). >+ * @since 3.1 >+ */ >+ public static final String EMACS_COMPLETION= "org.eclipse.ui.edit.text.emacsCompletion"; //$NON-NLS-1$ > } >Index: src/org/eclipse/ui/texteditor/EmacsCompleteAction.java >=================================================================== >RCS file: src/org/eclipse/ui/texteditor/EmacsCompleteAction.java >diff -N src/org/eclipse/ui/texteditor/EmacsCompleteAction.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/ui/texteditor/EmacsCompleteAction.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,360 @@ >+/******************************************************************************* >+ * Copyright (c) 2000, 2005 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Common Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/cpl-v10.html >+ * >+ * Contributors: >+ * Genady Beryozkin, me@genady.org - initial API and implementation >+ * IBM Corporation - fixes and cleaning >+ *******************************************************************************/ >+package org.eclipse.ui.texteditor; >+ >+import java.util.ArrayList; >+import java.util.HashSet; >+import java.util.Iterator; >+import java.util.LinkedList; >+import java.util.ResourceBundle; >+ >+import org.eclipse.jface.viewers.ISelectionChangedListener; >+import org.eclipse.jface.viewers.SelectionChangedEvent; >+ >+import org.eclipse.jface.text.BadLocationException; >+import org.eclipse.jface.text.DocumentEvent; >+import org.eclipse.jface.text.FindReplaceDocumentAdapter; >+import org.eclipse.jface.text.IDocument; >+import org.eclipse.jface.text.IDocumentListener; >+import org.eclipse.jface.text.IRegion; >+import org.eclipse.jface.text.ITextSelection; >+ >+import org.eclipse.ui.IEditorInput; >+import org.eclipse.ui.IEditorPart; >+import org.eclipse.ui.IEditorReference; >+ >+/** >+ * This class implements the emacs style completion action. >+ * Completion action is a stateful action, as the user may invoke >+ * it several times in a row in order to scroll the possible completions. >+ * >+ * >+ * TODO: Work on backward suggestions >+ * TODO: Sort by editor type >+ * TODO: Provide history option >+ * >+ * @author Genady Beryozkin, me@genady.org >+ */ >+public class EmacsCompleteAction extends TextEditorAction { >+ >+ private IDocument doc; >+ >+ /** >+ * The completion state to continue >+ * the iteration over suggestions >+ */ >+ private CompletionState lastCompletion = null; >+ >+ private boolean modifyingLock = false; >+ >+ SelectionChangeListener selectionListener; >+ DocumentChangeListerner contentListener; >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.ui.texteditor.TextEditorAction#setEditor(org.eclipse.ui.texteditor.ITextEditor) >+ */ >+ public void setEditor(ITextEditor editor) { >+ ITextEditor old= getTextEditor(); >+ if (old != null) { >+ old.getSelectionProvider().removeSelectionChangedListener(selectionListener); >+ doc.removeDocumentListener(contentListener); >+ } >+ super.setEditor(editor); >+ >+ selectionListener = new SelectionChangeListener(); >+ contentListener = new DocumentChangeListerner(); >+ >+ IEditorInput input = editor.getEditorInput(); >+ doc = editor.getDocumentProvider().getDocument(input); >+ editor.getSelectionProvider().addSelectionChangedListener(selectionListener); >+ doc.addDocumentListener(contentListener); >+ } >+ >+ class SelectionChangeListener implements ISelectionChangedListener { >+ public void selectionChanged(SelectionChangedEvent event) { >+ if (!modifyingLock) { >+ lastCompletion = null; >+ } >+ } >+ } >+ >+ class DocumentChangeListerner implements IDocumentListener { >+ public void documentAboutToBeChanged(DocumentEvent event) { >+ } >+ >+ public void documentChanged(DocumentEvent event) { >+ if (!modifyingLock) { >+ lastCompletion = null; >+ } >+ } >+ } >+ >+ /** >+ * Perform the next completion. >+ */ >+ private void completeNext() { >+ // we don't wish to receive events on our own changes >+ modifyingLock = true; >+ >+ try { >+ doc.replace(lastCompletion.startOffset, lastCompletion.length, >+ lastCompletion.suggestions[lastCompletion.nextSuggestion]); >+ } catch (BadLocationException e) { >+ // we should never get here >+ throw new IllegalStateException(e.toString()); >+ } >+ >+ // advance the suggestion state >+ lastCompletion.advance(); >+ >+ // move the cursor to the insertion point >+ ((AbstractTextEditor) getTextEditor()).getSourceViewer().setSelectedRange(lastCompletion.startOffset+lastCompletion.length, 0); >+ >+ // allow changes >+ modifyingLock = false; >+ } >+ >+ >+ /** >+ * This class represents the state of the last completion process. >+ * Each time the user moves to a new position and calls this action >+ * an instance of this inner classs is created and saved in >+ * {@link #lastCompletion}. >+ */ >+ private static class CompletionState { >+ >+ /** The list of suggestions that was computed when the completion >+ * action was first invoked >+ */ >+ final String[] suggestions; >+ >+ /** The caret position at which we insert the suggestions */ >+ final int startOffset; >+ >+ /** The length of the last suggestion string */ >+ int length; >+ >+ /** The index of next suggestion (index into the suggestion array) */ >+ int nextSuggestion; >+ >+ CompletionState(String[] suggestions, int startOffset) { >+ this.suggestions = suggestions; >+ this.startOffset = startOffset; >+ length = 0; >+ nextSuggestion = 0; >+ } >+ >+ public void advance() { >+ length = suggestions[nextSuggestion].length(); >+ nextSuggestion = (nextSuggestion + 1) % suggestions.length; >+ } >+ } >+ >+ /** >+ * @param bundle the resource bundle >+ * @param prefix a prefix to be prepended to the various resource keys >+ * (described in <code>ResourceAction</code> constructor), or >+ * <code>null</code> if none >+ * @param editor the text editor >+ */ >+ protected EmacsCompleteAction(ResourceBundle bundle, String prefix, ITextEditor editor) { >+ super(bundle, prefix, editor); >+ } >+ >+ /* (non-Javadoc) >+ * @see org.eclipse.jface.action.Action#run() >+ */ >+ public void run() { >+ if (lastCompletion != null) >+ { >+ completeNext(); >+ return; >+ } >+ String prefix = getCurrentPrefix(); >+ if (prefix == null) { >+ getTextEditor().getSite().getShell().getDisplay().beep(); >+ return; >+ } >+ String[] suggestions = getSuggestions(prefix); >+ >+ // if it is single empty suggestion >+ if (suggestions.length == 1) { >+ getTextEditor().getSite().getShell().getDisplay().beep(); >+ return; >+ } >+ lastCompletion = new CompletionState(suggestions, >+ ((ITextSelection) getTextEditor().getSelectionProvider().getSelection()).getOffset()); >+ completeNext(); >+ } >+ >+ >+ /** >+ * Create the array of suggestions. It scan all open text editors >+ * and prefers suggestion from the currently open editor. >+ * It also addes the empty suggestion at the end. >+ * >+ * @param currEditor The current editor >+ */ >+ public String[] getSuggestions(String prefix) { >+ >+ // Change the order of open editors, to make the active editor >+ // to appear first. >+ IEditorReference editorsArray[] = getTextEditor().getSite().getWorkbenchWindow().getActivePage().getEditorReferences(); >+ ArrayList editorsVector = new ArrayList(); >+ for (int i = 0; i < editorsArray.length; i++) { >+ IEditorPart realEditor = editorsArray[i].getEditor(false); >+ if (realEditor != null) { >+ editorsVector.add(realEditor); >+ } >+ } >+ editorsVector.remove(getTextEditor()); >+ editorsVector.add(0, getTextEditor()); >+ >+ // collect the suggestions from all open text editors >+ LinkedList suggestions = new LinkedList(); >+ for (int i = 0; i < editorsVector.size(); i++) { >+ if (editorsVector.get(i) instanceof ITextEditor) { >+ ITextEditor textEditor = (ITextEditor) editorsVector.get(i); >+ IEditorInput input = textEditor.getEditorInput(); >+ IDocument doc = textEditor.getDocumentProvider().getDocument(input); >+ >+ try { >+ suggestions.addAll(getForwardSuggestions(doc, prefix)); >+ } catch (BadLocationException e) { >+ // TODO Auto-generated catch block >+ e.printStackTrace(); >+ } >+ } >+ } >+ >+ makeUnique(suggestions); >+ >+ suggestions.add(""); // empty suggestion >+ return (String[])suggestions.toArray(new String[0]); >+ } >+ >+ >+ /** >+ * Remove duplicate suggestions, leaving the closest to list head. >+ * @param suggestions >+ */ >+ private void makeUnique(LinkedList suggestions) { >+ HashSet seenAlready = new HashSet(); >+ >+ for (Iterator i = suggestions.iterator(); i.hasNext();) { >+ String suggestion = (String) i.next(); >+ if (seenAlready.contains(suggestion)) { >+ i.remove(); >+ } else { >+ seenAlready.add(suggestion); >+ } >+ } >+ } >+ >+ /** >+ * Copied from {@link FindReplaceDocumentAdapter}. >+ * >+ * Converts a non-regex string to a pattern >+ * that can be used with the regex search engine. >+ * >+ * @param string the non-regex pattern >+ * @return the string converted to a regex pattern >+ */ >+ private static String asRegPattern(String string) { >+ StringBuffer out= new StringBuffer(string.length()); >+ boolean quoting= false; >+ >+ for (int i= 0, length= string.length(); i < length; i++) { >+ char ch= string.charAt(i); >+ if (ch == '\\') { >+ if (quoting) { >+ out.append("\\E"); //$NON-NLS-1$ >+ quoting= false; >+ } >+ out.append("\\\\"); //$NON-NLS-1$ >+ continue; >+ } >+ if (!quoting) { >+ out.append("\\Q"); //$NON-NLS-1$ >+ quoting= true; >+ } >+ out.append(ch); >+ } >+ if (quoting) >+ out.append("\\E"); //$NON-NLS-1$ >+ >+ return out.toString(); >+ } >+ >+ >+ /** >+ * Return the list of completion suggestions the correspond to the provided >+ * prefix >+ * >+ * @param document >+ * @param prefix >+ * @return >+ * @throws BadLocationException >+ */ >+ private static ArrayList getForwardSuggestions(IDocument document, String prefix) throws BadLocationException { >+ ArrayList res = new ArrayList(); >+ >+ FindReplaceDocumentAdapter searcher = new >+ FindReplaceDocumentAdapter(document); >+ >+ // search only at word boundaries >+ String searchPattern = "\\b" + asRegPattern(prefix); >+ >+ IRegion reg = searcher.find(0, searchPattern, true, true, false, true); >+ while (reg != null) { >+ // try to complete to a word >+ IRegion word = searcher.find(reg.getOffset(), "\\w+", true, true, false, true); >+ if (word.getLength() > reg.getLength() ) { // empty suggestion will be added later >+ String found = document.get(word.getOffset(), word.getLength()); >+ res.add(found.substring(prefix.length())); >+ } >+ int nextPos = word.getOffset() + word.getLength(); >+ if (nextPos >= document.getLength() ) { >+ break; >+ } >+ reg = searcher.find(nextPos, searchPattern, true, true, false, true); >+ } >+ >+ return res; >+ } >+ >+ /** >+ * Return the part of a word before the caret. >+ * If the caret is not at a middle/end of a word, >+ * returns null. >+ */ >+ public String getCurrentPrefix() { >+ ITextSelection selection = (ITextSelection) getTextEditor().getSelectionProvider().getSelection(); >+ if (selection.getLength() > 0) { >+ return null; >+ } >+ int pos = selection.getOffset(); >+ String docText = doc.get(); >+ int prevNonAlpha = pos; >+ while (prevNonAlpha > 0 && >+ Character.isJavaIdentifierPart(docText.charAt(prevNonAlpha-1))) >+ { >+ prevNonAlpha--; >+ } >+ if (prevNonAlpha != pos) { >+ return docText.substring(prevNonAlpha, pos); >+ } else { >+ return null; >+ } >+ >+ } >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 11668
:
806
|
14942
|
17032
|
17127
|
17183
|
17184
|
17243
|
17310