Search in sources :

Example 1 with EOFError

use of org.apache.felix.gogo.runtime.EOFError in project felix by apache.

the class Highlighter method highlight.

public AttributedString highlight(LineReader reader, String buffer) {
    try {
        Program program = null;
        List<Token> tokens = null;
        List<Statement> statements = null;
        String repaired = buffer;
        while (program == null) {
            try {
                org.apache.felix.gogo.runtime.Parser parser = new org.apache.felix.gogo.runtime.Parser(repaired);
                program = parser.program();
                tokens = parser.tokens();
                statements = parser.statements();
            } catch (EOFError e) {
                repaired = repaired + " " + e.repair();
                // Make sure we don't loop forever
                if (repaired.length() > buffer.length() + 1024) {
                    return new AttributedStringBuilder().append(buffer).toAttributedString();
                }
            }
        }
        Map<String, String> colors = Posix.getColorMap(session, "HIGHLIGHTER", DEFAULT_HIGHLIGHTER_COLORS);
        int underlineStart = -1;
        int underlineEnd = -1;
        int negativeStart = -1;
        int negativeEnd = -1;
        String search = reader.getSearchTerm();
        if (search != null && search.length() > 0) {
            underlineStart = buffer.indexOf(search);
            if (underlineStart >= 0) {
                underlineEnd = underlineStart + search.length() - 1;
            }
        }
        if (reader.getRegionActive() != RegionType.NONE) {
            negativeStart = reader.getRegionMark();
            negativeEnd = reader.getBuffer().cursor();
            if (negativeStart > negativeEnd) {
                int x = negativeEnd;
                negativeEnd = negativeStart;
                negativeStart = x;
            }
            if (reader.getRegionActive() == RegionType.LINE) {
                while (negativeStart > 0 && reader.getBuffer().atChar(negativeStart - 1) != '\n') {
                    negativeStart--;
                }
                while (negativeEnd < reader.getBuffer().length() - 1 && reader.getBuffer().atChar(negativeEnd + 1) != '\n') {
                    negativeEnd++;
                }
            }
        }
        Type[] types = new Type[repaired.length()];
        Arrays.fill(types, Type.Unknown);
        int cur = 0;
        for (Token token : tokens) {
            // We're on the repair side, so exit now
            if (token.start() >= buffer.length()) {
                break;
            }
            if (token.start() > cur) {
                cur = token.start();
            }
            // Find corresponding statement
            Statement statement = null;
            for (int i = statements.size() - 1; i >= 0; i--) {
                Statement s = statements.get(i);
                if (s.start() <= cur && cur < s.start() + s.length()) {
                    statement = s;
                    break;
                }
            }
            // Reserved tokens
            Type type = Type.Unknown;
            if (Token.eq(token, "{") || Token.eq(token, "}") || Token.eq(token, "(") || Token.eq(token, ")") || Token.eq(token, "[") || Token.eq(token, "]") || Token.eq(token, "|") || Token.eq(token, ";") || Token.eq(token, "=")) {
                type = Type.Reserved;
            } else if (token.charAt(0) == '\'' || token.charAt(0) == '"') {
                type = Type.String;
            } else if (token.toString().matches("^[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?$")) {
                type = Type.Number;
            } else if (token.charAt(0) == '$') {
                type = Type.Variable;
            } else if (((Set) session.get(CommandSessionImpl.CONSTANTS)).contains(token.toString()) || Token.eq(token, "null") || Token.eq(token, "false") || Token.eq(token, "true")) {
                type = Type.Constant;
            } else {
                boolean isFirst = statement != null && statement.tokens().size() > 0 && token == statement.tokens().get(0);
                boolean isThirdWithNext = statement != null && statement.tokens().size() > 3 && token == statement.tokens().get(2);
                boolean isAssign = statement != null && statement.tokens().size() > 1 && Token.eq(statement.tokens().get(1), "=");
                if (isFirst && isAssign) {
                    type = Type.VariableName;
                }
                if (isFirst && !isAssign || isAssign && isThirdWithNext) {
                    Object v = session.get(Shell.resolve(session, token.toString()));
                    type = (v instanceof Function) ? Type.Function : Type.BadFunction;
                }
            }
            Arrays.fill(types, token.start(), Math.min(token.start() + token.length(), types.length), type);
            cur = Math.min(token.start() + token.length(), buffer.length());
        }
        if (buffer.length() < repaired.length()) {
            Arrays.fill(types, buffer.length(), repaired.length(), Type.Repair);
        }
        AttributedStringBuilder sb = new AttributedStringBuilder();
        for (int i = 0; i < repaired.length(); i++) {
            sb.style(AttributedStyle.DEFAULT);
            applyStyle(sb, colors, types[i]);
            if (i >= underlineStart && i <= underlineEnd) {
                sb.style(sb.style().underline());
            }
            if (i >= negativeStart && i <= negativeEnd) {
                sb.style(sb.style().inverse());
            }
            char c = repaired.charAt(i);
            if (c == '\t' || c == '\n') {
                sb.append(c);
            } else if (c < 32) {
                sb.style(sb.style().inverseNeg()).append('^').append((char) (c + '@')).style(sb.style().inverseNeg());
            } else {
                int w = WCWidth.wcwidth(c);
                if (w > 0) {
                    sb.append(c);
                }
            }
        }
        return sb.toAttributedString();
    } catch (SyntaxError e) {
        return super.highlight(reader, buffer);
    }
}
Also used : Program(org.apache.felix.gogo.runtime.Parser.Program) Statement(org.apache.felix.gogo.runtime.Parser.Statement) Token(org.apache.felix.gogo.runtime.Token) AttributedStringBuilder(org.jline.utils.AttributedStringBuilder) AttributedString(org.jline.utils.AttributedString) Function(org.apache.felix.service.command.Function) RegionType(org.jline.reader.LineReader.RegionType) SyntaxError(org.apache.felix.gogo.runtime.SyntaxError) EOFError(org.apache.felix.gogo.runtime.EOFError)

