Package org.jnode.shell.bjorne

Source Code of org.jnode.shell.bjorne.BjorneCompleter

/*
* $Id$
*
* Copyright (C) 2003-2014 JNode.org
*
* 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.shell.bjorne;

import static org.jnode.shell.bjorne.BjorneToken.TOK_ASSIGNMENT;
import static org.jnode.shell.bjorne.BjorneToken.TOK_CASE_WORD;
import static org.jnode.shell.bjorne.BjorneToken.TOK_COMMAND_NAME;
import static org.jnode.shell.bjorne.BjorneToken.TOK_COMMAND_WORD;
import static org.jnode.shell.bjorne.BjorneToken.TOK_END_OF_LINE;
import static org.jnode.shell.bjorne.BjorneToken.TOK_END_OF_STREAM;
import static org.jnode.shell.bjorne.BjorneToken.TOK_FILE_NAME;
import static org.jnode.shell.bjorne.BjorneToken.TOK_FOR_NAME;
import static org.jnode.shell.bjorne.BjorneToken.TOK_FOR_WORD;
import static org.jnode.shell.bjorne.BjorneToken.TOK_FUNCTION_NAME;
import static org.jnode.shell.bjorne.BjorneToken.TOK_HERE_END;
import static org.jnode.shell.bjorne.BjorneToken.TOK_IO_NUMBER;
import static org.jnode.shell.bjorne.BjorneToken.TOK_NAME;
import static org.jnode.shell.bjorne.BjorneToken.TOK_PATTERN;
import static org.jnode.shell.bjorne.BjorneToken.TOK_WORD;

import org.jnode.driver.console.CompletionInfo;
import org.jnode.shell.ArgumentCompleter;
import org.jnode.shell.CommandShell;
import org.jnode.shell.Completable;
import org.jnode.shell.help.CompletionException;
import org.jnode.shell.syntax.AliasArgument;
import org.jnode.shell.syntax.Argument;
import org.jnode.shell.syntax.FileArgument;

/**
* This class is used by the Bjorne parser to capture completion information.
* It tries to capture the end of stream token and the one before it, together
* with the aggregated expectSets that were used for those two tokens.  It also
* captures the last 'simple command' node that was created, or was being being
* when we hit whatever it was that caused us to stop the parse.
*
* @author crawley@jnode.org
*/
public class BjorneCompleter implements Completable {
   
    private BjorneToken endToken;
    private BjorneToken penultimateToken;
    private long endExpectedSet;
    private long penultimateExpectedSet;
    private SimpleCommandNode command;
    private final BjorneContext context;

    public BjorneCompleter(BjorneContext context) {
        super();
        this.context = context;
    }

