/* * Copyright (c) 2009-present the original author or authors. * * 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 com.planet57.gshell.util.jline; import org.jline.builtins.Less; import org.jline.terminal.Terminal; import org.jline.utils.AttributedString; import org.jline.utils.AttributedStringBuilder; import javax.annotation.Nullable; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.PrintWriter; import java.util.List; import java.util.function.IntBinaryOperator; import java.util.stream.Collectors; import java.util.stream.Stream; /** * {@link Terminal} helpers. * * @since 3.0 */ public class TerminalHelper { private TerminalHelper() { // empty } // Adapted from: https://github.com/apache/felix/blob/trunk/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Posix.java public static void printColumns(final Terminal terminal, final PrintWriter out, final Stream<String> values, final boolean horizontal) { int width = terminal.getWidth(); List<AttributedString> strings = values.map(AttributedString::fromAnsi).collect(Collectors.toList()); if (!strings.isEmpty()) { int max = strings.stream().mapToInt(AttributedString::columnLength).max().getAsInt(); int c = Math.max(1, width / max); while (c > 1 && c * max + (c - 1) >= width) { c--; } int columns = c; int lines = (strings.size() + columns - 1) / columns; IntBinaryOperator index; if (horizontal) { index = (i, j) -> i * columns + j; } else { index = (i, j) -> j * lines + i; } AttributedStringBuilder buff = new AttributedStringBuilder(); for (int i = 0; i < lines; i++) { for (int j = 0; j < columns; j++) { int idx = index.applyAsInt(i, j); if (idx < strings.size()) { AttributedString str = strings.get(idx); boolean hasRightItem = j < columns - 1 && index.applyAsInt(i, j + 1) < strings.size(); buff.append(str); if (hasRightItem) { for (int k = 0; k <= max - str.length(); k++) { buff.append(' '); } } } } buff.append('\n'); } out.print(buff.toAnsi(terminal)); } } public static void pageOutput(final Terminal terminal, @Nullable final String name, final String output) throws IOException, InterruptedException { Less less = new Less(terminal); less.run(new InputStreamSource(new ByteArrayInputStream(output.getBytes()), name)); } public static void pageOutput(final Terminal terminal, final String output) throws IOException, InterruptedException { pageOutput(terminal, null, output); } }