This is an automated email from the git hooks/post-receive script. ben pushed a commit to branch master in repository autocomplete.
commit 25951e4e41dd29b9013aa719e8b077cfdb9c36b6 Author: bobbylight <[email protected]> Date: Thu Dec 16 04:19:32 2010 +0000 Beginning work towards parameter completions for a ParameterizedCompletion's parameters. --- .../autocomplete/AbstractCompletionProvider.java | 27 +-- .../fife/ui/autocomplete/CompletionProvider.java | 12 + .../ui/autocomplete/CompletionProviderBase.java | 28 +++ .../ui/autocomplete/ParameterChoicesProvider.java | 54 +++++ .../ParameterizedCompletionChoicesWindow.java | 244 ++++++++++++++++++++ .../ParameterizedCompletionDescriptionToolTip.java | 193 +++++++++++++++- src/org/fife/ui/autocomplete/Util.java | 27 ++- 7 files changed, 551 insertions(+), 34 deletions(-) diff --git a/src/org/fife/ui/autocomplete/AbstractCompletionProvider.java b/src/org/fife/ui/autocomplete/AbstractCompletionProvider.java index 02144c1..72111d7 100644 --- a/src/org/fife/ui/autocomplete/AbstractCompletionProvider.java +++ b/src/org/fife/ui/autocomplete/AbstractCompletionProvider.java @@ -198,7 +198,7 @@ public abstract class AbstractCompletionProvider while (index<completions.size()) { Completion c = (Completion)completions.get(index); - if (startsWithIgnoreCase(c.getInputText(), text)) { + if (Util.startsWithIgnoreCase(c.getInputText(), text)) { retVal.add(c); index++; } @@ -237,31 +237,6 @@ public abstract class AbstractCompletionProvider /** - * Returns whether <code>str</code> starts with <code>start</code>, - * ignoring case. - * - * @param str The string to check. - * @param start The prefix to check for. - * @return Whether <code>str</code> starts with <code>start</code>, - * ignoring case. - */ - protected boolean startsWithIgnoreCase(String str, String start) { - int startLen = start.length(); - if (str.length()>=startLen) { - for (int i=0; i<startLen; i++) { - char c1 = str.charAt(i); - char c2 = start.charAt(i); - if (Character.toLowerCase(c1)!=Character.toLowerCase(c2)) { - return false; - } - } - return true; - } - return false; - } - - - /** * A comparator that compares the input text of a {@link Completion} * against a String lexicographically, ignoring case. * diff --git a/src/org/fife/ui/autocomplete/CompletionProvider.java b/src/org/fife/ui/autocomplete/CompletionProvider.java index 67337b4..b8fa082 100644 --- a/src/org/fife/ui/autocomplete/CompletionProvider.java +++ b/src/org/fife/ui/autocomplete/CompletionProvider.java @@ -100,6 +100,18 @@ public interface CompletionProvider { /** + * Returns an object that can return a list of completion choices for + * parameters. This is used when a user code-completes a parameterized + * completion, such as a function or method. For any parameter to the + * function/method, this object can return possible completions. + * + * @return The parameter choices provider, or <code>null</code> if + * none is installed. + */ + public ParameterChoicesProvider getParameterChoicesProvider(); + + + /** * 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). diff --git a/src/org/fife/ui/autocomplete/CompletionProviderBase.java b/src/org/fife/ui/autocomplete/CompletionProviderBase.java index 7a8bcc7..dd861f8 100644 --- a/src/org/fife/ui/autocomplete/CompletionProviderBase.java +++ b/src/org/fife/ui/autocomplete/CompletionProviderBase.java @@ -80,6 +80,11 @@ public abstract class CompletionProviderBase implements CompletionProvider { private String autoActivateChars; /** + * Provides completion choices for a parameterized completion's parameters. + */ + private ParameterChoicesProvider paramChoicesProvider; + + /** * A segment to use for fast char access. */ private Segment s = new Segment(); @@ -147,6 +152,14 @@ public abstract class CompletionProviderBase implements CompletionProvider { /** * {@inheritDoc} */ + public ParameterChoicesProvider getParameterChoicesProvider() { + return paramChoicesProvider; + } + + + /** + * {@inheritDoc} + */ public char getParameterListEnd() { return paramListEnd; } @@ -209,6 +222,21 @@ public abstract class CompletionProviderBase implements CompletionProvider { /** + * Sets the param choices provider. This is used when a user + * code-completes a parameterized completion, such as a function or method. + * For any parameter to the function/method, this object can return + * possible completions. + * + * @param pcp The parameter choices provider, or <code>null</code> for + * none. + * @see #getParameterChoicesProvider() + */ + public void setParameterChoicesProvider(ParameterChoicesProvider pcp) { + paramChoicesProvider = pcp; + } + + + /** * {@inheritDoc} */ public void setListCellRenderer(ListCellRenderer r) { diff --git a/src/org/fife/ui/autocomplete/ParameterChoicesProvider.java b/src/org/fife/ui/autocomplete/ParameterChoicesProvider.java new file mode 100644 index 0000000..2303202 --- /dev/null +++ b/src/org/fife/ui/autocomplete/ParameterChoicesProvider.java @@ -0,0 +1,54 @@ +/* + * 12/14/2010 + * + * ParameterChoicesProvider.java - Provides completions for a + * ParameterizedCompletion's parameters. + * Copyright (C) 2010 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.util.List; +import javax.swing.text.JTextComponent; + + +/** + * Provides completions for a {@link ParameterizedCompletion}'s parameters. + * So, for example, if the user code-completes a function or method, if + * a <code>ParameterChoicesProvider</code> is installed, it can return possible + * completions for the parameters to that function or method. + * + * @author Robert Futrell + * @version 1.0 + */ +public interface ParameterChoicesProvider { + + + /** + * Returns a list of choices for a specific parameter. + * + * @param tc The text component. + * @param p The currently focused parameter. + * @return The list of parameters. This may be <code>null</code> for + * "no parameters." + */ + public List getParameterChoices(JTextComponent tc, + ParameterizedCompletion.Parameter param); + + +} \ No newline at end of file diff --git a/src/org/fife/ui/autocomplete/ParameterizedCompletionChoicesWindow.java b/src/org/fife/ui/autocomplete/ParameterizedCompletionChoicesWindow.java new file mode 100644 index 0000000..6914879 --- /dev/null +++ b/src/org/fife/ui/autocomplete/ParameterizedCompletionChoicesWindow.java @@ -0,0 +1,244 @@ +/* + * 12/11/2010 + * + * ParameterizedCompletionChoicesWindow.java - A list of likely choices for a + * parameter. + * Copyright (C) 2010 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.ComponentOrientation; +import java.awt.Rectangle; +import java.awt.Window; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.swing.DefaultListModel; +import javax.swing.JList; +import javax.swing.JScrollPane; +import javax.swing.JWindow; +import javax.swing.SwingUtilities; +import javax.swing.text.JTextComponent; + + +/** + * A small popup window offering a list of likely choices for a parameter + * when the user has code-completed a parameterized completion. For example, + * if they have just code-completed the C function "<code>fprintf</code>", + * when entering the file name, this popup might display all local variables + * of type "<code>char *</code>". + * + * @author Robert Futrell + * @version 1.0 + */ +public class ParameterizedCompletionChoicesWindow extends JWindow { + + /** + * The parent AutoCompletion instance. + */ + private AutoCompletion ac; + + /** + * The list of completion choices. + */ + private JList list; + + /** + * The currently displayed completion choices. + */ + private DefaultListModel model; + + /** + * A list of lists of choices for each parameter. + */ + private List choicesListList; + + + /** + * Constructor. + * + * @param parent The parent window (hosting the text component). + * @param ac The auto-completion instance. + */ + public ParameterizedCompletionChoicesWindow(Window parent, + AutoCompletion ac) { + + super(parent); + this.ac = ac; + ComponentOrientation o = ac.getTextComponentOrientation(); + + model = new DefaultListModel(); + list = new JList(model); + JScrollPane sp = new JScrollPane(list); + // Required to easily keep popup wide enough for no horiz. scroll bar + sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + + setContentPane(sp); + applyComponentOrientation(o); + + setFocusableWindowState(false); + + } + + + /** + * Changes the selected index. + * + * @param amount The amount by which to change the selected index. + */ + public void incSelection(int amount) { + int selection = list.getSelectedIndex(); + selection += amount; + if (selection<0) { + // Account for nothing selected yet + selection = model.getSize()-1;//+= model.getSize(); + } + else { + selection %= model.getSize(); + } + list.setSelectedIndex(selection); + list.setSelectedIndex(selection); + } + + + /** + * Initializes this window to offer suggestions for the parameters of + * a specific completion. + * + * @param pc The completion whose parameters we should offer suggestions + * for. + */ + public void initialize(ParameterizedCompletion pc) { + + CompletionProvider provider = pc.getProvider(); + ParameterChoicesProvider pcp = provider.getParameterChoicesProvider(); + if (pcp==null) { + choicesListList = null; + return; + } + + int paramCount = pc.getParamCount(); + choicesListList = new ArrayList(paramCount); + JTextComponent tc = ac.getTextComponent(); + + for (int i=0; i<paramCount; i++) { + ParameterizedCompletion.Parameter param = pc.getParam(i); + List choices = pcp.getParameterChoices(tc, param); + choicesListList.add(choices); + } + + } + + + /** + * Sets the location of this window relative to the given rectangle. + * + * @param r The visual position of the caret (in screen coordinates). + */ + public void setLocationRelativeTo(Rectangle r) { + + // Multi-monitor support - make sure the completion window (and + // description window, if applicable) both fit in the same window in + // a multi-monitor environment. To do this, we decide which monitor + // the rectangle "r" is in, and use that one (just pick top-left corner + // as the defining point). + Rectangle screenBounds = Util.getScreenBoundsForPoint(r.x, r.y); + //Dimension screenSize = tooltip.getToolkit().getScreenSize(); + + // Try putting our stuff "below" the caret first. + int 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<screenBounds.x) { + x = screenBounds.x; + } + else if (x+getWidth()>screenBounds.x+screenBounds.width) { // completions don't fit + x = screenBounds.x + screenBounds.width - getWidth(); + } + + setLocation(x, y); + + } + + + /** + * Displays the choices for the specified parameter matching the given + * text. + * + * @param param The index of the parameter the caret is currently in. + * This may be <code>-1</code> if not in a parameter (i.e., on + * the comma between parameters). + * @param alreadyEntered Text in the parameter before the dot. + */ + public void setParameter(int param, String alreadyEntered) { + + model.clear(); + + if (choicesListList!=null && param>=0 && param<choicesListList.size()) { + + List choices = (List)choicesListList.get(param); + for (Iterator i=choices.iterator(); i.hasNext(); ) { + String choice = (String)i.next(); + if (Util.startsWithIgnoreCase(choice, alreadyEntered)) { + model.addElement(choice); + } + } + + int visibleRowCount = Math.min(model.size(), 10); + list.setVisibleRowCount(visibleRowCount); + + pack(); + + } + + } + + + /** + * Toggles the visibility of this popup window. + * + * @param visible Whether this window should be visible. + */ + public void setVisible(boolean visible) { + + if (visible!=isVisible()) { + + if (visible) { + + } + + super.setVisible(visible); + + } + + } + + + /** + * Updates the <tt>LookAndFeel</tt> of this window. + */ + public void updateUI() { + SwingUtilities.updateComponentTreeUI(this); + } + + +} \ 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 454365f..c03d698 100644 --- a/src/org/fife/ui/autocomplete/ParameterizedCompletionDescriptionToolTip.java +++ b/src/org/fife/ui/autocomplete/ParameterizedCompletionDescriptionToolTip.java @@ -111,6 +111,18 @@ class ParameterizedCompletionDescriptionToolTip { private Position maxPos; // Moves with text inserted. /** + * A small popup window giving likely choices for parameterized completions. + */ + private ParameterizedCompletionChoicesWindow paramChoicesWindow; + + /** + * The text before the caret for the current parameter. If + * {@link #paramChoicesWindow} is non-<code>null</code>, this is used to + * determine what parameter choices to actually show. + */ + private String paramAlreadyEntered; + + /** * The currently "selected" parameter in the displayed text. */ private int lastSelectedParam; @@ -119,6 +131,10 @@ class ParameterizedCompletionDescriptionToolTip { private Action oldTabAction; private Object oldShiftTabKey; private Action oldShiftTabAction; + private Object oldUpKey; + private Action oldUpAction; + private Object oldDownKey; + private Action oldDownAction; private Object oldEnterKey; private Action oldEnterAction; private Object oldEscapeKey; @@ -128,6 +144,8 @@ class ParameterizedCompletionDescriptionToolTip { private static final String IM_KEY_TAB = "ParamCompDescTip.Tab"; private static final String IM_KEY_SHIFT_TAB = "ParamCompDescTip.ShiftTab"; + private static final String IM_KEY_UP = "ParamCompDescTip.Up"; + private static final String IM_KEY_DOWN = "ParamCompDescTip.Down"; private static final String IM_KEY_ESCAPE = "ParamCompDescTip.Escape"; private static final String IM_KEY_ENTER = "ParamCompDescTip.Enter"; private static final String IM_KEY_CLOSING = "ParamCompDescTip.Closing"; @@ -164,6 +182,48 @@ class ParameterizedCompletionDescriptionToolTip { p = new OutlineHighlightPainter(Color.GRAY); tags = new ArrayList(1); // Usually small + paramChoicesWindow = createParamChoicesWindow(); + + } + + + /** + * Creates the completion window offering suggestions for parameters. + * + * @return The window. + */ + private ParameterizedCompletionChoicesWindow createParamChoicesWindow() { + ParameterizedCompletionChoicesWindow pcw = + new ParameterizedCompletionChoicesWindow(tooltip.getOwner(), ac); + pcw.initialize(pc); + return pcw; + } + + + /** + * Returns the starting offset of the current parameter. + * + * @return The current parameter's starting offset, or <code>-1</code> if + * the caret is not in a parameter's bounds. + */ + private int getCurrentParameterStartOffset() { + + JTextComponent tc = ac.getTextComponent(); + int dot = tc.getCaretPosition(); + if (dot>0) { + dot--; // Workaround for Java Highlight issues + } + + List paramHighlights = getParameterHighlights(); + for (int i=0; i<paramHighlights.size(); i++) { + Highlight h = (Highlight)paramHighlights.get(i); + if (dot>=h.getStartOffset() && dot<h.getEndOffset()) { + return h.getStartOffset() + 1; + } + } + + return -1; + } @@ -208,6 +268,18 @@ class ParameterizedCompletionDescriptionToolTip { oldShiftTabAction = am.get(IM_KEY_SHIFT_TAB); am.put(IM_KEY_SHIFT_TAB, new PrevParamAction()); + ks = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0); + oldUpKey = im.get(ks); + im.put(ks, IM_KEY_UP); + oldUpAction = am.get(IM_KEY_UP); + am.put(IM_KEY_UP, new NextChoiceAction(-1, oldUpAction)); + + ks = KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0); + oldDownKey = im.get(ks); + im.put(ks, IM_KEY_DOWN); + oldDownAction = am.get(IM_KEY_DOWN); + am.put(IM_KEY_DOWN, new NextChoiceAction(1, oldDownAction)); + ks = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0); oldEnterKey = im.get(ks); im.put(ks, IM_KEY_ENTER); @@ -324,6 +396,42 @@ class ParameterizedCompletionDescriptionToolTip { /** + * Updates the optional window listing likely completion choices, + */ + private void prepareParamChoicesWindow() { + + if (paramChoicesWindow!=null) { + + int offs = getCurrentParameterStartOffset(); + if (offs==-1) { + paramChoicesWindow.setVisible(false); + paramChoicesWindow = null; + return; + } + + JTextComponent tc = ac.getTextComponent(); + try { + Rectangle r = tc.modelToView(offs); + Point p = new Point(r.x, r.y); + SwingUtilities.convertPointToScreen(p, tc); + r.x = p.x; + r.y = p.y; + paramChoicesWindow.setLocationRelativeTo(r); + } catch (BadLocationException ble) { // Should never happen + UIManager.getLookAndFeel().provideErrorFeedback(tc); + ble.printStackTrace(); + } + + paramChoicesWindow.setParameter(lastSelectedParam, + paramAlreadyEntered); + paramChoicesWindow.setVisible(true); + + } + + } + + + /** * Removes the bounding boxes around parameters. */ private void removeParameterHighlights() { @@ -382,16 +490,26 @@ class ParameterizedCompletionDescriptionToolTip { * <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); + prepareParamChoicesWindow(); } else { listener.uninstall(); } + tooltip.setVisible(visible); + if (paramChoicesWindow!=null) { + paramChoicesWindow.setVisible(visible); + } + } + } @@ -419,6 +537,14 @@ class ParameterizedCompletionDescriptionToolTip { im.put(ks, oldShiftTabKey); am.put(IM_KEY_SHIFT_TAB, oldShiftTabAction); + ks = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0); + im.put(ks, oldUpKey); + am.put(IM_KEY_UP, oldUpAction); + + ks = KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0); + im.put(ks, oldDownKey); + am.put(IM_KEY_DOWN, oldDownAction); + ks = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0); im.put(ks, oldEnterKey); am.put(IM_KEY_ENTER, oldEnterAction); @@ -439,8 +565,10 @@ class ParameterizedCompletionDescriptionToolTip { * Updates the text in the tool tip to have the current parameter * displayed in bold. The "current parameter" is determined from the * current caret position. + * + * @return Whether the text needed to be updated. */ - private void updateText() { + private boolean updateText() { JTextComponent tc = ac.getTextComponent(); int dot = tc.getCaretPosition(); @@ -452,13 +580,21 @@ class ParameterizedCompletionDescriptionToolTip { List paramHighlights = getParameterHighlights(); for (int i=0; i<paramHighlights.size(); i++) { Highlight h = (Highlight)paramHighlights.get(i); - if (dot>=h.getStartOffset() && dot<h.getEndOffset()) { + // "+1" because of param hack - see OutlineHighlightPainter + int start = h.getStartOffset()+1; + if (dot>=start && dot<h.getEndOffset()) { + try { + paramAlreadyEntered = tc.getText(start, dot-start); + } catch (BadLocationException ble) { + ble.printStackTrace(); + paramAlreadyEntered = null; + } index = i; break; } } - updateText(index); + return updateText(index); } @@ -468,13 +604,14 @@ class ParameterizedCompletionDescriptionToolTip { * displayed in bold. * * @param selectedParam The index of the selected parameter. + * @return Whether the text needed to be updated. */ - private void updateText(int selectedParam) { + private boolean 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; + return false; } lastSelectedParam = selectedParam; @@ -506,6 +643,8 @@ class ParameterizedCompletionDescriptionToolTip { descLabel.setText(sb.toString()); tooltip.pack(); + return true; + } @@ -515,6 +654,9 @@ class ParameterizedCompletionDescriptionToolTip { */ public void updateUI() { SwingUtilities.updateComponentTreeUI(tooltip); + if (paramChoicesWindow!=null) { + paramChoicesWindow.updateUI(); + } } @@ -549,7 +691,7 @@ class ParameterizedCompletionDescriptionToolTip { JTextComponent tc = ac.getTextComponent(); int dot = tc.getCaretPosition(); char end = pc.getProvider().getParameterListEnd(); - + // Are they at or past the end of the parameters? if (dot>=maxPos.getOffset()-1) { // ">=" for overwrite mode @@ -655,12 +797,17 @@ class ParameterizedCompletionDescriptionToolTip { public void caretUpdate(CaretEvent e) { if (maxPos==null) { // Sanity check setVisible(false, false); + return; } int dot = e.getDot(); if (dot<minPos || dot>=maxPos.getOffset()) { setVisible(false, false); + return; + } + boolean updated = updateText(); + if (updated) { + prepareParamChoicesWindow(); } - updateText(); } @@ -805,6 +952,38 @@ class ParameterizedCompletionDescriptionToolTip { /** + * Action performed when the user presses the up or down arrow keys and + * the parameter completion choices popup is visible. + * + * @author Robert Futrell + * @version 1.0 + */ + private class NextChoiceAction extends AbstractAction { + + private Action oldAction; + private int amount; + + public NextChoiceAction(int amount, Action oldAction) { + this.amount = amount; + this.oldAction = oldAction; + } + + public void actionPerformed(ActionEvent e) { + if (paramChoicesWindow!=null && paramChoicesWindow.isVisible()) { + paramChoicesWindow.incSelection(amount); + } + else if (oldAction!=null) { + oldAction.actionPerformed(e); + } + else { + setVisible(false, false); + } + } + + } + + + /** * Action performed when the user hits the tab key. * * @author Robert Futrell diff --git a/src/org/fife/ui/autocomplete/Util.java b/src/org/fife/ui/autocomplete/Util.java index a59e885..2f17cb1 100644 --- a/src/org/fife/ui/autocomplete/Util.java +++ b/src/org/fife/ui/autocomplete/Util.java @@ -37,7 +37,7 @@ import java.net.URI; * @author Robert Futrell * @version 1.0 */ -class Util { +public class Util { private static boolean desktopCreationAttempted; private static Object desktop; @@ -181,4 +181,29 @@ class Util { } + /** + * Returns whether <code>str</code> starts with <code>start</code>, + * ignoring case. + * + * @param str The string to check. + * @param start The prefix to check for. + * @return Whether <code>str</code> starts with <code>start</code>, + * ignoring case. + */ + public static boolean startsWithIgnoreCase(String str, String start) { + int startLen = start.length(); + if (str.length()>=startLen) { + for (int i=0; i<startLen; i++) { + char c1 = str.charAt(i); + char c2 = start.charAt(i); + if (Character.toLowerCase(c1)!=Character.toLowerCase(c2)) { + return false; + } + } + return true; + } + return false; + } + + } \ No newline at end of file -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/autocomplete.git _______________________________________________ pkg-java-commits mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-java-commits

