use of org.apache.felix.gogo.runtime.Parser.Program 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);
}
}
use of org.apache.felix.gogo.runtime.Parser.Program in project felix by apache.
the class TestParser method testPipeRedir.
@Test
public void testPipeRedir() {
Program x = new Parser("abc def|&ghi").program();
Pipeline p0 = (Pipeline) x.tokens().get(0);
Statement s00 = (Statement) p0.tokens().get(0);
assertEquals("|&", p0.tokens().get(1).toString());
Statement s01 = (Statement) p0.tokens().get(2);
assertEquals("abc", s00.tokens().get(0).toString());
assertEquals("def", s00.tokens().get(1).toString());
assertEquals("ghi", s01.tokens().get(0).toString());
}
use of org.apache.felix.gogo.runtime.Parser.Program in project felix by apache.
the class TestParser method testBackground.
@Test
public void testBackground() {
Program x = new Parser("echo foo&echo bar").program();
Statement s0 = (Statement) x.tokens().get(0);
assertEquals("&", x.tokens().get(1).toString());
Statement s1 = (Statement) x.tokens().get(2);
assertEquals("echo", s0.tokens().get(0).toString());
assertEquals("foo", s0.tokens().get(1).toString());
assertEquals("echo", s1.tokens().get(0).toString());
assertEquals("bar", s1.tokens().get(1).toString());
}
use of org.apache.felix.gogo.runtime.Parser.Program in project felix by apache.
the class TestParser method testProgram.
@Test
public void testProgram() {
Program x = new Parser("abc def|ghi jkl;mno pqr|stu vwx").program();
Pipeline p0 = (Pipeline) x.tokens().get(0);
Statement s00 = (Statement) p0.tokens().get(0);
assertEquals("|", p0.tokens().get(1).toString());
Statement s01 = (Statement) p0.tokens().get(2);
assertEquals(";", x.tokens().get(1).toString());
Pipeline p1 = (Pipeline) x.tokens().get(2);
Statement s10 = (Statement) p1.tokens().get(0);
assertEquals("|", p1.tokens().get(1).toString());
Statement s11 = (Statement) p1.tokens().get(2);
assertEquals("abc", s00.tokens().get(0).toString());
assertEquals("def", s00.tokens().get(1).toString());
assertEquals("ghi", s01.tokens().get(0).toString());
assertEquals("jkl", s01.tokens().get(1).toString());
assertEquals("mno", s10.tokens().get(0).toString());
assertEquals("pqr", s10.tokens().get(1).toString());
assertEquals("stu", s11.tokens().get(0).toString());
assertEquals("vwx", s11.tokens().get(1).toString());
}
use of org.apache.felix.gogo.runtime.Parser.Program in project felix by apache.
the class TestParser method testPipeAndOr.
@Test
public void testPipeAndOr() {
Program x = new Parser("abc|def&&ghi || jkl").program();
Pipeline p0 = (Pipeline) x.tokens().get(0);
Statement s00 = (Statement) p0.tokens().get(0);
assertEquals("|", p0.tokens().get(1).toString());
Statement s01 = (Statement) p0.tokens().get(2);
assertEquals("&&", x.tokens().get(1).toString());
Statement s1 = (Statement) x.tokens().get(2);
assertEquals("||", x.tokens().get(3).toString());
Statement s2 = (Statement) x.tokens().get(4);
assertEquals("abc", s00.tokens().get(0).toString());
assertEquals("def", s01.tokens().get(0).toString());
assertEquals("ghi", s1.tokens().get(0).toString());
assertEquals("jkl", s2.tokens().get(0).toString());
}
Aggregations