io.termd.core.readline.InputrcParser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of termd-core Show documentation
Show all versions of termd-core Show documentation
An open source terminal daemon library providing terminal handling in Java,
back ported to Alibaba by core engine team to support running on JDK 6+.
/*
* Copyright 2015 Julien Viet
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.termd.core.readline;
import io.termd.core.util.Logging;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author Julien Viet
*/
public abstract class InputrcParser {
static final Pattern COMMENT = Pattern.compile("#.*");
static final Pattern CONDITIONAL = Pattern.compile("\\$.*");
static final Pattern SET_VARIABLE = Pattern.compile("set\\s+(\\S)+\\s+(\\S)+\\s*");
static final Pattern BIND = Pattern.compile("(?:(?:\"(.*)\")|(.*))" + ":\\s*" + "(?:(?:\"(.*)\")|(?:'(.*)')|(\\S+))" + "\\s*");
static final Pattern A = Pattern.compile("^\\\\([0-9]{1,3})");
static final Pattern B = Pattern.compile("^\\\\x([0-9,A-F,a-f]{1,2})");
static void parse(String s, InputrcParser handler) throws UnsupportedEncodingException {
parse(new ByteArrayInputStream(s.getBytes("US-ASCII")), handler);
}
static void parse(InputStream s, InputrcParser handler) {
Scanner sc = new Scanner(s, "US-ASCII").useDelimiter("\n");
while (sc.hasNext()) {
String next = sc.next();
if (COMMENT.matcher(next).matches()) {
} else if (CONDITIONAL.matcher(next).matches()) {
Logging.READLINE.warn("Inputrc conditional not implemented");
} else {
Matcher matcher = SET_VARIABLE.matcher(next);
if (matcher.matches()) {
String variable = matcher.group(1);
String value = matcher.group(2);
Logging.READLINE.warn("Inputrc set variable not implemented");
} else {
matcher = BIND.matcher(next);
if (matcher.matches()) {
String keyseq = matcher.group(1);
String keyname = matcher.group(2);
String macro1 = matcher.group(3);
String macro2 = matcher.group(4);
String functionname = matcher.group(5);
if (keyseq != null) {
int[] f = parseKeySeq(keyseq);
if (functionname != null) {
handler.bindFunction(f, functionname);
} else if (macro1 != null) {
handler.bindMacro(f, macro1);
} else {
handler.bindMacro(f, macro2);
}
} else {
if (functionname != null) {
handler.bindFunction(keyname, functionname);
} else if (macro1 != null) {
handler.bindMacro(keyname, macro1);
} else {
handler.bindMacro(keyname, macro2);
}
}
}
}
}
}
}
void bindMacro(String keyName, String macro) {
}
void bindFunction(String keyName, String functionName) {
}
void bindMacro(int[] keySequence, String macro) {
}
void bindFunction(int[] keySequence, String functionName) {
}
public static Keymap create() {
InputStream inputrc = InputrcParser.class.getResourceAsStream("inputrc");
return new Keymap(inputrc);
}
static int[] parseKeySeq(String keyseq) {
ArrayList builder = new ArrayList();
while (keyseq.length() > 0) {
if (keyseq.startsWith("\\C-") && keyseq.length() > 3) {
int c = (Character.toUpperCase(keyseq.charAt(3)) - '@') & 0x7F;
builder.add(c);
keyseq = keyseq.substring(4);
} else if (keyseq.startsWith("\\M-") && keyseq.length() > 3) {
int c = (Character.toUpperCase(keyseq.charAt(3)) - '@') & 0x7F;
builder.add(27);
builder.add(c);
keyseq = keyseq.substring(4);
} else if (keyseq.startsWith("\\e")) {
builder.add(27);
keyseq = keyseq.substring(2);
} else if (keyseq.startsWith("\\\\")) {
builder.add((int)'\\');
keyseq = keyseq.substring(2);
} else if (keyseq.startsWith("\\\"")) {
builder.add((int)'"');
keyseq = keyseq.substring(2);
} else if (keyseq.startsWith("\\'")) {
builder.add((int)'\'');
keyseq = keyseq.substring(2);
} else if (keyseq.startsWith("\\a")) {
builder.add(7);
keyseq = keyseq.substring(2);
} else if (keyseq.startsWith("\\b")) {
builder.add(8);
keyseq = keyseq.substring(2);
} else if (keyseq.startsWith("\\d")) {
builder.add(127);
keyseq = keyseq.substring(2);
} else if (keyseq.startsWith("\\f")) {
builder.add(12);
keyseq = keyseq.substring(2);
} else if (keyseq.startsWith("\\n")) {
builder.add(10);
keyseq = keyseq.substring(2);
} else if (keyseq.startsWith("\\r")) {
builder.add(13);
keyseq = keyseq.substring(2);
} else if (keyseq.startsWith("\\t")) {
builder.add(9);
keyseq = keyseq.substring(2);
} else if (keyseq.startsWith("\\v")) {
builder.add(11);
keyseq = keyseq.substring(2);
} else {
Matcher matcher = A.matcher(keyseq);
if (matcher.find()) {
builder.add(Integer.parseInt(matcher.group(1), 8));
keyseq = keyseq.substring(matcher.end());
} else {
matcher = B.matcher(keyseq);
if (matcher.find()) {
builder.add(Integer.parseInt(matcher.group(1), 16));
keyseq = keyseq.substring(matcher.end());
} else {
builder.add((int) keyseq.charAt(0));
keyseq = keyseq.substring(1);
}
}
}
}
int[] f = new int[builder.size()];
for (int i = 0;i < builder.size();i++) {
f[i] = builder.get(i);
}
return f;
}
}