[autocomplete] 09/143: Lots of work on parameter assistance. Functions/methods can have descriptions of their return values.

Benjamin Mesing ben at alioth.debian.org
Sat Oct 19 12:53:08 UTC 2013


This is an automated email from the git hooks/post-receive script.

ben pushed a commit to branch master
in repository autocomplete.

commit eb0012afb95483c5241cb8c286ae1bc6777726d7
Author: bobbylight <robert at fifesoft.com>
Date:   Sat Jan 10 22:34:57 2009 +0000

    Lots of work on parameter assistance.  Functions/methods can have descriptions of their return values.
---
 .../autocomplete/AbstractCompletionProvider.java   |  125 +++++++-------------
 .../ui/autocomplete/AutoCompleteDescWindow.java    |   11 +-
 src/org/fife/ui/autocomplete/AutoCompletion.java   |   74 ++++++++++--
 .../fife/ui/autocomplete/CCompletionProvider.java  |   79 +++++++++++--
 .../fife/ui/autocomplete/CompletionProvider.java   |   36 +++++-
 .../ui/autocomplete/CompletionProviderBase.java    |   86 ++++++++++++++
 .../fife/ui/autocomplete/CompletionXMLParser.java  |   22 +++-
 .../ui/autocomplete/DefaultCompletionProvider.java |   29 +++--
 .../fife/ui/autocomplete/FunctionCompletion.java   |   38 +++++-
 .../ParameterizedCompletionDescriptionToolTip.java |  102 ++++++++++++----
 10 files changed, 459 insertions(+), 143 deletions(-)

diff --git a/src/org/fife/ui/autocomplete/AbstractCompletionProvider.java b/src/org/fife/ui/autocomplete/AbstractCompletionProvider.java
index 0e930ff..2ddc480 100644
--- a/src/org/fife/ui/autocomplete/AbstractCompletionProvider.java
+++ b/src/org/fife/ui/autocomplete/AbstractCompletionProvider.java
@@ -27,12 +27,7 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
-import javax.swing.ListCellRenderer;
-import javax.swing.text.BadLocationException;
-import javax.swing.text.Document;
-import javax.swing.text.Element;
 import javax.swing.text.JTextComponent;
-import javax.swing.text.Segment;
 
 
 /**
@@ -44,12 +39,8 @@ import javax.swing.text.Segment;
  * @author Robert Futrell
  * @version 1.0
  */