    @Override
    public void complete(CompletionInfo completions, CommandShell shell) throws CompletionException {
        if (endToken == null) {
            if (penultimateToken == null) {
                completeCommandWord(completions, shell, new BjorneToken(""));
                return;
            }
            endToken = penultimateToken;
            endExpectedSet = penultimateExpectedSet;
        }
        if (command != null) {
            BjorneToken[] words = command.getWords();
            if (words.length > 1 && words[words.length - 1] == penultimateToken) {
                boolean argumentAnticipated = penultimateToken.end < endToken.end;
                command.complete(completions, context, shell, argumentAnticipated);
            } else if (words.length == 1 && words[0] == penultimateToken && penultimateToken.end < endToken.end) {
                command.complete(completions, context, shell, true);
            }
        }
        String partial;
        BjorneToken token;
        long expectedSet;
        if (penultimateToken == null || penultimateToken.end < endToken.end) {
            partial = "";
            expectedSet = endExpectedSet;
            completions.setCompletionStart(endToken.start);
            token = endToken;
        } else {
            partial = penultimateToken.unparse();
            expectedSet = penultimateExpectedSet | endExpectedSet;
            completions.setCompletionStart(penultimateToken.start);
            token = penultimateToken;
        }
        if (!partial.equals(token.getText())) {
            token = new BjorneToken(token.getTokenType(), token.unparse(), token.start, token.end);
        }
        for (int i = 0; i < 64; i++) {
            if (((1L << i) & expectedSet) == 0) {
                continue;
            }
            switch (i) {
                case TOK_END_OF_LINE:
                case TOK_END_OF_STREAM:
                    // These are not completable
                    break;
                case TOK_WORD:
                case TOK_NAME:
                    // These are generic token types... completion is based on more specific types
                    break;
                case TOK_IO_NUMBER:
                case TOK_COMMAND_WORD:
                case TOK_FUNCTION_NAME:
                case TOK_HERE_END:
                case TOK_FOR_NAME:
                case TOK_PATTERN:
                case TOK_CASE_WORD:
                    // Ignore for purposes of completion
                    break;
                case TOK_ASSIGNMENT:
                    ArgumentCompleter ac = new ArgumentCompleter(
                            new AssignmentArgument("?", context, Argument.MANDATORY, null), token);
                    ac.complete(completions, shell);
                    break;
                case TOK_FOR_WORD:
                case TOK_FILE_NAME:
                    // Complete against the file system namespace
                    ac = new ArgumentCompleter(
                            new FileArgument("?", Argument.MANDATORY, null), token);
                    ac.complete(completions, shell);
                    break;
                case TOK_COMMAND_NAME:
                    // Complete against the command/alias/function namespaces
                    completeCommandWord(completions, shell, token);
                    break;
                default:
                    String candidate = BjorneToken.toString(i);
                    if (candidate.startsWith(partial)) {
                        completions.addCompletion(candidate);
                    }
            }
        }
    }
   
    private void completeCommandWord(CompletionInfo completions, CommandShell shell, BjorneToken token) {
        // FIXME ... do functions ...
        for (String builtinName : BjorneInterpreter.BUILTINS.keySet()) {
            if (builtinName.startsWith(token.text)) {
                completions.addCompletion(builtinName);
            }
        }
        ArgumentCompleter ac = new ArgumentCompleter(
                new AliasArgument("?", Argument.MANDATORY, null), token);
        ac.complete(completions, shell);
        ac = new ArgumentCompleter(
                new BjorneAliasNameArgument("?", context, Argument.MANDATORY, null), token);
        ac.complete(completions, shell);
    }

    public void setEndToken(BjorneToken endToken) {
        this.endToken = endToken;
    }

    public BjorneToken getEndToken() {
        return endToken;
    }

    public void setPenultimateToken(BjorneToken penultimateToken) {
        this.penultimateToken = penultimateToken;
    }

    public BjorneToken getPenultimateToken() {
        return penultimateToken;
    }

    public void setEndExpectedSet(long expectedSet) {
        this.endExpectedSet = expectedSet;
    }

    public void addToEndExpectedSet(long expectedSet) {
        this.endExpectedSet |= expectedSet;
    }

    public long getEndExpectedSet() {
        return endExpectedSet;
    }
   
    public void setPenultimateExpectedSet(long expectedSet) {
        this.penultimateExpectedSet = expectedSet;
    }

    public void addToPenultimateExpectedSet(long expectedSet) {
        this.penultimateExpectedSet |= expectedSet;
    }

    public long getPenultimateExpectedSet() {
        return penultimateExpectedSet;
    }

    public void setCommand(SimpleCommandNode command) {
        this.command = command;
    }

    public SimpleCommandNode getCommand() {
        return command;
    }
   
    @Override
    public String toString() {
        return "BjorneCompleter{endToken=" + BjorneToken.toString(endToken) +
            ",endExpectedSet={" + BjorneToken.formatExpectedSet(endExpectedSet) +
            "},penultimateToken=" + BjorneToken.toString(penultimateToken) +
            ",penultimateExpectedSet={" + BjorneToken.formatExpectedSet(penultimateExpectedSet) +
            "},command=" + command + "}";
    }
   
}
TOP

Related Classes of org.jnode.shell.bjorne.BjorneCompleter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.