All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.termd.core.readline.InputrcParser Maven / Gradle / Ivy

Go to download

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+.

There is a newer version: 1.1.7.14
Show newest version
/*
 * 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;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy