    001    /*
    002     * SideKickCompletion.java
    003     * :tabSize=8:indentSize=8:noTabs=false:
    004     * :folding=explicit:collapseFolds=1:
    005     *
    006     * Copyright (C) 2003, 2005 Slava Pestov
    007     *
    008     * This program is free software; you can redistribute it and/or
    009     * modify it under the terms of the GNU General Public License
    010     * as published by the Free Software Foundation; either version 2
    011     * of the License, or any later version.
    012     *
    013     * This program is distributed in the hope that it will be useful,
    014     * but WITHOUT ANY WARRANTY; without even the implied warranty of
    015     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    016     * GNU General Public License for more details.
    017     *
    018     * You should have received a copy of the GNU General Public License
    019     * along with this program; if not, write to the Free Software
    020     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    021     */
    022
    023    package sidekick;
    024
    025    //{{{ Imports
    026    import javax.swing.*;
    027    import java.util.*;
    028    import org.gjt.sp.jedit.*;
    029    import org.gjt.sp.jedit.buffer.JEditBuffer;
    030    import org.gjt.sp.jedit.textarea.*;
    031    //}}}
    032
    033    /**
    034     * A code completion instance.<p>
    035     *
    036     * This is a wrapper around a collection of possible completions, with callbacks
    037     * for inserting and displaying the completions in a popup menu.
    038     *
    039     * @author Slava Pestov
    040     * @version $Id: SideKickCompletion.java,v 1.8 2006/06/04 15:03:49 ezust Exp $
    041     * @since SideKick 0.3
    042     */
    043    public abstract class SideKickCompletion
    044    {
    045            //{{{ SideKickCompletion constructor
    046            /**
    047             * @deprecated Use the other constructor instead.
    048             */
    049            public SideKickCompletion() {}
    050            //}}}
    051
    052            //{{{ SideKickCompletion constructor
    053            /**
    054             * @since SideKick 0.3.2
    055             */
    056            public SideKickCompletion(View view, String text)
    057            {
    058                    this.view = view;
    059                    textArea = view.getTextArea();
    060                    this.text = text;
    061            } //}}}
    062
    063            //{{{ SideKickCompletion constructor
    064            /**
    065             * @since SideKick 0.3.2
    066             * @param items - a list of strings containing the possible completions.
    067             */
    068            public SideKickCompletion(View view, String text, List items)
    069            {
    070                    this(view,text);
    071                    this.items = items;
    072            } //}}}
    073
    074            //{{{ SideKickCompletion constructor
    075            /**
    076             * @since SideKick 0.3.2
    077             */
    078            public SideKickCompletion(View view, String text, Object[] items)
    079            {
    080                    this(view,text);
    081                    this.items = Arrays.asList(items);
    082            } //}}}
    083
    084            //{{{ size() method
    085            public int size()
    086            {
    087                    return items.size();
    088            } //}}}
    089
    090            //{{{ get() method
    091            public Object get(int index)
    092            {
    093                    return items.get(index);
    094            } //}}}
    095
    096            //{{{ getCompletionDescription() method
    097            public String getCompletionDescription(int index)
    098            {
    099                    return null;
    100            } //}}}
    101
    102            //{{{ isCompletionSelectable() method
    103            public boolean isCompletionSelectable(int index)
    104            {
    105                    return true;
    106            } //}}}
    107
    108            //{{{ updateInPlace() method
    109            /**
    110             * @return If this returns false, then we create a new completion
    111             * object after user input.
    112             */
    113            public boolean updateInPlace(EditPane editPane, int caret)
    114            {
    115                    return false;
    116            } //}}}
    117
    118            //{{{ getRenderer() method
    119            public ListCellRenderer getRenderer()
    120            {
    121                    return new DefaultListCellRenderer();
    122            } //}}}
    123
    124            //{{{ insert() method
    125            public void insert(int index)
    126            {
    127                    String selected = String.valueOf(get(index));
    128                    int caret = textArea.getCaretPosition();
    129                    Selection s = textArea.getSelectionAtOffset(caret);
    130                    int start = (s == null ? caret : s.getStart());
    131                    int end = (s == null ? caret : s.getEnd());
    132                    JEditBuffer buffer = textArea.getBuffer();
    133                    try
    134                    {
    135                            buffer.beginCompoundEdit();
    136                            buffer.remove(start - text.length(),text.length());
    137                            buffer.insert(start - text.length(),selected);
    138                    }
    139                    finally
    140                    {
    141                            buffer.endCompoundEdit();
    142                    }
    143            } //}}}
    144
    145            //{{{ getTokenLength() method
    146            /**
    147             * The length of the text being completed (popup will be positioned there).
    148             */
    149            public int getTokenLength()
    150            {
    151                    return text.length();
    152            } //}}}
    153
    154            //{{{ handleKeystroke() method
    155            /**
    156             * @param selectedIndex -1 if the popup is empty, otherwise the index of
    157             * the selected completion.
    158             * @param keyChar the character typed by the user.
    159             * @return True if completion should continue, false otherwise.
    160             * @since SideKick 0.3.2
    161             */
    162            public boolean handleKeystroke(int selectedIndex, char keyChar)
    163            {
    164                    if(keyChar == '\t' || keyChar == '\n')
    165                    {
    166                            insert(selectedIndex);
    167                            return false;
    168                    }
    169                    else if(keyChar == ' ')
    170                    {
    171                            insert(selectedIndex);
    172                            textArea.userInput(' ');
    173                            return false;
    174                    }
    175                    else
    176                    {
    177                            textArea.userInput(keyChar);
    178                            return true;
    179                    }
    180            } //}}}
    181
    182            protected View view;
    183            protected JEditTextArea textArea;
    184            protected String text;
    185            protected List items = new ArrayList();
    186    }