001/*
002 * (C) Copyright 2006-2007 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     bstefanescu
016 *
017 * $Id$
018 */
019
020package org.nuxeo.shell.cmds.completors;
021
022import java.util.List;
023
024import jline.ArgumentCompletor.WhitespaceArgumentDelimiter;
025import jline.Completor;
026
027import org.nuxeo.shell.CommandType;
028import org.nuxeo.shell.Shell;
029import org.nuxeo.shell.cmds.Interactive;
030
031/**
032 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
033 */
034public class ShellCompletor implements Completor {
035
036    private final Interactive interactive;
037
038    private final CommandCompletor completor;
039
040    public ShellCompletor(Interactive interactive) {
041        this.interactive = interactive;
042        completor = new CommandCompletor(interactive.getShell());
043    }
044
045    @SuppressWarnings("rawtypes")
046    public int complete(String buffer, int cursor, List candidates) {
047        jline.ArgumentCompletor.ArgumentList list = new WhitespaceArgumentDelimiter().delimit(buffer, cursor);
048        String[] args = list.getArguments();
049        // the current arg text (null if empty - i.e. after a space)
050        String argText = list.getCursorArgument();
051        // the offset of the current arg
052        int argIndex = list.getCursorArgumentIndex();
053        // the offset of the next character relative to the cursor in the
054        // current arg
055        int offset = list.getArgumentPosition();
056        // the leading text in the current arg
057        String text = argText == null ? null : argText.substring(0, offset);
058        if (argIndex == 0) {
059            int ret = completor.complete(text, offset, candidates);
060            return ret + (list.getBufferPosition() - offset);
061        } else {
062            Shell shell = interactive.getShell();
063            CommandType cmd = shell.getActiveRegistry().getCommandType(args[0]);
064            if (cmd == null) { // no such command
065                return -1;
066            }
067            if (argIndex >= args.length) {
068                // at the beginning of a new token
069                String[] newArgs = new String[args.length + 1];
070                System.arraycopy(args, 0, newArgs, 0, args.length);
071                newArgs[args.length] = "";
072                args = newArgs;
073            } else if (argIndex < args.length) { // TODO
074                String[] newArgs = new String[argIndex + 1];
075                System.arraycopy(args, 0, newArgs, 0, newArgs.length);
076                args = newArgs;
077            }
078            Completor comp = cmd.getLastTokenCompletor(shell, args);
079            if (comp != null) {
080                int ret = comp.complete(text, offset, candidates);
081                return ret + (list.getBufferPosition() - offset);
082            }
083            return -1;
084        }
085    }
086
087}