-public abstract class AbstractCompletionProvider implements CompletionProvider {
-
-	/**
-	 * The parent completion provider.
-	 */
-	private CompletionProvider parent;
+public abstract class AbstractCompletionProvider
+								extends CompletionProviderBase {
 
 	/**
 	 * The completions this provider is aware of.  Subclasses should ensure
@@ -58,41 +49,33 @@ public abstract class AbstractCompletionProvider implements CompletionProvider {
 	protected List completions;
 
 	/**
-	 * The renderer to use for completions from this provider.  If this is
-	 * <code>null</code>, a default renderer is used.
-	 */
-	private ListCellRenderer listCellRenderer;
-
-	/**
 	 * The case-insensitive {@link Completion} comparator.
 	 */
 	private Comparator comparator;
 
 	/**
-	 * Text that marks the beginning of a parameter list, for example, "(".
+	 * Text that marks the beginning of a parameter list, for example, '('.
 	 */
-	private String paramListStart;
+	private char paramListStart;
 
 	/**
-	 * Text that marks the end of a parameter list, for example, ")".
+	 * Text that marks the end of a parameter list, for example, ')'.
 	 */
-	private String paramListEnd;
+	private char paramListEnd;
 
 	/**
 	 * Text that separates items in a parameter list, for example, ", ".
 	 */
 	private String paramListSeparator;
 
-	protected static final String EMPTY_STRING = "";
-
 
 	/**
 	 * Constructor.
 	 */
 	public AbstractCompletionProvider() {
 		comparator = new CaseInsensitiveComparator();
-		paramListStart = "(";
-		paramListEnd = ")";
+		paramListStart = '(';
+		paramListEnd = ')';
 		paramListSeparator = ", ";
 	}
 
@@ -173,44 +156,47 @@ public abstract class AbstractCompletionProvider implements CompletionProvider {
 
 
 	/**
-	 * Returns the first <tt>Completion</tt> in this provider with the
-	 * specified input text.
-	 *
-	 * @param inputText The input text to search for.
-	 * @return The {@link Completion}, or <code>null</code> if there is no such
-	 *         <tt>Completion</tt>.
+	 * {@inheritDoc}
 	 */
-	public Completion getCompletionByInputText(String inputText) {
-		// TODO: Do a binary search for performance
-		for (int i=0; i<completions.size(); i++) {
-			Completion c = (Completion)completions.get(i);
-			if (c.getInputText().equals(inputText)) {
-				return c;
-			}
-		}
-		return null;
+	public void clearParameterizedCompletionParams() {
+		paramListEnd = paramListStart = 0;
+		paramListSeparator = null;
 	}
 
 
 	/**
-	 * {@inheritDoc}
+	 * Returns a list of <tt>Completion</tt>s in this provider with the
+	 * specified input text.
+	 *
+	 * @param inputText The input text to search for.
+	 * @return A list of {@link Completion}s, or <code>null</code> if there
+	 *         are no matching <tt>Completion</tt>s.
 	 */
-	public final List getCompletions(JTextComponent comp) {
-		List completions = getCompletionsImpl(comp);
-		if (parent!=null) {
-			completions.addAll(parent.getCompletions(comp));
-			Collections.sort(completions);
+	public List getCompletionByInputText(String inputText) {
+
+		// Find any entry that matches this input text (there may be > 1).
+		int end = Collections.binarySearch(completions, inputText, comparator);
+		if (end<0) {
+			return null;
+		}
+
+		// There might be multiple entries with the same input text.
+		int start = end;
+		while (start>0 &&
+				comparator.compare(completions.get(start-1), inputText)==0) {
+			start--;
 		}
-		return completions;
+		int count = completions.size();
+		while (++end<count &&
+				comparator.compare(completions.get(end), inputText)==0);
+
+		return completions.subList(start, end); // (inclusive, exclusive)
+
 	}
 
 
 	/**
-	 * Does the dirty work of creating a list of completions.
-	 *
-	 * @param comp The text component to look in.
-	 * @return The list of possible completions, or an empty list if there
-	 *         are none.
+	 * {@inheritDoc}
 	 */
 	protected List getCompletionsImpl(JTextComponent comp) {
 
@@ -242,15 +228,7 @@ public abstract class AbstractCompletionProvider implements CompletionProvider {
 	/**
 	 * {@inheritDoc}
 	 */
-	public ListCellRenderer getListCellRenderer() {
-		return listCellRenderer;
-	}
-
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public String getParameterListEnd() {
+	public char getParameterListEnd() {
 		return paramListEnd;
 	}
 
@@ -266,20 +244,12 @@ public abstract class AbstractCompletionProvider implements CompletionProvider {
 	/**
 	 * {@inheritDoc}
 	 */
-	public String getParameterListStart() {
+	public char getParameterListStart() {
 		return paramListStart;
 	}
 
 
 	/**
-	 * {@inheritDoc}
-	 */
-	public CompletionProvider getParent() {
-		return parent;
-	}
-
-
-	/**
 	 * Removes the specified completion from this provider.  This method
 	 * will not remove completions from the parent provider, if there is one.
 	 *
@@ -304,16 +274,11 @@ public abstract class AbstractCompletionProvider implements CompletionProvider {
 	/**
 	 * {@inheritDoc}
 	 */
-	public void setListCellRenderer(ListCellRenderer r) {
-		listCellRenderer = r;
-	}
-
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public void setParent(CompletionProvider parent) {
-		this.parent = parent;
+	public void setParameterizedCompletionParams(char listStart,
+										String separator, char listEnd) {
+		paramListStart = listStart;
+		paramListSeparator = separator;
+		paramListEnd = listEnd;
 	}
 
 
diff --git a/src/org/fife/ui/autocomplete/AutoCompleteDescWindow.java b/src/org/fife/ui/autocomplete/AutoCompleteDescWindow.java
index 2e30837..60b5794 100644
--- a/src/org/fife/ui/autocomplete/AutoCompleteDescWindow.java
+++ b/src/org/fife/ui/autocomplete/AutoCompleteDescWindow.java
@@ -294,9 +294,16 @@ class AutoCompleteDescWindow extends JWindow implements HyperlinkListener {
 				CompletionProvider p = parent.getSelection().getProvider();
 				if (p instanceof AbstractCompletionProvider) {
 					String name = e.getDescription();
-					Completion c = ((AbstractCompletionProvider)p).
+					List l = ((AbstractCompletionProvider)p).
 										getCompletionByInputText(name);
-					setDescriptionFor(c, true);
+					if (l!=null && !l.isEmpty()) {
+						// Just use the 1st one if there's more than 1
+						Completion c = (Completion)l.get(0);
+						setDescriptionFor(c, true);
+					}
+					else {
+						UIManager.getLookAndFeel().provideErrorFeedback(descArea);
+					}
 				}
 			}
 		}
diff --git a/src/org/fife/ui/autocomplete/AutoCompletion.java b/src/org/fife/ui/autocomplete/AutoCompletion.java
index a7d7ac9..2727327 100644
--- a/src/org/fife/ui/autocomplete/AutoCompletion.java
+++ b/src/org/fife/ui/autocomplete/AutoCompletion.java
@@ -33,6 +33,21 @@ import javax.swing.text.*;
  * Adds autocompletion to a text component.  Provides a popup window with a
  * list of autocomplete choices on a given keystroke, such as Crtrl+Space.<p>
  *
+ * Depending on the {@link CompletionProvider} installed, the following
+ * auto-completion features may be enabled:
+ * 
+ * <ul>
+ *    <li>An auto-complete choices list made visible via e.g. Ctrl+Space</li>
+ *    <li>A "description" window displayed alongside the choices list that
+ *        provides documentation on the currently selected completion choice
+ *        (as seen in Eclipse and NetBeans).</li>
+ *    <li>Parameter assistance.  If this is enabled, if the user enters a
+ *        "parameterized" completion, such as a method or a function, then
+ *        they will receive a tooltip describing the arguments they have to
+ *        enter to the completion.  Also, the arguments can be navigated via
+ *        tab and shift+tab (ala Eclipse and NetBeans).</li>
+ * </ul>
+ *
  * @author Robert Futrell
  * @version 1.0
  */
@@ -100,6 +115,11 @@ public class AutoCompletion implements HierarchyListener {
 	private boolean autoCompleteSingleChoices;
 
 	/**
+	 * Whether parameter assistance is enabled.
+	 */
+	private boolean parameterAssistanceEnabled;
+
+	/**
 	 * The keystroke that triggers the completion window.
 	 */
 	private KeyStroke trigger;
@@ -161,8 +181,11 @@ public class AutoCompletion implements HierarchyListener {
 		// Don't bother with a tooltip if there are no parameters.
 		if (pc.getParamCount()==0) {
 			CompletionProvider p = pc.getProvider();
-			textComponent.replaceSelection(p.getParameterListStart() +
-									p.getParameterListEnd());
+			String text = Character.toString(p.getParameterListEnd());
+			if (addParamListStart) {
+				text = p.getParameterListStart() + text;
+			}
+			textComponent.replaceSelection(text);
 			return;
 		}
 
@@ -381,12 +404,7 @@ public class AutoCompletion implements HierarchyListener {
 		caret.setDot(start);
 		caret.moveDot(dot);
 		textComp.replaceSelection(replacement);
-
-		if (c instanceof ParameterizedCompletion) {
-			ParameterizedCompletion pc = (ParameterizedCompletion)c;
-			displayDescriptionToolTip(pc, true);
-		}
-/*
+		/*
 		Document doc = textComp.getDocument();
 try {
 		if (doc instanceof AbstractDocument) {
@@ -398,6 +416,13 @@ try {
 		}
 } catch (javax.swing.text.BadLocationException ble) { ble.printStackTrace(); }
 */
+
+		if (isParameterAssistanceEnabled() &&
+				(c instanceof ParameterizedCompletion)) {
+			ParameterizedCompletion pc = (ParameterizedCompletion)c;
+			displayDescriptionToolTip(pc, true);
+		}
+
 	}
 
 
@@ -418,6 +443,7 @@ try {
 		this.textComponent = c;
 		installTriggerKey(getTriggerKey());
 
+		// TODO: Fix me
 		InputMap im = c.getInputMap();
 		ActionMap am = c.getActionMap();
 		KeyStroke ks = KeyStroke.getKeyStroke('(');
@@ -427,6 +453,9 @@ try {
 		am.put("AutoCompletion.FunctionStart", new javax.swing.AbstractAction() {
 			public void actionPerformed(java.awt.event.ActionEvent e) {
 				textComponent.replaceSelection("(");
+				if (!isParameterAssistanceEnabled()) {
+					return;
+				}
 				List completions = provider.getParameterizedCompletionsAt(textComponent);
 				if (completions!=null && completions.size()>0) {
 					// TODO: Have tooltip let you select between multiple, like VS
@@ -470,6 +499,17 @@ try {
 
 
 	/**
+	 * Returns whether parameter assistance is enabled.
+	 *
+	 * @return Whether parameter assistance is enabled.
+	 * @see #setParameterAssistanceEnabled(boolean)
+	 */
+	public boolean isParameterAssistanceEnabled() {
+		return parameterAssistanceEnabled;
+	}
+
+
+	/**
 	 * Returns whether the popup window is visible.
 	 *
 	 * @return Whether the popup window is visible.
@@ -620,6 +660,21 @@ try {
 
 
 	/**
+	 * Sets whether parameter assistance is enabled.  If parameter assistance
+	 * is enabled, and a "parameterized" completion (such as a function or
+	 * method) is inserted, the user will get "assistance" in inserting the
+	 * parameters in the form of a popup window with documentation and easy
+	 * tabbing through the arguments (as seen in Eclipse and NetBeans).
+	 *
+	 * @param enabled Whether parameter assistance should be enabled.
+	 * @see #isParameterAssistanceEnabled()
+	 */
+	public void setParameterAssistanceEnabled(boolean enabled) {
+		parameterAssistanceEnabled = enabled;
+	}
+
+
+	/**
 	 * Sets whether the "description window" should be shown beside the
 	 * completion window.
 	 *
@@ -698,6 +753,9 @@ try {
 		if (popupWindow!=null) {
 			popupWindow.updateUI();
 		}
+		if (descToolTip!=null) {
+			descToolTip.updateUI();
+		}
 	}
 
 
diff --git a/src/org/fife/ui/autocomplete/CCompletionProvider.java b/src/org/fife/ui/autocomplete/CCompletionProvider.java
index 258422e..4821122 100644
--- a/src/org/fife/ui/autocomplete/CCompletionProvider.java
+++ b/src/org/fife/ui/autocomplete/CCompletionProvider.java
@@ -51,7 +51,7 @@ import org.fife.ui.rsyntaxtextarea.Token;
  * @author Robert Futrell
  * @version 1.0
  */
-public class CCompletionProvider extends AbstractCompletionProvider{
+public class CCompletionProvider extends CompletionProviderBase {
 
 	/**
 	 * The provider to use when no provider is assigned to a particular token
@@ -83,10 +83,26 @@ public class CCompletionProvider extends AbstractCompletionProvider{
 	 */
 	public CCompletionProvider(CompletionProvider defaultProvider) {
 		setDefaultCompletionProvider(defaultProvider);
-		completions = new ArrayList(0); // TODO: Remove me.
 	}
 
 
+	/**
+	 * Calling this method will result in an
+	 * {@link UnsupportedOperationException} being thrown.  To set the
+	 * parameter completion parameters, do so on the provider returned by
+	 * {@link #getDefaultCompletionProvider()}.
+	 *
+	 * @throws UnsupportedOperationException Always.
+	 * @see #setParameterizedCompletionParams(char, String, char)
+	 */
+	public void clearParameterizedCompletionParams() {
+		throw new UnsupportedOperationException();
+	}
+
+
+	/**
+	 * {@inheritDoc}
+	 */
 	public String getAlreadyEnteredText(JTextComponent comp) {
 		if (!(comp instanceof RSyntaxTextArea)) {
 			return EMPTY_STRING;
@@ -151,12 +167,46 @@ public class CCompletionProvider extends AbstractCompletionProvider{
 	 * {@inheritDoc}
 	 */
 	public List getParameterizedCompletionsAt(JTextComponent tc) {
+		// Parameterized completions can only come from the "code" completion
+		// provider.  We do not do function/method completions while editing
+		// strings or comments.
 		CompletionProvider provider = getProviderFor(tc);
-		return provider!=null ? provider.getParameterizedCompletionsAt(tc) :
-								null;
+		return provider==defaultProvider ?
+				provider.getParameterizedCompletionsAt(tc) : null;
+	}
+
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public char getParameterListEnd() {
+		return defaultProvider.getParameterListEnd();
 	}
 
 
+	/**
+	 * {@inheritDoc}
+	 */
+	public String getParameterListSeparator() {
+		return defaultProvider.getParameterListSeparator();
+	}
+
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public char getParameterListStart() {
+		return defaultProvider.getParameterListStart();
+	}
+
+
+	/**
+	 * Returns the completion provider to use at the current caret position in
+	 * a text component.
+	 *
+	 * @param comp The text component to check.
+	 * @return The completion provider to use.
+	 */
 	private CompletionProvider getProviderFor(JTextComponent comp) {
 
 		RSyntaxTextArea rsta = (RSyntaxTextArea)comp;
@@ -244,9 +294,6 @@ public class CCompletionProvider extends AbstractCompletionProvider{
 	 * @see #getCommentCompletionProvider()
 	 */
 	public void setCommentCompletionProvider(CompletionProvider provider) {
-		if (provider==null) {
-			throw new IllegalArgumentException("provider cannot be null");
-		}
 		this.commentCompletionProvider = provider;
 	}
 
@@ -273,14 +320,26 @@ public class CCompletionProvider extends AbstractCompletionProvider{
 	 * @see #getDocCommentCompletionProvider()
 	 */
 	public void setDocCommentCompletionProvider(CompletionProvider provider) {
-		if (provider==null) {
-			throw new IllegalArgumentException("provider cannot be null");
-		}
 		this.docCommentCompletionProvider = provider;
 	}
 
 
 	/**
+	 * Calling this method will result in an
+	 * {@link UnsupportedOperationException} being thrown.  To set the
+	 * parameter completion parameters, do so on the provider returned by
+	 * {@link #getDefaultCompletionProvider()}.
+	 *
+	 * @throws UnsupportedOperationException Always.
+	 * @see #clearParameterizedCompletionParams()
+	 */
+	public void setParameterizedCompletionParams(char listStart,
+										String separator, char listEnd) {
+		throw new UnsupportedOperationException();
+	}
+
+
+	/**
 	 * Sets the completion provider to use while in a string.
 	 *
 	 * @param provider The provider to use.
diff --git a/src/org/fife/ui/autocomplete/CompletionProvider.java b/src/org/fife/ui/autocomplete/CompletionProvider.java
index f5ebcab..cf51934 100644
--- a/src/org/fife/ui/autocomplete/CompletionProvider.java
+++ b/src/org/fife/ui/autocomplete/CompletionProvider.java
@@ -43,6 +43,16 @@ public interface CompletionProvider {
 
 
 	/**
+	 * Clears the values used to identify and insert "parameterized completions"
+	 * (e.g. functions or methods).  After this method is called, functions and
+	 * methods will not have their parameters auto-completed.
+	 *
+	 * @see #setParameterizedCompletionParams(char, String, char)
+	 */
+	public void clearParameterizedCompletionParams();
+
+
+	/**
 	 * Returns the text just before the current caret position that could be
 	 * the start of something auto-completable.
 	 *
@@ -90,11 +100,12 @@ public interface CompletionProvider {
 	 * function or method.
 	 *
 	 * @return The text for a parameter list end, for example,
-	 *         "<code>)</code>".
+	 *         '<code>)</code>'.
 	 * @see #getParameterListStart()
 	 * @see #getParameterListSeparator()
+	 * @see #setParameterizedCompletionParams(char, String, char)
 	 */
-	public String getParameterListEnd();
+	public char getParameterListEnd();
 
 
 	/**
@@ -104,6 +115,7 @@ public interface CompletionProvider {
 	 *         "<code>, </code>".
 	 * @see #getParameterListStart()
 	 * @see #getParameterListEnd()
+	 * @see #setParameterizedCompletionParams(char, String, char)
 	 */
 	public String getParameterListSeparator();
 
@@ -116,8 +128,9 @@ public interface CompletionProvider {
 	 *         "<code>(</code>".
 	 * @see #getParameterListEnd()
 	 * @see #getParameterListSeparator()
+	 * @see #setParameterizedCompletionParams(char, String, char)
 	 */
-	public String getParameterListStart();
+	public char getParameterListStart();
 
 
 	/**
@@ -139,6 +152,23 @@ public interface CompletionProvider {
 
 
 	/**
+	 * Sets the values used to identify and insert "parameterized completions"
+	 * (e.g. functions or methods).  If this method isn't called, functions
+	 * and methods will not have their parameters auto-completed.
+	 *
+	 * @param listStart The character that marks the beginning of a list of
+	 *        parameters, such as '<tt>(</tt>' in C or Java.
+	 * @param separator Text that should separate parameters in a parameter
+	 *        list when one is inserted.  For example, "<tt>, </tt>".
+	 * @param listEnd The character that marks the end of a list of parameters,
+	 *        such as '<tt>)</tt>' in C or Java.
+	 * @see #clearParameterizedCompletionParams()
+	 */
+	public void setParameterizedCompletionParams(char listStart,
+										String separator, char listEnd);
+
+
+	/**
 	 * Sets the parent completion provider.
 	 *
 	 * @param parent The parent provider.  <code>null</code> means there will
diff --git a/src/org/fife/ui/autocomplete/CompletionProviderBase.java b/src/org/fife/ui/autocomplete/CompletionProviderBase.java
new file mode 100644
index 0000000..fa4632d
--- /dev/null
+++ b/src/org/fife/ui/autocomplete/CompletionProviderBase.java
@@ -0,0 +1,86 @@
+package org.fife.ui.autocomplete;
+
+import java.util.Collections;
+import java.util.List;
+import javax.swing.ListCellRenderer;
+import javax.swing.text.JTextComponent;
+
+
+/**
+ * A base class for all standard completion providers.
+ *
+ * @author Robert Futrell
+ * @version 1.0
+ */
+abstract class CompletionProviderBase implements CompletionProvider {
+
+	/**
+	 * The parent completion provider.
+	 */
+	private CompletionProvider parent;
+
+	/**
+	 * The renderer to use for completions from this provider.  If this is
+	 * <code>null</code>, a default renderer is used.
+	 */
+	private ListCellRenderer listCellRenderer;
+
+	protected static final String EMPTY_STRING = "";
+
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public List getCompletions(JTextComponent comp) {
+		List completions = getCompletionsImpl(comp);
+		if (parent!=null) {
+			completions.addAll(parent.getCompletions(comp));
+			Collections.sort(completions);
+		}
+		return completions;
+	}
+
+
+	/**
+	 * Does the dirty work of creating a list of completions.
+	 *
+	 * @param comp The text component to look in.
+	 * @return The list of possible completions, or an empty list if there
+	 *         are none.
+	 */
+	protected abstract List getCompletionsImpl(JTextComponent comp);
+
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public ListCellRenderer getListCellRenderer() {
+		return listCellRenderer;
+	}
+
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public CompletionProvider getParent() {
+		return parent;
+	}
+
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void setListCellRenderer(ListCellRenderer r) {
+		listCellRenderer = r;
+	}
+
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void setParent(CompletionProvider parent) {
+		this.parent = parent;
+	}
+
+
+}
\ No newline at end of file
diff --git a/src/org/fife/ui/autocomplete/CompletionXMLParser.java b/src/org/fife/ui/autocomplete/CompletionXMLParser.java
index 5102774..5d74e0b 100644
--- a/src/org/fife/ui/autocomplete/CompletionXMLParser.java
+++ b/src/org/fife/ui/autocomplete/CompletionXMLParser.java
@@ -27,6 +27,7 @@ class CompletionXMLParser extends DefaultHandler {
 	private String name;
 	private String type;
 	private String returnType;
+	private StringBuffer returnValDesc;
 	private StringBuffer desc;
 	private String paramName;
 	private String paramType;
@@ -35,6 +36,7 @@ class CompletionXMLParser extends DefaultHandler {
 	private String definedIn;
 	private boolean doingKeywords;
 	private boolean inKeyword;
+	private boolean gettingReturnValDesc;
 	private boolean gettingDesc;
 	private boolean gettingParams;
 	private boolean inParam;
@@ -53,6 +55,7 @@ class CompletionXMLParser extends DefaultHandler {
 		params = new ArrayList(1);
 		desc = new StringBuffer();
 		paramDesc = new StringBuffer();
+		returnValDesc = new StringBuffer();
 	}
 
 
@@ -66,6 +69,9 @@ class CompletionXMLParser extends DefaultHandler {
 		else if (gettingParamDesc) {
 			paramDesc.append(ch, start, length);
 		}
+		else if (gettingReturnValDesc) {
+			returnValDesc.append(ch, start, length);
+		}
 	}
 
 
@@ -78,6 +84,10 @@ class CompletionXMLParser extends DefaultHandler {
 		}
 		fc.setParams(params);
 		fc.setDefinedIn(definedIn);
+		if (returnValDesc.length()>0) {
+			fc.setReturnValueDescription(returnValDesc.toString());
+			returnValDesc.setLength(0);
+		}
 		return fc;
 	}
 
@@ -136,8 +146,8 @@ class CompletionXMLParser extends DefaultHandler {
 				inKeyword = false;
 			}
 			else if (inKeyword) {
-				if ("desc".equals(qName)) {
-					gettingDesc = false;
+				if ("returnValDesc".equals(qName)) {
+					gettingReturnValDesc = false;
 				}
 				else if (gettingParams) {
 					if ("params".equals(qName)) {
@@ -160,6 +170,9 @@ class CompletionXMLParser extends DefaultHandler {
 						}
 					}
 				}
+				else if ("desc".equals(qName)) {
+					gettingDesc = false;
+				}
 			}
 
 		}
@@ -208,7 +221,10 @@ class CompletionXMLParser extends DefaultHandler {
 				inKeyword = true;
 			}
 			else if (inKeyword) {
-				if ("params".equals(qName)) {
+				if ("returnValDesc".equals(qName)) {
+					gettingReturnValDesc = true;
+				}
+				else if ("params".equals(qName)) {
 					gettingParams = true;
 				}
 				else if (gettingParams) {
diff --git a/src/org/fife/ui/autocomplete/DefaultCompletionProvider.java b/src/org/fife/ui/autocomplete/DefaultCompletionProvider.java
index f1737ce..6fe44e4 100644
--- a/src/org/fife/ui/autocomplete/DefaultCompletionProvider.java
+++ b/src/org/fife/ui/autocomplete/DefaultCompletionProvider.java
@@ -125,8 +125,10 @@ public class DefaultCompletionProvider extends AbstractCompletionProvider {
 
 		List list = null;
 
-		String paramListStart = getParameterListStart();
-		if (paramListStart==null) {
+		// If this provider doesn't support parameterized completions,
+		// bail out now.
+		char paramListStart = getParameterListStart();
+		if (paramListStart==0) {
 			return list; // null
 		}
 
@@ -137,7 +139,7 @@ public class DefaultCompletionProvider extends AbstractCompletionProvider {
 		int line = root.getElementIndex(dot);
 		Element elem = root.getElement(line);
 		int offs = elem.getStartOffset();
-		int len = dot - offs - paramListStart.length();
+		int len = dot - offs - 1/*paramListStart.length()*/;
 		if (len<=0) { // Not enough chars on line for a method.
 			return list; // null
 		}
@@ -145,25 +147,34 @@ public class DefaultCompletionProvider extends AbstractCompletionProvider {
 		try {
 
 			doc.getText(offs, len, s);
+
+			// Get the identifier preceeding the '(', ignoring any whitespace
+			// between them.
 			offs = s.offset + len - 1;
 			while (offs>=s.offset && Character.isWhitespace(s.array[offs])) {
 				offs--;
 			}
 			int end = offs;
 			while (offs>=s.offset && isValidChar(s.array[offs])) {
-				System.out.println("... Examining '" + s.array[offs] + "'");
 				offs--;
 			}
 
 			String text = new String(s.array, offs+1, end-offs);
 			System.out.println("... ... \"" + text + "\"");
 
-			Completion c = getCompletionByInputText(text);
-			if (c instanceof ParameterizedCompletion) {
-				if (list==null) {
-					list = new ArrayList(1);
+			// Get a list of all Completions matching the text, but then
+			// narrow it down to just the ParameterizedCompletions.
+			List l = getCompletionByInputText(text);
+			if (l!=null && !l.isEmpty()) {
+				for (int i=0; i<l.size(); i++) {
+					Object o = l.get(i);
+					if (o instanceof ParameterizedCompletion) {
+						if (list==null) {
+							list = new ArrayList(1);
+						}
+						list.add(o);
+					}
 				}
-				list.add(c);
 			}
 
 		} catch (BadLocationException ble) {
diff --git a/src/org/fife/ui/autocomplete/FunctionCompletion.java b/src/org/fife/ui/autocomplete/FunctionCompletion.java
index 31ccfaf..52bdd20 100644
--- a/src/org/fife/ui/autocomplete/FunctionCompletion.java
+++ b/src/org/fife/ui/autocomplete/FunctionCompletion.java
@@ -40,6 +40,11 @@ public class FunctionCompletion extends VariableCompletion
 	 */
 	private List params;
 
+	/**
+	 * A description of the return value of this function.
+	 */
+	private String returnValDesc;
+
 
 	/**
 	 * Constructor.
@@ -68,8 +73,11 @@ public class FunctionCompletion extends VariableCompletion
 	 */
 	protected void addParameters(StringBuffer sb) {
 
+		// TODO: Localize me
+		// TODO: Use tables (?) to improve indentation of long descriptions
+
 		if (params!=null && params.size()>0) {
-			sb.append("<b>Parameters:</b><br>"); // TODO: Localize me
+			sb.append("<b>Parameters:</b><br>");
 			for (int i=0; i<getParamCount(); i++) {
 				Parameter param = getParam(i);
 				sb.append("   <b>");
@@ -85,7 +93,11 @@ public class FunctionCompletion extends VariableCompletion
 			sb.append("<br><br>");
 		}
 
-		// TODO: Add description of return type.
+		if (returnValDesc!=null) {
+			sb.append("<b>Returns:</b><br>   ");
+			sb.append(returnValDesc);
+			sb.append("<br><br>");
+		}
 
 	}
 
@@ -162,6 +174,17 @@ public class FunctionCompletion extends VariableCompletion
 
 
 	/**
+	 * Returns the description of the return value of this function.
+	 *
+	 * @return The description, or <code>null</code> if there is none.
+	 * @see #setReturnValueDescription(String)
+	 */
+	public String getReturnValueDescription() {
+		return returnValDesc;
+	}
+
+
+	/**
 	 * {@inheritDoc}
 	 */
 	public String getSummary() {
@@ -188,4 +211,15 @@ public class FunctionCompletion extends VariableCompletion
 	}
 
 
+	/**
+	 * Sets the description of the return value of this function.
+	 *
+	 * @param desc The description.
+	 * @see #getReturnValueDescription()
+	 */
+	public void setReturnValueDescription(String desc) {
+		this.returnValDesc = desc;
+	}
+
+
 }
\ No newline at end of file
diff --git a/src/org/fife/ui/autocomplete/ParameterizedCompletionDescriptionToolTip.java b/src/org/fife/ui/autocomplete/ParameterizedCompletionDescriptionToolTip.java
index 9a43069..881af58 100644
--- a/src/org/fife/ui/autocomplete/ParameterizedCompletionDescriptionToolTip.java
+++ b/src/org/fife/ui/autocomplete/ParameterizedCompletionDescriptionToolTip.java
@@ -45,10 +45,12 @@ import javax.swing.InputMap;
 import javax.swing.JLabel;
 import javax.swing.JWindow;
 import javax.swing.KeyStroke;
+import javax.swing.SwingUtilities;
 import javax.swing.UIManager;
 import javax.swing.event.CaretEvent;
 import javax.swing.event.CaretListener;
 import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
 import javax.swing.text.Highlighter;
 import javax.swing.text.JTextComponent;
 import javax.swing.text.Position;
@@ -226,15 +228,13 @@ class ParameterizedCompletionDescriptionToolTip {
 		oldEscapeAction = am.get(IM_KEY_ESCAPE);
 		am.put(IM_KEY_ESCAPE, new HideAction());
 
-		String end = pc.getProvider().getParameterListEnd();
-		if (end.length()==1) { // Practically always true, usually ')'
-			char ch = end.charAt(0);
-			ks = KeyStroke.getKeyStroke(ch);
-			oldClosingKey = im.get(ks);
-			im.put(ks, IM_KEY_CLOSING);
-			oldClosingAction = am.get(IM_KEY_CLOSING);
-			am.put(IM_KEY_CLOSING, new ClosingAction());
-		}
+		char end = pc.getProvider().getParameterListEnd();
+		ks = KeyStroke.getKeyStroke(end);
+		oldClosingKey = im.get(ks);
+		im.put(ks, IM_KEY_CLOSING);
+		oldClosingAction = am.get(IM_KEY_CLOSING);
+		am.put(IM_KEY_CLOSING, new ClosingAction());
+
 	}
 
 
@@ -251,7 +251,7 @@ class ParameterizedCompletionDescriptionToolTip {
 		int tagCount = tags.size();
 		if (tagCount==0) {
 			tc.setCaretPosition(maxPos.getOffset());
-			tooltip.setVisible(false);
+			setVisible(false, false);
 		}
 
 		Highlight currentNext = null;
@@ -275,7 +275,7 @@ class ParameterizedCompletionDescriptionToolTip {
 		}
 		else {
 			tc.setCaretPosition(maxPos.getOffset());
-			tooltip.setVisible(false);
+			setVisible(false, false);
 		}
 
 	}
@@ -293,7 +293,7 @@ class ParameterizedCompletionDescriptionToolTip {
 		int tagCount = tags.size();
 		if (tagCount==0) { // Should never happen
 			tc.setCaretPosition(maxPos.getOffset());
-			tooltip.setVisible(false);
+			setVisible(false, false);
 		}
 
 		int dot = tc.getCaretPosition();
@@ -322,7 +322,7 @@ class ParameterizedCompletionDescriptionToolTip {
 		}
 		else {
 			tc.setCaretPosition(maxPos.getOffset());
-			tooltip.setVisible(false);
+			setVisible(false, false);
 		}
 
 	}
@@ -417,13 +417,10 @@ class ParameterizedCompletionDescriptionToolTip {
 		im.put(ks, oldEscapeKey);
 		am.put(IM_KEY_ESCAPE, oldEscapeAction);
 
-		String end = pc.getProvider().getParameterListEnd();
-		if (end.length()==1) { // Practically always true, usually ')'
-			char ch = end.charAt(0);
-			ks = KeyStroke.getKeyStroke(ch);
-			im.put(ks, oldClosingKey);
-			am.put(IM_KEY_CLOSING, oldClosingAction);
-		}
+		char end = pc.getProvider().getParameterListEnd();
+		ks = KeyStroke.getKeyStroke(end);
+		im.put(ks, oldClosingKey);
+		am.put(IM_KEY_CLOSING, oldClosingAction);
 
 	}
 
@@ -486,6 +483,16 @@ class ParameterizedCompletionDescriptionToolTip {
 			}
 		}
 
+		if (selectedParam>=0 && selectedParam<paramCount) {
+			ParameterizedCompletion.Parameter param =
+							pc.getParam(selectedParam);
+			String desc = param.getDescription();
+			if (desc!=null) {
+				sb.append("<br>");
+				sb.append(desc);
+			}
+		}
+
 		descLabel.setText(sb.toString());
 		tooltip.pack();
 
@@ -493,6 +500,15 @@ class ParameterizedCompletionDescriptionToolTip {
 
 
 	/**
+	 * Updates the <tt>LookAndFeel</tt> of this window and the description
+	 * window.
+	 */
+	public void updateUI() {
+		SwingUtilities.updateComponentTreeUI(tooltip);
+	}
+
+
+	/**
 	 * Called when the user types the character marking the closing of the
 	 * parameter list, such as '<code>)</code>'.
 	 *
@@ -503,8 +519,42 @@ class ParameterizedCompletionDescriptionToolTip {
 
 		public void actionPerformed(ActionEvent e) {
 			JTextComponent tc = ac.getTextComponent();
-			tc.setCaretPosition(maxPos.getOffset());
-			tooltip.setVisible(false);
+			int dot = tc.getCaretPosition();
+			if (dot>=maxPos.getOffset()-1) { // ">=" for overwrite mode
+				if (dot==maxPos.getOffset()) { // Happens in overwrite mode
+					char ch = pc.getProvider().getParameterListEnd();
+					tc.replaceSelection(Character.toString(ch));
+				}
+				else {
+					tc.setCaretPosition(maxPos.getOffset());
+				}
+				setVisible(false, false);
+			}
+			else {
+				char ch = pc.getProvider().getParameterListEnd();
+				tc.replaceSelection(Character.toString(ch));
+			}
+		}
+
+		public String getArgumentText(int arg) {
+			if (arg<0 || arg>=pc.getParamCount()) {
+				return null;
+			}
+			List paramHighlights = getParameterHighlights();
+			if (paramHighlights==null || arg>=paramHighlights.size()) {
+				return null;
+			}
+			Highlight h = (Highlight)paramHighlights.get(arg);
+			int len = h.getEndOffset() - h.getStartOffset();
+			JTextComponent tc = ac.getTextComponent();
+			Document doc = tc.getDocument();
+			try {
+				return doc.getText(h.getStartOffset(), len);
+			} catch (BadLocationException ble) {
+				UIManager.getLookAndFeel().provideErrorFeedback(tc);
+				ble.printStackTrace();
+				return null;
+			}
 		}
 
 	}
@@ -519,7 +569,7 @@ class ParameterizedCompletionDescriptionToolTip {
 	private class HideAction extends AbstractAction {
 
 		public void actionPerformed(ActionEvent e) {
-			tooltip.setVisible(false);
+			setVisible(false, false);
 		}
 
 	}
@@ -541,11 +591,11 @@ class ParameterizedCompletionDescriptionToolTip {
 		 */
 		public void caretUpdate(CaretEvent e) {
 			if (maxPos==null) { // Sanity check
-				tooltip.setVisible(false);
+				setVisible(false, false);
 			}
 			int dot = e.getDot();
 			if (dot<minPos || dot>maxPos.getOffset()) {
-				tooltip.setVisible(false);
+				setVisible(false, false);
 			}
 			updateText();
 		}
@@ -567,7 +617,7 @@ class ParameterizedCompletionDescriptionToolTip {
 		 * @param e The event.
 		 */
 		public void focusLost(FocusEvent e) {
-			tooltip.setVisible(false);
+			setVisible(false, false);
 		}
 
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/autocomplete.git



More information about the pkg-java-commits mailing list