[autocomplete] 08/143: Adding parameter support when typing a function or method. Like Eclipse, arguments are pre-filled in and you can tab through them, and there is a tooltip listing the parameters to enter.

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 aa4fa8ef4ea7391c9f68506d7140d1999eedd0a0
Author: bobbylight <robert at fifesoft.com>
Date:   Fri Jan 9 23:41:35 2009 +0000

    Adding parameter support when typing a function or method.  Like Eclipse, arguments are pre-filled in and you can tab through them, and there is a tooltip listing the parameters to enter.
---
 .../autocomplete/AbstractCompletionProvider.java   |   46 ++
 .../ui/autocomplete/AutoCompleteDescWindow.java    |    2 +-
 src/org/fife/ui/autocomplete/AutoCompletion.java   |   81 +++
 .../fife/ui/autocomplete/CCompletionProvider.java  |   11 +
 .../ui/autocomplete/CompletionCellRenderer.java    |    7 +-
 .../fife/ui/autocomplete/CompletionProvider.java   |   47 ++
 .../ui/autocomplete/DefaultCompletionProvider.java |   57 ++
 .../fife/ui/autocomplete/FunctionCompletion.java   |  136 ++--
 .../ui/autocomplete/JarCompletionProvider.java     |    8 +
 .../fife/ui/autocomplete/MarkupTagCompletion.java  |    2 +-
 .../ui/autocomplete/OutlineHighlightPainter.java   |  133 ++++
 .../ui/autocomplete/ParameterizedCompletion.java   |   92 +++
 .../ParameterizedCompletionDescriptionToolTip.java |  721 ++++++++++++++++++++
 13 files changed, 1253 insertions(+), 90 deletions(-)

diff --git a/src/org/fife/ui/autocomplete/AbstractCompletionProvider.java b/src/org/fife/ui/autocomplete/AbstractCompletionProvider.java
index 3d9f5fe..0e930ff 100644
--- a/src/org/fife/ui/autocomplete/AbstractCompletionProvider.java
+++ b/src/org/fife/ui/autocomplete/AbstractCompletionProvider.java
@@ -28,7 +28,11 @@ 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;
 
 
 /**
@@ -64,6 +68,21 @@ public abstract class AbstractCompletionProvider implements CompletionProvider {
 	 */
 	private Comparator comparator;
 
+	/**
+	 * Text that marks the beginning of a parameter list, for example, "(".
+	 */
+	private String paramListStart;
+
+	/**
+	 * Text that marks the end of a parameter list, for example, ")".
+	 */
+	private String paramListEnd;
+
+	/**
+	 * Text that separates items in a parameter list, for example, ", ".
+	 */
+	private String paramListSeparator;
+
 	protected static final String EMPTY_STRING = "";
 
 
