use of org.jline.builtins.Less in project felix by apache.
the class Posix method less.
protected void less(CommandSession session, Process process, String[] argv) throws Exception {
String[] usage = { "less - file pager", "Usage: less [OPTIONS] [FILES]", " -? --help Show help", " -e --quit-at-eof Exit on second EOF", " -E --QUIT-AT-EOF Exit on EOF", " -F --quit-if-one-screen Exit if entire file fits on first screen", " -q --quiet --silent Silent mode", " -Q --QUIET --SILENT Completely silent", " -S --chop-long-lines Do not fold long lines", " -i --ignore-case Search ignores lowercase case", " -I --IGNORE-CASE Search ignores all case", " -x --tabs Set tab stops", " -N --LINE-NUMBERS Display line number for each line", " --no-init Disable terminal initialization", " --no-keypad Disable keypad handling" };
boolean hasExtendedOptions = false;
try {
Less.class.getField("quitIfOneScreen");
hasExtendedOptions = true;
} catch (NoSuchFieldException e) {
List<String> ustrs = new ArrayList<>(Arrays.asList(usage));
ustrs.removeIf(s -> s.contains("--quit-if-one-screen") || s.contains("--no-init") || s.contains("--no-keypad"));
usage = ustrs.toArray(new String[ustrs.size()]);
}
Options opt = parseOptions(session, usage, argv);
List<Source> sources = new ArrayList<>();
if (opt.args().isEmpty()) {
opt.args().add("-");
}
for (String arg : opt.args()) {
if ("-".equals(arg)) {
sources.add(new StdInSource(process));
} else {
sources.add(new PathSource(session.currentDir().resolve(arg), arg));
}
}
if (!process.isTty(1)) {
for (Source source : sources) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(source.read()))) {
cat(process, reader, opt.isSet("LINE-NUMBERS"));
}
}
return;
}
Less less = new Less(Shell.getTerminal(session));
less.quitAtFirstEof = opt.isSet("QUIT-AT-EOF");
less.quitAtSecondEof = opt.isSet("quit-at-eof");
less.quiet = opt.isSet("quiet");
less.veryQuiet = opt.isSet("QUIET");
less.chopLongLines = opt.isSet("chop-long-lines");
less.ignoreCaseAlways = opt.isSet("IGNORE-CASE");
less.ignoreCaseCond = opt.isSet("ignore-case");
if (opt.isSet("tabs")) {
less.tabs = opt.getNumber("tabs");
}
less.printLineNumbers = opt.isSet("LINE-NUMBERS");
if (hasExtendedOptions) {
Less.class.getField("quitIfOneScreen").set(less, opt.isSet("quit-if-one-screen"));
Less.class.getField("noInit").set(less, opt.isSet("no-init"));
Less.class.getField("noKeypad").set(less, opt.isSet("no-keypad"));
}
less.run(sources);
}
use of org.jline.builtins.Less in project felix by apache.
the class Posix method ls.
protected void ls(CommandSession session, Process process, String[] argv) throws Exception {
final String[] usage = { "ls - list files", "Usage: ls [OPTIONS] [PATTERNS...]", " -? --help show help", " -1 list one entry per line", " -C multi-column output", " --color=WHEN colorize the output, may be `always', `never' or `auto'", " -a list entries starting with .", " -F append file type indicators", " -m comma separated", " -l long listing", " -S sort by size", " -f output is not sorted", " -r reverse sort order", " -t sort by modification time", " -x sort horizontally", " -L list referenced file for links", " -h print sizes in human readable form" };
Options opt = parseOptions(session, usage, argv);
String color = opt.isSet("color") ? opt.get("color") : "auto";
boolean colored;
switch(color) {
case "always":
case "yes":
case "force":
colored = true;
break;
case "never":
case "no":
case "none":
colored = false;
break;
case "auto":
case "tty":
case "if-tty":
colored = process.isTty(1);
break;
default:
throw new IllegalArgumentException("invalid argument ‘" + color + "’ for ‘--color’");
}
Map<String, String> colors = colored ? getLsColorMap(session) : Collections.emptyMap();
class PathEntry implements Comparable<PathEntry> {
final Path abs;
final Path path;
final Map<String, Object> attributes;
public PathEntry(Path abs, Path root) {
this.abs = abs;
this.path = abs.startsWith(root) ? root.relativize(abs) : abs;
this.attributes = readAttributes(abs);
}
@Override
public int compareTo(PathEntry o) {
int c = doCompare(o);
return opt.isSet("r") ? -c : c;
}
private int doCompare(PathEntry o) {
if (opt.isSet("f")) {
return -1;
}
if (opt.isSet("S")) {
long s0 = attributes.get("size") != null ? ((Number) attributes.get("size")).longValue() : 0L;
long s1 = o.attributes.get("size") != null ? ((Number) o.attributes.get("size")).longValue() : 0L;
return s0 > s1 ? -1 : s0 < s1 ? 1 : path.toString().compareTo(o.path.toString());
}
if (opt.isSet("t")) {
long t0 = attributes.get("lastModifiedTime") != null ? ((FileTime) attributes.get("lastModifiedTime")).toMillis() : 0L;
long t1 = o.attributes.get("lastModifiedTime") != null ? ((FileTime) o.attributes.get("lastModifiedTime")).toMillis() : 0L;
return t0 > t1 ? -1 : t0 < t1 ? 1 : path.toString().compareTo(o.path.toString());
}
return path.toString().compareTo(o.path.toString());
}
boolean isNotDirectory() {
return is("isRegularFile") || is("isSymbolicLink") || is("isOther");
}
boolean isDirectory() {
return is("isDirectory");
}
private boolean is(String attr) {
Object d = attributes.get(attr);
return d instanceof Boolean && (Boolean) d;
}
String display() {
String type;
String suffix;
String link = "";
if (is("isSymbolicLink")) {
type = "sl";
suffix = "@";
try {
Path l = Files.readSymbolicLink(abs);
link = " -> " + l.toString();
} catch (IOException e) {
// ignore
}
} else if (is("isDirectory")) {
type = "dr";
suffix = "/";
} else if (is("isExecutable")) {
type = "ex";
suffix = "*";
} else if (is("isOther")) {
type = "ot";
suffix = "";
} else {
type = "";
suffix = "";
}
String col = colors.get(type);
boolean addSuffix = opt.isSet("F");
if (col != null && !col.isEmpty()) {
return "\033[" + col + "m" + path.toString() + "\033[m" + (addSuffix ? suffix : "") + link;
} else {
return path.toString() + (addSuffix ? suffix : "") + link;
}
}
String longDisplay() {
String username;
if (attributes.containsKey("owner")) {
username = Objects.toString(attributes.get("owner"), null);
} else {
username = "owner";
}
if (username.length() > 8) {
username = username.substring(0, 8);
} else {
for (int i = username.length(); i < 8; i++) {
username = username + " ";
}
}
String group;
if (attributes.containsKey("group")) {
group = Objects.toString(attributes.get("group"), null);
} else {
group = "group";
}
if (group.length() > 8) {
group = group.substring(0, 8);
} else {
for (int i = group.length(); i < 8; i++) {
group = group + " ";
}
}
Number length = (Number) attributes.get("size");
if (length == null) {
length = 0L;
}
String lengthString;
if (opt.isSet("h")) {
double l = length.longValue();
String unit = "B";
if (l >= 1000) {
l /= 1024;
unit = "K";
if (l >= 1000) {
l /= 1024;
unit = "M";
if (l >= 1000) {
l /= 1024;
unit = "T";
}
}
}
if (l < 10 && length.longValue() > 1000) {
lengthString = String.format("%.1f", l) + unit;
} else {
lengthString = String.format("%3.0f", l) + unit;
}
} else {
lengthString = String.format("%1$8s", length);
}
@SuppressWarnings("unchecked") Set<PosixFilePermission> perms = (Set<PosixFilePermission>) attributes.get("permissions");
if (perms == null) {
perms = EnumSet.noneOf(PosixFilePermission.class);
}
// TODO: all fields should be padded to align
return (is("isDirectory") ? "d" : (is("isSymbolicLink") ? "l" : (is("isOther") ? "o" : "-"))) + PosixFilePermissions.toString(perms) + " " + String.format("%3s", (attributes.containsKey("nlink") ? attributes.get("nlink").toString() : "1")) + " " + username + " " + group + " " + lengthString + " " + toString((FileTime) attributes.get("lastModifiedTime")) + " " + display();
}
protected String toString(FileTime time) {
long millis = (time != null) ? time.toMillis() : -1L;
if (millis < 0L) {
return "------------";
}
ZonedDateTime dt = Instant.ofEpochMilli(millis).atZone(ZoneId.systemDefault());
// Less than six months
if (System.currentTimeMillis() - millis < 183L * 24L * 60L * 60L * 1000L) {
return DateTimeFormatter.ofPattern("MMM ppd HH:mm").format(dt);
} else // Older than six months
{
return DateTimeFormatter.ofPattern("MMM ppd yyyy").format(dt);
}
}
protected Map<String, Object> readAttributes(Path path) {
Map<String, Object> attrs = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
for (String view : path.getFileSystem().supportedFileAttributeViews()) {
try {
Map<String, Object> ta = Files.readAttributes(path, view + ":*", getLinkOptions(opt.isSet("L")));
ta.entrySet().forEach(e -> attrs.putIfAbsent(e.getKey(), e.getValue()));
} catch (IOException e) {
// Ignore
}
}
attrs.computeIfAbsent("isExecutable", s -> Files.isExecutable(path));
attrs.computeIfAbsent("permissions", s -> getPermissionsFromFile(path.toFile()));
return attrs;
}
}
Path currentDir = session.currentDir();
// Listing
List<Path> expanded = new ArrayList<>();
if (opt.args().isEmpty()) {
expanded.add(currentDir);
} else {
opt.args().forEach(s -> expanded.add(currentDir.resolve(s)));
}
boolean listAll = opt.isSet("a");
Predicate<Path> filter = p -> listAll || !p.getFileName().toString().startsWith(".");
List<PathEntry> all = expanded.stream().filter(filter).map(p -> new PathEntry(p, currentDir)).sorted().collect(Collectors.toList());
// Print files first
List<PathEntry> files = all.stream().filter(PathEntry::isNotDirectory).collect(Collectors.toList());
PrintStream out = process.out();
Consumer<Stream<PathEntry>> display = s -> {
boolean optLine = opt.isSet("1");
boolean optComma = opt.isSet("m");
boolean optLong = opt.isSet("l");
boolean optCol = opt.isSet("C");
if (!optLine && !optComma && !optLong && !optCol) {
if (process.isTty(1)) {
optCol = true;
} else {
optLine = true;
}
}
// One entry per line
if (optLine) {
s.map(PathEntry::display).forEach(out::println);
} else // Comma separated list
if (optComma) {
out.println(s.map(PathEntry::display).collect(Collectors.joining(", ")));
} else // Long listing
if (optLong) {
s.map(PathEntry::longDisplay).forEach(out::println);
} else // Column listing
if (optCol) {
toColumn(session, process, out, s.map(PathEntry::display), opt.isSet("x"));
}
};
boolean space = false;
if (!files.isEmpty()) {
display.accept(files.stream());
space = true;
}
// Print directories
List<PathEntry> directories = all.stream().filter(PathEntry::isDirectory).collect(Collectors.toList());
for (PathEntry entry : directories) {
if (space) {
out.println();
}
space = true;
Path path = currentDir.resolve(entry.path);
if (expanded.size() > 1) {
out.println(currentDir.relativize(path).toString() + ":");
}
display.accept(Stream.concat(Arrays.asList(".", "..").stream().map(path::resolve), Files.list(path)).filter(filter).map(p -> new PathEntry(p, path)).sorted());
}
}
Aggregations