Example 2 with EOFError

use of org.apache.felix.gogo.runtime.EOFError in project karaf by apache.

the class KarafParser method doParse.

private ParsedLine doParse(String line, int cursor, ParseContext parseContext) throws SyntaxError {
    Program program = null;
    List<Statement> statements = null;
    String repaired = line;
    while (program == null) {
        try {
            org.apache.felix.gogo.runtime.Parser parser = new org.apache.felix.gogo.runtime.Parser(repaired);
            program = parser.program();
            statements = parser.statements();
        } catch (EOFError e) {
            // Make sure we don't loop forever
            if (parseContext == ParseContext.COMPLETE && repaired.length() < line.length() + 1024) {
                repaired = repaired + " " + e.repair();
            } else {
                throw e;
            }
        }
    }
    // Find corresponding statement
    Statement statement = null;
    for (int i = statements.size() - 1; i >= 0; i--) {
        Statement s = statements.get(i);
        if (s.start() <= cursor) {
            boolean isOk = true;
            // check if there are only spaces after the previous statement
            if (s.start() + s.length() < cursor) {
                for (int j = s.start() + s.length(); isOk && j < cursor; j++) {
                    isOk = Character.isWhitespace(line.charAt(j));
                }
            }
            statement = s;
            break;
        }
    }
    if (statement != null && statement.tokens() != null && !statement.tokens().isEmpty()) {
        String cmdName = session.resolveCommand(statement.tokens().get(0).toString());
        String[] parts = cmdName.split(":");
        Command cmd = parts.length == 2 ? session.getRegistry().getCommand(parts[0], parts[1]) : null;
        Parser cmdParser = cmd != null ? cmd.getParser() : null;
        if (cmdParser != null) {
            final CommandLine cmdLine = cmdParser.parse(session, statement.toString(), cursor - statement.start());
            return new ParsedLine() {

                @Override
                public String word() {
                    return cmdLine.getCursorArgument();
                }

                @Override
                public int wordCursor() {
                    return cmdLine.getArgumentPosition();
                }

                @Override
                public int wordIndex() {
                    return cmdLine.getCursorArgumentIndex();
                }

                @Override
                public List<String> words() {
                    return Arrays.asList(cmdLine.getArguments());
                }

                @Override
                public String line() {
                    return cmdLine.getBuffer();
                }

                @Override
                public int cursor() {
                    return cmdLine.getBufferPosition();
                }
            };
        }
        if (repaired != line) {
            Token stmt = statement.subSequence(0, line.length() - statement.start());
            List<Token> tokens = new ArrayList<>(statement.tokens());
            Token last = tokens.get(tokens.size() - 1);
            tokens.set(tokens.size() - 1, last.subSequence(0, line.length() - last.start()));
            return new ParsedLineImpl(program, stmt, cursor, tokens);
        }
        return new ParsedLineImpl(program, statement, cursor, statement.tokens());
    } else {
        // TODO:
        return new ParsedLineImpl(program, program, cursor, Collections.singletonList(program));
    }
}
Also used : Program(org.apache.felix.gogo.runtime.Parser.Program) Statement(org.apache.felix.gogo.runtime.Parser.Statement) ArrayList(java.util.ArrayList) Token(org.apache.felix.gogo.runtime.Token) Parser(org.apache.karaf.shell.api.console.Parser) CommandLine(org.apache.karaf.shell.api.console.CommandLine) Command(org.apache.karaf.shell.api.console.Command) ParsedLineImpl(org.apache.felix.gogo.jline.ParsedLineImpl) ParsedLine(org.jline.reader.ParsedLine) EOFError(org.apache.felix.gogo.runtime.EOFError)

Aggregations

EOFError (org.apache.felix.gogo.runtime.EOFError)2 Program (org.apache.felix.gogo.runtime.Parser.Program)2 Statement (org.apache.felix.gogo.runtime.Parser.Statement)2 Token (org.apache.felix.gogo.runtime.Token)2 ArrayList (java.util.ArrayList)1 ParsedLineImpl (org.apache.felix.gogo.jline.ParsedLineImpl)1 SyntaxError (org.apache.felix.gogo.runtime.SyntaxError)1 Function (org.apache.felix.service.command.Function)1 Command (org.apache.karaf.shell.api.console.Command)1 CommandLine (org.apache.karaf.shell.api.console.CommandLine)1 Parser (org.apache.karaf.shell.api.console.Parser)1 RegionType (org.jline.reader.LineReader.RegionType)1 ParsedLine (org.jline.reader.ParsedLine)1 AttributedString (org.jline.utils.AttributedString)1 AttributedStringBuilder (org.jline.utils.AttributedStringBuilder)1