@@ -72,6 +91,9 @@ public abstract class AbstractCompletionProvider implements CompletionProvider {
 	 */
 	public AbstractCompletionProvider() {
 		comparator = new CaseInsensitiveComparator();
+		paramListStart = "(";
+		paramListEnd = ")";
+		paramListSeparator = ", ";
 	}
 
 
@@ -228,6 +250,30 @@ public abstract class AbstractCompletionProvider implements CompletionProvider {
 	/**
 	 * {@inheritDoc}
 	 */
+	public String getParameterListEnd() {
+		return paramListEnd;
+	}
+
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public String getParameterListSeparator() {
+		return paramListSeparator;
+	}
+
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public String getParameterListStart() {
+		return paramListStart;
+	}
+
+
+	/**
+	 * {@inheritDoc}
+	 */
 	public CompletionProvider getParent() {
 		return parent;
 	}
diff --git a/src/org/fife/ui/autocomplete/AutoCompleteDescWindow.java b/src/org/fife/ui/autocomplete/AutoCompleteDescWindow.java
index 17bd894..2e30837 100644
--- a/src/org/fife/ui/autocomplete/AutoCompleteDescWindow.java
+++ b/src/org/fife/ui/autocomplete/AutoCompleteDescWindow.java
@@ -267,7 +267,7 @@ class AutoCompleteDescWindow extends JWindow implements HyperlinkListener {
 	 * @param e The event.
 	 */
 	public void hyperlinkUpdate(HyperlinkEvent e) {
-System.out.println(descArea.isEnabled() + ", " + e);
+
 		HyperlinkEvent.EventType type = e.getEventType();
 
 		if (type.equals(HyperlinkEvent.EventType.ACTIVATED)) {
diff --git a/src/org/fife/ui/autocomplete/AutoCompletion.java b/src/org/fife/ui/autocomplete/AutoCompletion.java
index e2f3677..a7d7ac9 100644
--- a/src/org/fife/ui/autocomplete/AutoCompletion.java
+++ b/src/org/fife/ui/autocomplete/AutoCompletion.java
@@ -60,6 +60,11 @@ public class AutoCompletion implements HierarchyListener {
 	private AutoCompletePopupWindow popupWindow;
 
 	/**
+	 * A "tooltip" describing a function just entered.
+	 */
+	private ParameterizedCompletionDescriptionToolTip descToolTip;
+
+	/**
 	 * Provides the completion options relevant to the current caret position.
 	 */
 	private CompletionProvider provider;
@@ -140,6 +145,47 @@ public class AutoCompletion implements HierarchyListener {
 
 
 	/**
+	 * Displays a "tooltip" detailing the inputs to the function just entered.
+	 *
+	 * @param pc The completion.
+	 * @param addParamListStart Whether or not
+	 *        {@link CompletionProvider#getParameterListStart()} should be
+	 *        added to the text component.
+	 */
+	private void displayDescriptionToolTip(ParameterizedCompletion pc,
+										boolean addParamListStart) {
+
+		// Get rid of the previous tooltip window, if there is one.
+		hideToolTipWindow();
+
+		// 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());
+			return;
+		}
+
+		descToolTip = new ParameterizedCompletionDescriptionToolTip(
+													parentWindow, this, pc);
+		try {
+			int dot = textComponent.getCaretPosition();
+			Rectangle r = textComponent.modelToView(dot);
+			Point p = new Point(r.x, r.y);
+			SwingUtilities.convertPointToScreen(p, textComponent);
+			r.x = p.x;
+			r.y = p.y;
+			descToolTip.setLocationRelativeTo(r);
+			descToolTip.setVisible(true, addParamListStart);
+		} catch (BadLocationException ble) { // Should never happen
+			UIManager.getLookAndFeel().provideErrorFeedback(textComponent);
+			ble.printStackTrace();
+		}
+
+	}
+
+
+	/**
 	 * Displays the popup window.  Hosting applications can call this method
 	 * to programmatically begin an auto-completion operation.
 	 */
@@ -306,6 +352,14 @@ public class AutoCompletion implements HierarchyListener {
 	}
 
 
+	private void hideToolTipWindow() {
+		if (descToolTip!=null) {
+			descToolTip.setVisible(false, false);
+			descToolTip = null;
+		}
+	}
+
+
 	/**
 	 * Inserts a completion.
 	 *
@@ -327,6 +381,11 @@ 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 {
@@ -359,6 +418,24 @@ try {
 		this.textComponent = c;
 		installTriggerKey(getTriggerKey());
 
+		InputMap im = c.getInputMap();
+		ActionMap am = c.getActionMap();
+		KeyStroke ks = KeyStroke.getKeyStroke('(');
+		Object oldParenKey = im.get(ks);
+		im.put(ks, "AutoCompletion.FunctionStart");
+		Action oldParenAction = am.get("AutoCompletion.FunctionStart");
+		am.put("AutoCompletion.FunctionStart", new javax.swing.AbstractAction() {
+			public void actionPerformed(java.awt.event.ActionEvent e) {
+				textComponent.replaceSelection("(");
+				List completions = provider.getParameterizedCompletionsAt(textComponent);
+				if (completions!=null && completions.size()>0) {
+					// TODO: Have tooltip let you select between multiple, like VS
+					ParameterizedCompletion pc = (ParameterizedCompletion)completions.get(0);
+					displayDescriptionToolTip(pc, false);
+				}
+			}
+		});
+
 		this.textComponent.addHierarchyListener(this);
 		hierarchyChanged(null); // In case textComponent is already in a window
 
@@ -662,14 +739,17 @@ try {
 
 		public void componentHidden(ComponentEvent e) {
 			hidePopupWindow();
+			hideToolTipWindow();
 		}
 
 		public void componentMoved(ComponentEvent e) {
 			hidePopupWindow();
+			hideToolTipWindow();
 		}
 
 		public void componentResized(ComponentEvent e) {
 			hidePopupWindow();
+			hideToolTipWindow();
 		}
 
 		public void removeFrom(Window w) {
@@ -682,6 +762,7 @@ try {
 
 		public void windowLostFocus(WindowEvent e) {
 			hidePopupWindow();
+			hideToolTipWindow();
 		}
 
 	}
diff --git a/src/org/fife/ui/autocomplete/CCompletionProvider.java b/src/org/fife/ui/autocomplete/CCompletionProvider.java
index 4fcea1a..258422e 100644
--- a/src/org/fife/ui/autocomplete/CCompletionProvider.java
+++ b/src/org/fife/ui/autocomplete/CCompletionProvider.java
@@ -147,6 +147,16 @@ public class CCompletionProvider extends AbstractCompletionProvider{
 	}
 
 
+	/**
+	 * {@inheritDoc}
+	 */
+	public List getParameterizedCompletionsAt(JTextComponent tc) {
+		CompletionProvider provider = getProviderFor(tc);
+		return provider!=null ? provider.getParameterizedCompletionsAt(tc) :
+								null;
+	}
+
+
 	private CompletionProvider getProviderFor(JTextComponent comp) {
 
 		RSyntaxTextArea rsta = (RSyntaxTextArea)comp;
@@ -201,6 +211,7 @@ public class CCompletionProvider extends AbstractCompletionProvider{
 				return getCommentCompletionProvider();
 			case Token.COMMENT_DOCUMENTATION:
 				return getDocCommentCompletionProvider();
+			case Token.NULL:
 			case Token.WHITESPACE:
 			case Token.IDENTIFIER:
 			case Token.VARIABLE:
diff --git a/src/org/fife/ui/autocomplete/CompletionCellRenderer.java b/src/org/fife/ui/autocomplete/CompletionCellRenderer.java
index 92401bf..6df1ad1 100644
--- a/src/org/fife/ui/autocomplete/CompletionCellRenderer.java
+++ b/src/org/fife/ui/autocomplete/CompletionCellRenderer.java
@@ -148,7 +148,7 @@ public class CompletionCellRenderer extends DefaultListCellRenderer {
 		sb.append(fc.getName());
 		sb.append("</em></b>");
 
-		sb.append('(');
+		sb.append(fc.getProvider().getParameterListStart());
 		int paramCount = fc.getParamCount();
 		for (int i=0; i<paramCount; i++) {
 			FunctionCompletion.Parameter param = fc.getParam(i);
@@ -170,10 +170,11 @@ public class CompletionCellRenderer extends DefaultListCellRenderer {
 				sb.append(name);
 			}
 			if (i<paramCount-1) {
-				sb.append(", ");
+				sb.append(fc.getProvider().getParameterListSeparator());
 			}
 		}
-		sb.append(") : ");
+		sb.append(fc.getProvider().getParameterListEnd());
+		sb.append(" : ");
 		if (!selected) {
 			sb.append("<font color='#a0a0ff'>");
 		}
diff --git a/src/org/fife/ui/autocomplete/CompletionProvider.java b/src/org/fife/ui/autocomplete/CompletionProvider.java
index 26b86ea..f5ebcab 100644
--- a/src/org/fife/ui/autocomplete/CompletionProvider.java
+++ b/src/org/fife/ui/autocomplete/CompletionProvider.java
@@ -74,6 +74,53 @@ public interface CompletionProvider {
 
 
 	/**
+	 * Returns a list of parameterized completions that have been entered
+	 * at the current caret position of a text component (and thus can have
+	 * their completion choices displayed).
+	 * 
+	 * @param tc The text component.
+	 * @return The list of {@link ParameterizedCompletion}s.  If no completions
+	 *         are available, this may be <code>null</code>.
+	 */
+	public List getParameterizedCompletionsAt(JTextComponent tc);
+
+
+	/**
+	 * Returns the text that marks the end of a list of parameters to a
+	 * function or method.
+	 *
+	 * @return The text for a parameter list end, for example,
+	 *         "<code>)</code>".
+	 * @see #getParameterListStart()
+	 * @see #getParameterListSeparator()
+	 */
+	public String getParameterListEnd();
+
+
+	/**
+	 * Returns the text that separates parameters to a function or method.
+	 *
+	 * @return The text that separates parameters, for example,
+	 *         "<code>, </code>".
+	 * @see #getParameterListStart()
+	 * @see #getParameterListEnd()
+	 */
+	public String getParameterListSeparator();
+
+
+	/**
+	 * Returns the text that marks the start of a list of parameters to a
+	 * function or method.
+	 *
+	 * @return The text for a parameter list start, for example,
+	 *         "<code>(</code>".
+	 * @see #getParameterListEnd()
+	 * @see #getParameterListSeparator()
+	 */
+	public String getParameterListStart();
+
+
+	/**
 	 * Returns the parent completion provider.
 	 *
 	 * @return The parent completion provider.
diff --git a/src/org/fife/ui/autocomplete/DefaultCompletionProvider.java b/src/org/fife/ui/autocomplete/DefaultCompletionProvider.java
index 4a0dfc9..f1737ce 100644
--- a/src/org/fife/ui/autocomplete/DefaultCompletionProvider.java
+++ b/src/org/fife/ui/autocomplete/DefaultCompletionProvider.java
@@ -119,6 +119,63 @@ public class DefaultCompletionProvider extends AbstractCompletionProvider {
 
 
 	/**
+	 * {@inheritDoc}
+	 */
+	public List getParameterizedCompletionsAt(JTextComponent tc) {
+
+		List list = null;
+
+		String paramListStart = getParameterListStart();
+		if (paramListStart==null) {
+			return list; // null
+		}
+
+		int dot = tc.getCaretPosition();
+		Segment s = new Segment();
+		Document doc = tc.getDocument();
+		Element root = doc.getDefaultRootElement();
+		int line = root.getElementIndex(dot);
+		Element elem = root.getElement(line);
+		int offs = elem.getStartOffset();
+		int len = dot - offs - paramListStart.length();
+		if (len<=0) { // Not enough chars on line for a method.
+			return list; // null
+		}
+
+		try {
+
+			doc.getText(offs, len, s);
+			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);
+				}
+				list.add(c);
+			}
+
+		} catch (BadLocationException ble) {
+			ble.printStackTrace(); // Never happens
+		}
+
+		return list;
+
+	}
+
+
+	/**
 	 * Initializes this completion provider.
 	 */
 	protected void init() {
diff --git a/src/org/fife/ui/autocomplete/FunctionCompletion.java b/src/org/fife/ui/autocomplete/FunctionCompletion.java
index ff5c05d..31ccfaf 100644
--- a/src/org/fife/ui/autocomplete/FunctionCompletion.java
+++ b/src/org/fife/ui/autocomplete/FunctionCompletion.java
@@ -32,7 +32,8 @@ import java.util.List;
  * @author Robert Futrell
  * @version 1.0
  */
-public class FunctionCompletion extends VariableCompletion {
+public class FunctionCompletion extends VariableCompletion
+								implements ParameterizedCompletion {
 
 	/**
 	 * Parameters to the function.
@@ -54,42 +55,9 @@ public class FunctionCompletion extends VariableCompletion {
 
 
 	protected void addDefinitionString(StringBuffer sb) {
-
 		sb.append("<html><b>");
-
-		// Add the return type if applicable (C macros like NULL have no type).
-		String type = getType();
-		if (type!=null) {
-			appendPossibleDataType(sb, type);
-			sb.append(' ');
-		}
-
-		// Add the item being described's name.
-		sb.append(getName());
-
-		// Add parameters for functions.
-		sb.append('(');
-		for (int i=0; i<getParamCount(); i++) {
-			Parameter param = getParam(i);
-			type = param.getType();
-			String name = param.getName();
-			if (type!=null) {
-				appendPossibleDataType(sb, type);
-				if (name!=null) {
-					sb.append(' ');
-				}
-			}
-			if (name!=null) {
-				sb.append(name);
-			}
-			if (i<params.size()-1) {
-				sb.append(", ");
-			}
-		}
-		sb.append(')');
-
+		sb.append(getDefinitionString());
 		sb.append("</b>");
-
 	}
 
 
@@ -123,6 +91,54 @@ public class FunctionCompletion extends VariableCompletion {
 
 
 	/**
+	 * Returns the "definition string" for this function completion.  For
+	 * example, for the C "<code>printf</code>" function, this would return
+	 * "<code>int printf(const char *, ...)</code>".
+	 * 
+	 * @return The definition string.
+	 */
+	public String getDefinitionString() {
+
+		StringBuffer sb = new StringBuffer();
+
+		// Add the return type if applicable (C macros like NULL have no type).
+		String type = getType();
+		if (type!=null) {
+			appendPossibleDataType(sb, type);
+			sb.append(' ');
+		}
+
+		// Add the item being described's name.
+		sb.append(getName());
+
+		// Add parameters for functions.
+		CompletionProvider provider = getProvider();
+		sb.append(provider.getParameterListStart());
+		for (int i=0; i<getParamCount(); i++) {
+			Parameter param = getParam(i);
+			type = param.getType();
+			String name = param.getName();
+			if (type!=null) {
+				appendPossibleDataType(sb, type);
+				if (name!=null) {
+					sb.append(' ');
+				}
+			}
+			if (name!=null) {
+				sb.append(name);
+			}
+			if (i<params.size()-1) {
+				sb.append(provider.getParameterListSeparator());
+			}
+		}
+		sb.append(provider.getParameterListEnd());
+
+		return sb.toString();
+
+	}
+
+
+	/**
 	 * Returns the specified {@link Parameter}.
 	 *
 	 * @param index The index of the parameter to retrieve.
@@ -172,54 +188,4 @@ public class FunctionCompletion extends VariableCompletion {
 	}
 
 
-	/**
-	 * A parameter passed to a function.
-	 *
-	 * @author Robert Futrell
-	 * @version 1.0
-	 */
-	public static class Parameter {
-
-		private String name;
-		private String type;
-		private String desc;
-
-		public Parameter(String type, String name) {
-			this.name = name;
-			this.type = type;
-		}
-
-		public String getDescription() {
-			return desc;
-		}
-
-		public String getName() {
-			return name;
-		}
-
-		public String getType() {
-			return type;
-		}
-
-		public void setDescription(String desc) {
-			this.desc = desc;
-		}
-
-		public String toString() {
-			StringBuffer sb = new StringBuffer();
-			if (type!=null) {
-				sb.append(type);
-			}
-			if (name!=null) {
-				if (type!=null) {
-					sb.append(' ');
-					sb.append(name);
-				}
-			}
-			return sb.toString();
-		}
-
-	}
-
-
 }
\ No newline at end of file
diff --git a/src/org/fife/ui/autocomplete/JarCompletionProvider.java b/src/org/fife/ui/autocomplete/JarCompletionProvider.java
index 92a6dfd..b6a0839 100644
--- a/src/org/fife/ui/autocomplete/JarCompletionProvider.java
+++ b/src/org/fife/ui/autocomplete/JarCompletionProvider.java
@@ -149,6 +149,14 @@ public class JarCompletionProvider extends AbstractCompletionProvider {
 
 
 	/**
+	 * {@inheritDoc}
+	 */
+	public List getParameterizedCompletionsAt(JTextComponent tc) {
+		return null; // This provider knows no functions or methods.
+	}
+
+
+	/**
 	 * Returns whether the specified character is valid in an auto-completion.
 	 *
 	 * @param ch The character.
diff --git a/src/org/fife/ui/autocomplete/MarkupTagCompletion.java b/src/org/fife/ui/autocomplete/MarkupTagCompletion.java
index c9ad95b..113c970 100644
--- a/src/org/fife/ui/autocomplete/MarkupTagCompletion.java
+++ b/src/org/fife/ui/autocomplete/MarkupTagCompletion.java
@@ -26,7 +26,7 @@ package org.fife.ui.autocomplete;
 import java.util.ArrayList;
 import java.util.List;
 
-import org.fife.ui.autocomplete.FunctionCompletion.Parameter;
+import org.fife.ui.autocomplete.ParameterizedCompletion.Parameter;
 
 
 /**
diff --git a/src/org/fife/ui/autocomplete/OutlineHighlightPainter.java b/src/org/fife/ui/autocomplete/OutlineHighlightPainter.java
new file mode 100644
index 0000000..1e3b3ee
--- /dev/null
+++ b/src/org/fife/ui/autocomplete/OutlineHighlightPainter.java
@@ -0,0 +1,133 @@
+package org.fife.ui.autocomplete;
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.io.Serializable;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.DefaultHighlighter;
+import javax.swing.text.JTextComponent;
+import javax.swing.text.Position;
+import javax.swing.text.View;
+
+
+/**
+ * Highlight painter that draws an outline around the text.  This is used to
+ * draw bounds around function/method parameters.
+ *
+ * @author Robert Futrell
+ * @version 1.0
+ */
+/*
+ * NOTE: Whenever you see text like "Workaround for Java Highlight issues",
+ * this is because highlighted text in a JTextComponent gets "pushed" forward
+ * when the caret is at the Highlight's start, when we need it to instead get
+ * prepended to.  For this reason, the autocomplete package adds its Highlights
+ * 1 char too long (1 char earlier than where it should really start), but only
+ * paint the Highlight from the 2nd char on.
+ */
+class OutlineHighlightPainter extends
+			DefaultHighlighter.DefaultHighlightPainter implements Serializable {
+
+	/**
+	 * DefaultHighlightPainter doesn't allow changing color, so we must cache
+	 * ours here.
+	 */
+	private Color color;
+
+	
+	/**
+	 * Constructor.
+	 *
+	 * @param color The color to draw the bounding boxes with.  This cannot
+	 *        be <code>null</code>.
+	 */
+	public OutlineHighlightPainter(Color color) {
+		super(color);
+		setColor(color);
+	}
+
+
+	/**
+	 * Returns the color to paint bounding boxes with.
+	 *
+	 * @return The color.
+	 * @see #setColor(Color)
+	 */
+	public Color getColor() {
+		return color;
+	}
+
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Shape paintLayer(Graphics g, int p0, int p1, Shape viewBounds,
+								JTextComponent c, View view) {
+
+		g.setColor(getColor());
+		p0++; // Workaround for Java Highlight issues.
+
+		// This special case isn't needed for most standard Swing Views (which
+		// always return a width of 1 for modelToView() calls), but it is
+		// needed for RSTA views, which actually return the width of chars for
+		// modelToView calls.  But this should be faster anyway, as we
+		// short-circuit and do only one modelToView() for one offset.
+		if (p0==p1) {
+			try {
+				Shape s = view.modelToView(p0, viewBounds,
+											Position.Bias.Forward);
+				Rectangle r = s.getBounds();
+				g.drawLine(r.x, r.y, r.x, r.y+r.height);
+				return r;
+			} catch (BadLocationException ble) {
+				ble.printStackTrace(); // Never happens
+				return null;
+			}
+		}
+
+		if (p0 == view.getStartOffset() && p1 == view.getEndOffset()) {
+			// Contained in view, can just use bounds.
+			Rectangle alloc;
+			if (viewBounds instanceof Rectangle) {
+				alloc = (Rectangle) viewBounds;
+			} else {
+				alloc = viewBounds.getBounds();
+			}
+			g.drawRect(alloc.x, alloc.y, alloc.width - 1, alloc.height - 1);
+			return alloc;
+		}
+
+		// Should only render part of View.
+		try {
+			// --- determine locations ---
+			Shape shape = view.modelToView(p0, Position.Bias.Forward, p1,
+					Position.Bias.Backward, viewBounds);
+			Rectangle r = (shape instanceof Rectangle) ? (Rectangle) shape
+					: shape.getBounds();
+			g.drawRect(r.x, r.y, r.width - 1, r.height - 1);
+			return r;
+		} catch (BadLocationException e) { // Never happens
+			e.printStackTrace();
+			return null;
+		}
+
+	}
+
+
+	/**
+	 * Sets the color to paint the bounding boxes with.
+	 *
+	 * @param color The new color.  This cannot be <code>null</code>.
+	 * @see #getColor()
+	 */
+	public void setColor(Color color) {
+		if (color==null) {
+			throw new IllegalArgumentException("color cannot be null");
+		}
+		this.color = color;
+	}
+
+
+}
\ No newline at end of file
diff --git a/src/org/fife/ui/autocomplete/ParameterizedCompletion.java b/src/org/fife/ui/autocomplete/ParameterizedCompletion.java
new file mode 100644
index 0000000..30ee1f2
--- /dev/null
+++ b/src/org/fife/ui/autocomplete/ParameterizedCompletion.java
@@ -0,0 +1,92 @@
+package org.fife.ui.autocomplete;
+
+
+/**
+ * A completion option that takes parameters, such as a function or method.
+ *
+ * @author Robert Futrell
+ * @version 1.0
+ */
+public interface ParameterizedCompletion extends Completion {
+
+
+	/**
+	 * Returns the "definition string" for this completion.  For examle,
+	 * for the C "<code>printf</code>" function, this would return
+	 * "<code>int printf(const char *, ...)</code>".
+	 * 
+	 * @return The definition string.
+	 */
+	public String getDefinitionString();
+
+
+	/**
+	 * Returns the specified {@link Parameter}.
+	 *
+	 * @param index The index of the parameter to retrieve.
+	 * @return The parameter.
+	 * @see #getParamCount()
+	 */
+	public Parameter getParam(int index);
+
+
+	/**
+	 * Returns the number of parameters this completion takes.
+	 *
+	 * @return The number of parameters this completion takes.
+	 * @see #getParam(int)
+	 */
+	public int getParamCount();
+
+
+	/**
+	 * A parameter passed to a parameterized {@link Completion}.
+	 *
+	 * @author Robert Futrell
+	 * @version 1.0
+	 */
+	public static class Parameter {
+
+		private String name;
+		private String type;
+		private String desc;
+
+		public Parameter(String type, String name) {
+			this.name = name;
+			this.type = type;
+		}
+
+		public String getDescription() {
+			return desc;
+		}
+
+		public String getName() {
+			return name;
+		}
+
+		public String getType() {
+			return type;
+		}
+
+		public void setDescription(String desc) {
+			this.desc = desc;
+		}
+
+		public String toString() {
+			StringBuffer sb = new StringBuffer();
+			if (type!=null) {
+				sb.append(type);
+			}
+			if (name!=null) {
+				if (type!=null) {
+					sb.append(' ');
+				}
+				sb.append(name);
+			}
+			return sb.toString();
+		}
+
+	}
+
+
+}
\ No newline at end of file
diff --git a/src/org/fife/ui/autocomplete/ParameterizedCompletionDescriptionToolTip.java b/src/org/fife/ui/autocomplete/ParameterizedCompletionDescriptionToolTip.java
new file mode 100644
index 0000000..9a43069
--- /dev/null
+++ b/src/org/fife/ui/autocomplete/ParameterizedCompletionDescriptionToolTip.java
@@ -0,0 +1,721 @@
+/*
+ * 12/21/2008
+ *
+ * AutoCompleteDescWindow.java - A window containing a description of the
+ * currently selected completion.
+ * Copyright (C) 2008 Robert Futrell
+ * robert_futrell at users.sourceforge.net
+ * http://fifesoft.com/rsyntaxtextarea
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA.
+ */
+package org.fife.ui.autocomplete;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.SystemColor;
+import java.awt.Window;
+import java.awt.event.ActionEvent;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.ActionMap;
+import javax.swing.BorderFactory;
+import javax.swing.InputMap;
+import javax.swing.JLabel;
+import javax.swing.JWindow;
+import javax.swing.KeyStroke;
+import javax.swing.UIManager;
+import javax.swing.event.CaretEvent;
+import javax.swing.event.CaretListener;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Highlighter;
+import javax.swing.text.JTextComponent;
+import javax.swing.text.Position;
+import javax.swing.text.Highlighter.Highlight;
+
+
+/**
+ * A "tooltip" that displays information on the function or method currently
+ * being entered.
+ *
+ * @author Robert Futrell
+ * @version 1.0
+ */
+class ParameterizedCompletionDescriptionToolTip {
+
+	/**
+	 * The actual tooltip.
+	 */
+	private JWindow tooltip;
+
+	/**
+	 * The painter to paint borders around the variables.
+	 */
+	Highlighter.HighlightPainter p;
+
+	/**
+	 * The tags for the highlights around parameters.
+	 */
+	List tags;
+
+	/**
+	 * The parent AutoCompletion instance.
+	 */
+	private AutoCompletion ac;
+
+	/**
+	 * The label that holds the description.
+	 */
+	private JLabel descLabel;
+
+	/**
+	 * The completion being described.
+	 */
+	private ParameterizedCompletion pc;
+
+	/**
+	 * Listens for events in the text component while this window is vislble.
+	 */
+	private Listener listener;
+
+	/**
+	 * The minimum offset into the document that the caret can move to
+	 * before this tooltip disappears.
+	 */
+	private int minPos;
+
+	/**
+	 * The maximum offset into the document that the caret can move to
+	 * before this tooltip disappears.
+	 */
+	private Position maxPos; // Moves with text inserted.
+
+	/**
+	 * The currently "selected" parameter in the displayed text.
+	 */
+	private int lastSelectedParam;
+
+	private Object oldTabKey;
+	private Action oldTabAction;
+	private Object oldShiftTabKey;
+	private Action oldShiftTabAction;
+	private Object oldEscapeKey;
+	private Action oldEscapeAction;
+	private Object oldClosingKey;
+	private Action oldClosingAction;
+
+	private static final String IM_KEY_TAB = "ParamCompDescToolTip.Tab";
+	private static final String IM_KEY_SHIFT_TAB = "ParamCompDescToolTip.ShiftTab";
+	private static final String IM_KEY_ESCAPE = "ParamCompDescToolTip.Escape";
+	private static final String IM_KEY_CLOSING = "ParamCompDescToolTip.Closing";
+
+
+	/**
+	 * Constructor.
+	 *
+	 * @param owner The parent window.
+	 * @param ac The parent autocompletion.
+	 * @param pc The completion being described.
+	 */
+	public ParameterizedCompletionDescriptionToolTip(Window owner,
+						AutoCompletion ac, ParameterizedCompletion pc) {
+
+		tooltip = new JWindow(owner);
+		this.ac = ac;
+		this.pc = pc;
+
+		descLabel = new JLabel();
+		descLabel.setOpaque(true);
+		descLabel.setBorder(BorderFactory.createCompoundBorder(
+					BorderFactory.createLineBorder(Color.BLACK),
+					BorderFactory.createEmptyBorder(2, 5, 2, 5)));
+		descLabel.setBackground(getDefaultBackground());
+		tooltip.setContentPane(descLabel);
+
+		lastSelectedParam = -1;
+		updateText(0);
+
+		tooltip.setFocusableWindowState(false);
+		listener = new Listener();
+
+		p = new OutlineHighlightPainter(Color.GRAY);
+		tags = new ArrayList(1); // Usually small
+
+	}
+
+
+	/**
+	 * Returns the default background color to use for the description
+	 * window.
+	 *
+	 * @return The default background color.
+	 */
+	protected Color getDefaultBackground() {
+		Color c = UIManager.getColor("ToolTip.background");
+		if (c==null) { // Some LookAndFeels like Nimbus
+			c = UIManager.getColor("info"); // Used by Nimbus (and others)
+			if (c==null) {
+				c = SystemColor.infoText; // System default
+			}
+		}
+		return c;
+	}
+
+
+	private List getParameterHighlights() {
+		List paramHighlights = new ArrayList(1);
+		JTextComponent tc = ac.getTextComponent();
+		Highlight[] highlights = tc.getHighlighter().getHighlights();
+		for (int i=0; i<highlights.length; i++) {
+			if (highlights[i].getPainter()==p) {
+				paramHighlights.add(highlights[i]);
+			}
+		}
+		return paramHighlights;
+	}
+
+
+	/**
+	 * Installs key bindings on the text component that facilitate the user
+	 * editing this completion's parameters.
+	 *
+	 * @see #uninstallKeyBindings()
+	 */
+	private void installKeyBindings() {
+
+		JTextComponent tc = ac.getTextComponent();
+		InputMap im = tc.getInputMap();
+		ActionMap am = tc.getActionMap();
+
+		KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0);
+		oldTabKey = im.get(ks);
+		im.put(ks, IM_KEY_TAB);
+		oldTabAction = am.get(IM_KEY_TAB);
+		am.put(IM_KEY_TAB, new NextParamAction());
+
+		ks = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_MASK);
+		oldShiftTabKey = im.get(ks);
+		im.put(ks, IM_KEY_SHIFT_TAB);
+		oldShiftTabAction = am.get(IM_KEY_SHIFT_TAB);
+		am.put(IM_KEY_SHIFT_TAB, new PrevParamAction());
+
+		ks = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
+		oldEscapeKey = im.get(ks);
+		im.put(ks, IM_KEY_ESCAPE);
+		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());
+		}
+	}
+
+
+	/**
+	 * Moves to and selects the next parameter.
+	 *
+	 * @see #moveToPreviousParam()
+	 */
+	private void moveToNextParam() {
+
+		JTextComponent tc = ac.getTextComponent();
+		int dot = tc.getCaretPosition();
+
+		int tagCount = tags.size();
+		if (tagCount==0) {
+			tc.setCaretPosition(maxPos.getOffset());
+			tooltip.setVisible(false);
+		}
+
+		Highlight currentNext = null;
+		int pos = -1;
+		List highlights = getParameterHighlights();
+		for (int i=0; i<highlights.size(); i++) {
+			Highlight hl = (Highlight)highlights.get(i);
+			if (currentNext==null || currentNext.getStartOffset()<=dot ||
+					(hl.getStartOffset()>dot &&
+					hl.getStartOffset()<=currentNext.getStartOffset())) {
+				currentNext = hl;
+				pos = i;
+			}
+		}
+
+		if (currentNext!=null && dot<currentNext.getStartOffset()) {
+			 // "+1" is a workaround for Java Highlight issues.
+			tc.setSelectionStart(currentNext.getStartOffset()+1);
+			tc.setSelectionEnd(currentNext.getEndOffset());
+			updateText(pos);
+		}
+		else {
+			tc.setCaretPosition(maxPos.getOffset());
+			tooltip.setVisible(false);
+		}
+
+	}
+
+
+	/**
+	 * Moves to and selects the previous parameter.
+	 *
+	 * @see #moveToNextParam()
+	 */
+	private void moveToPreviousParam() {
+
+		JTextComponent tc = ac.getTextComponent();
+
+		int tagCount = tags.size();
+		if (tagCount==0) { // Should never happen
+			tc.setCaretPosition(maxPos.getOffset());
+			tooltip.setVisible(false);
+		}
+
+		int dot = tc.getCaretPosition();
+		int selStart = tc.getSelectionStart()-1; // Workaround for Java Highlight issues.
+		Highlight currentPrev = null;
+		int pos = 0;
+		Highlighter h = tc.getHighlighter();
+		Highlight[] highlights = h.getHighlights();
+		for (int i=0; i<highlights.length; i++) {
+			Highlight hl = highlights[i];
+			if (hl.getPainter()==p) { // Only way to identify our own higlights
+				if (currentPrev==null || currentPrev.getStartOffset()>=dot ||
+						(hl.getStartOffset()<selStart &&
+						hl.getStartOffset()>currentPrev.getStartOffset())) {
+					currentPrev = hl;
+					pos = i;
+				}
+			}
+		}
+
+		if (currentPrev!=null && dot>currentPrev.getStartOffset()) {
+			 // "+1" is a workaround for Java Highlight issues.
+			tc.setSelectionStart(currentPrev.getStartOffset()+1);
+			tc.setSelectionEnd(currentPrev.getEndOffset());
+			updateText(pos);
+		}
+		else {
+			tc.setCaretPosition(maxPos.getOffset());
+			tooltip.setVisible(false);
+		}
+
+	}
+
+
+	/**
+	 * Removes the bounding boxes around parameters.
+	 */
+	private void removeParameterHighlights() {
+		JTextComponent tc = ac.getTextComponent();
+		Highlighter h = tc.getHighlighter();
+		for (int i=0; i<tags.size(); i++) {
+			h.removeHighlight(tags.get(i));
+		}
+		tags.clear();
+	}
+
+
+	/**
+	 * Sets the location of this tooltip relative to the given rectangle.
+	 *
+	 * @param r The visual position of the caret (in screen coordinates).
+	 */
+	public void setLocationRelativeTo(Rectangle r) {
+
+		Dimension screenSize = tooltip.getToolkit().getScreenSize();
+
+		// Try putting our stuff "above" the caret first.
+		int y = r.y - 5 - tooltip.getHeight();
+		if (y<0) {
+			y = r.y + r.height + 5;
+		}
+
+		// Get x-coordinate of completions.  Try to align left edge with the
+		// caret first.
+		int x = r.x;
+		if (x<0) {
+			x = 0;
+		}
+		else if (x+tooltip.getWidth()>screenSize.width) { // completions don't fit
+			x = screenSize.width - tooltip.getWidth();
+		}
+
+		tooltip.setLocation(x, y);
+
+	}
+
+
+	/**
+	 * Toggles the visibility of this tooltip.
+	 *
+	 * @param visible Whether the tooltip should be visible.
+	 * @param addParamListStart Whether or not
+	 *        {@link CompletionProvider#getParameterListStart()} should be
+	 *        added to the text component.  If <code>visible</code> is
+	 *        <code>false</code>, this parameter is ignored.
+	 */
+	public void setVisible(boolean visible, boolean addParamListStart) {
+		if (visible!=tooltip.isVisible()) {
+			JTextComponent tc = ac.getTextComponent();
+			if (visible) {
+				listener.install(tc, addParamListStart);
+			}
+			else {
+				listener.uninstall();
+			}
+			tooltip.setVisible(visible);
+		}
+	}
+
+
+	/**
+	 * Removes the key bindings we installed.
+	 *
+	 * @see #installKeyBindings()
+	 */
+	private void uninstallKeyBindings() {
+
+		JTextComponent tc = ac.getTextComponent();
+		InputMap im = tc.getInputMap();
+		ActionMap am = tc.getActionMap();
+
+		KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0);
+		im.put(ks, oldTabKey);
+		am.put(IM_KEY_TAB, oldTabAction);
+
+		ks = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_MASK);
+		im.put(ks, oldShiftTabKey);
+		am.put(IM_KEY_SHIFT_TAB, oldShiftTabAction);
+
+		ks = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
+		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);
+		}
+
+	}
+
+
+	/**
+	 * Updates the text in the tooltip to have the current parameter
+	 * disiplayed in bold.  The "current parameter" is determined from the
+	 * current caret position.
+	 */
+	private void updateText() {
+
+		JTextComponent tc = ac.getTextComponent();
+		int dot = tc.getCaretPosition();
+		if (dot>0) {
+			dot--; // Workaround for Java Highlight issues
+		}
+		int index = -1;
+
+		List paramHighlights = getParameterHighlights();
+		for (int i=0; i<paramHighlights.size(); i++) {
+			Highlight h = (Highlight)paramHighlights.get(i);
+			if (dot>=h.getStartOffset() && dot<h.getEndOffset()) {
+				index = i;
+				break;
+			}
+		}
+
+		updateText(index);
+
+	}
+
+
+	/**
+	 * Updates the text in the tooltip to have the current parameter
+	 * displayed in bold.
+	 *
+	 * @param selectedParam The index of the selected parameter.
+	 */
+	private void updateText(int selectedParam) {
+
+		// Don't redo everything if they're just using the arrow keys to move
+		// through each char of a single parameter, for example.
+		if (selectedParam==lastSelectedParam) {
+			return;
+		}
+		lastSelectedParam = selectedParam;
+
+		StringBuffer sb = new StringBuffer("<html>");
+		int paramCount = pc.getParamCount();
+		for (int i=0; i<paramCount; i++) {
+			if (i==selectedParam) {
+				sb.append("<b>");
+			}
+			sb.append(pc.getParam(i).toString());
+			if (i==selectedParam) {
+				sb.append("</b>");
+			}
+			if (i<paramCount-1) {
+				sb.append(pc.getProvider().getParameterListSeparator());
+			}
+		}
+
+		descLabel.setText(sb.toString());
+		tooltip.pack();
+
+	}
+
+
+	/**
+	 * Called when the user types the character marking the closing of the
+	 * parameter list, such as '<code>)</code>'.
+	 *
+	 * @author Robert Futrell
+	 * @version 1.0
+	 */
+	private class ClosingAction extends AbstractAction {
+
+		public void actionPerformed(ActionEvent e) {
+			JTextComponent tc = ac.getTextComponent();
+			tc.setCaretPosition(maxPos.getOffset());
+			tooltip.setVisible(false);
+		}
+
+	}
+
+
+	/**
+	 * Action performed when the user hits the escape key.
+	 *
+	 * @author Robert Futrell
+	 * @version 1.0
+	 */
+	private class HideAction extends AbstractAction {
+
+		public void actionPerformed(ActionEvent e) {
+			tooltip.setVisible(false);
+		}
+
+	}
+
+
+	/**
+	 * Listens for various events in the text component while this tooltip
+	 * is visible.
+	 *
+	 * @author Robert Futrell
+	 * @version 1.0
+	 */
+	private class Listener implements FocusListener, CaretListener {
+
+		/**
+		 * Called when the text component's caret moves.
+		 *
+		 * @param e The event.
+		 */
+		public void caretUpdate(CaretEvent e) {
+			if (maxPos==null) { // Sanity check
+				tooltip.setVisible(false);
+			}
+			int dot = e.getDot();
+			if (dot<minPos || dot>maxPos.getOffset()) {
+				tooltip.setVisible(false);
+			}
+			updateText();
+		}
+
+
+		/**
+		 * Called when the text component gains focus.
+		 *
+		 * @param e The event.
+		 */
+		public void focusGained(FocusEvent e) {
+			// Do nothing
+		}
+
+
+		/**
+		 * Called when the text component loses focus.
+		 *
+		 * @param e The event.
+		 */
+		public void focusLost(FocusEvent e) {
+			tooltip.setVisible(false);
+		}
+
+
+		/**
+		 * Returns the text to insert for a parameter.
+		 *
+		 * @param param The parameter.
+		 * @return The text.
+		 */
+		private String getParamText(ParameterizedCompletion.Parameter param) {
+			String text = param.getName();
+			if (text==null) {
+				text = param.getType();
+				if (text==null) { // Shouldn't ever happen
+					text = "arg";
+				}
+			}
+			return text;
+		}
+
+
+		/**
+		 * Installs this listener onto a text component.
+		 *
+		 * @param tc The text component to install onto.
+		 * @param addParamListStart Whether or not
+		 *        {@link CompletionProvider#getParameterListStart()} should be
+		 *        added to the text component.
+		 * @see #uninstall()
+		 */
+		public void install(JTextComponent tc, boolean addParamStartList) {
+
+			// Add listeners to the text component.
+			tc.addCaretListener(this);
+			tc.addFocusListener(this);
+			installKeyBindings();
+
+			StringBuffer sb = new StringBuffer();
+			if (addParamStartList) {
+				sb.append(pc.getProvider().getParameterListStart());
+			}
+			int dot = tc.getCaretPosition() + sb.length();
+			int paramCount = pc.getParamCount();
+			List paramLocs = null;
+			if (paramCount>0) {
+				paramLocs = new ArrayList(paramCount);
+			}
+			Highlighter h = tc.getHighlighter();
+
+			try {
+
+				// Get the range in which the caret can move before we hide
+				// this tooltip.
+				minPos = dot;
+				maxPos = tc.getDocument().createPosition(dot-sb.length());
+				int firstParamLen = 0;
+
+				// Create the text to insert (keep it one completion for
+				// performance and simplicity of undo/redo).
+				int start = dot;
+				for (int i=0; i<paramCount; i++) {
+					FunctionCompletion.Parameter param = pc.getParam(i);
+					String paramText = getParamText(param);
+					if (i==0) {
+						firstParamLen = paramText.length();
+					}
+					sb.append(paramText);
+					int end = start + paramText.length();
+					paramLocs.add(new Point(start, end));
+					if (i<paramCount-1) {
+						sb.append(pc.getProvider().getParameterListSeparator());
+						start = end + 2;
+					}
+				}
+				sb.append(pc.getProvider().getParameterListEnd());
+
+				// Insert the parameter text and add highlights around the
+				// parameters.
+				tc.replaceSelection(sb.toString());
+				for (int i=0; i<paramCount; i++) {
+					Point pt = (Point)paramLocs.get(i);
+					 // "-1" is a workaround for Java Highlight issues.
+					tags.add(h.addHighlight(pt.x-1, pt.y, p));
+				}
+
+				// Go back and start at the first parameter.
+				tc.setCaretPosition(dot);
+				if (pc.getParamCount()>0) {
+					tc.moveCaretPosition(dot+firstParamLen);
+				}
+
+			} catch (BadLocationException ble) {
+				ble.printStackTrace(); // Never happens
+			}
+
+		}
+
+
+		/**
+		 * Uninstalls this listener from the current text component.
+		 * 
+		 */
+		public void uninstall() {
+
+			JTextComponent tc = ac.getTextComponent();
+			tc.removeCaretListener(this);
+			tc.removeFocusListener(this);
+			uninstallKeyBindings();
+
+			// Remove WeakReferences in javax.swing.text.
+			maxPos = null;
+			minPos = -1;
+			removeParameterHighlights();
+
+		}
+
+
+	}
+
+
+	/**
+	 * Action performed when the user hits the tab key.
+	 *
+	 * @author Robert Futrell
+	 * @version 1.0
+	 */
+	private class NextParamAction extends AbstractAction {
+
+		public void actionPerformed(ActionEvent e) {
+			moveToNextParam();
+		}
+
+	}
+
+
+	/**
+	 * Action performed when the user hits shift+tab.
+	 *
+	 * @author Robert Futrell
+	 * @version 1.0
+	 */
+	private class PrevParamAction extends AbstractAction {
+
+		public void actionPerformed(ActionEvent e) {
+			moveToPreviousParam();
+		}
+
+	}
+
+
+}
\ No newline at end of file

-- 
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