8229815: Upgrade Jline to 3.12.1
Reviewed-by: rfield
This commit is contained in:
parent
a66829bc89
commit
a9952bb5d9
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.keymap;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.keymap;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader;
|
||||
|
||||
|
@ -4,11 +4,12 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.time.Instant;
|
||||
import java.util.Iterator;
|
||||
import java.util.ListIterator;
|
||||
@ -41,6 +42,26 @@ public interface History extends Iterable<History.Entry>
|
||||
*/
|
||||
void save() throws IOException;
|
||||
|
||||
/**
|
||||
* Write history to the file. If incremental only the events that are new since the last incremental operation to
|
||||
* the file are added.
|
||||
* @throws IOException if a problem occurs
|
||||
*/
|
||||
void write(Path file, boolean incremental) throws IOException;
|
||||
|
||||
/**
|
||||
* Append history to the file. If incremental only the events that are new since the last incremental operation to
|
||||
* the file are added.
|
||||
* @throws IOException if a problem occurs
|
||||
*/
|
||||
void append(Path file, boolean incremental) throws IOException;
|
||||
|
||||
/**
|
||||
* Read history from the file. If incremental only the events that are not contained within the internal list are added.
|
||||
* @throws IOException if a problem occurs
|
||||
*/
|
||||
void read(Path file, boolean incremental) throws IOException;
|
||||
|
||||
/**
|
||||
* Purge history.
|
||||
* @throws IOException if a problem occurs
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader;
|
||||
|
||||
@ -95,7 +95,10 @@ public interface LineReader {
|
||||
String CALLBACK_FINISH = "callback-finish";
|
||||
String CALLBACK_KEYMAP = "callback-keymap";
|
||||
|
||||
String ACCEPT_AND_INFER_NEXT_HISTORY = "accept-and-infer-next-history";
|
||||
String ACCEPT_AND_HOLD = "accept-and-hold";
|
||||
String ACCEPT_LINE = "accept-line";
|
||||
String ACCEPT_LINE_AND_DOWN_HISTORY = "accept-line-and-down-history";
|
||||
String ARGUMENT_BASE = "argument-base";
|
||||
String BACKWARD_CHAR = "backward-char";
|
||||
String BACKWARD_DELETE_CHAR = "backward-delete-char";
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader;
|
||||
|
||||
@ -85,7 +85,7 @@ public final class LineReaderBuilder {
|
||||
public LineReaderBuilder parser(Parser parser) {
|
||||
if (parser != null) {
|
||||
try {
|
||||
if (!Boolean.parseBoolean(LineReader.PROP_SUPPORT_PARSEDLINE)
|
||||
if (!Boolean.getBoolean(LineReader.PROP_SUPPORT_PARSEDLINE)
|
||||
&& !(parser.parse("", 0) instanceof CompletingParsedLine)) {
|
||||
Log.warn("The Parser of class " + parser.getClass().getName() + " does not support the CompletingParsedLine interface. " +
|
||||
"Completion with escaped or quoted words won't work correctly.");
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader;
|
||||
|
||||
@ -16,6 +16,10 @@ public interface Parser {
|
||||
return parse(line, cursor, ParseContext.UNSPECIFIED);
|
||||
}
|
||||
|
||||
default boolean isEscapeChar(char ch) {
|
||||
return ch == '\\';
|
||||
}
|
||||
|
||||
enum ParseContext {
|
||||
UNSPECIFIED,
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader.impl;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader.impl;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader.impl;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader.impl;
|
||||
|
||||
@ -18,6 +18,13 @@ import jdk.internal.org.jline.reader.Parser;
|
||||
|
||||
public class DefaultParser implements Parser {
|
||||
|
||||
public enum Bracket {
|
||||
ROUND, // ()
|
||||
CURLY, // {}
|
||||
SQUARE, // []
|
||||
ANGLE; // <>
|
||||
}
|
||||
|
||||
private char[] quoteChars = {'\'', '"'};
|
||||
|
||||
private char[] escapeChars = {'\\'};
|
||||
@ -26,6 +33,10 @@ public class DefaultParser implements Parser {
|
||||
|
||||
private boolean eofOnEscapedNewLine;
|
||||
|
||||
private char[] openingBrackets = null;
|
||||
|
||||
private char[] closingBrackets = null;
|
||||
|
||||
//
|
||||
// Chainable setters
|
||||
//
|
||||
@ -45,6 +56,11 @@ public class DefaultParser implements Parser {
|
||||
return this;
|
||||
}
|
||||
|
||||
public DefaultParser eofOnUnclosedBracket(Bracket... brackets){
|
||||
setEofOnUnclosedBracket(brackets);
|
||||
return this;
|
||||
}
|
||||
|
||||
public DefaultParser eofOnEscapedNewLine(boolean eofOnEscapedNewLine) {
|
||||
this.eofOnEscapedNewLine = eofOnEscapedNewLine;
|
||||
return this;
|
||||
@ -86,6 +102,39 @@ public class DefaultParser implements Parser {
|
||||
return eofOnEscapedNewLine;
|
||||
}
|
||||
|
||||
public void setEofOnUnclosedBracket(Bracket... brackets){
|
||||
if (brackets == null) {
|
||||
openingBrackets = null;
|
||||
closingBrackets = null;
|
||||
} else {
|
||||
Set<Bracket> bs = new HashSet<>(Arrays.asList(brackets));
|
||||
openingBrackets = new char[bs.size()];
|
||||
closingBrackets = new char[bs.size()];
|
||||
int i = 0;
|
||||
for (Bracket b : bs) {
|
||||
switch (b) {
|
||||
case ROUND:
|
||||
openingBrackets[i] = '(';
|
||||
closingBrackets[i] = ')';
|
||||
break;
|
||||
case CURLY:
|
||||
openingBrackets[i] = '{';
|
||||
closingBrackets[i] = '}';
|
||||
break;
|
||||
case SQUARE:
|
||||
openingBrackets[i] = '[';
|
||||
closingBrackets[i] = ']';
|
||||
break;
|
||||
case ANGLE:
|
||||
openingBrackets[i] = '<';
|
||||
closingBrackets[i] = '>';
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ParsedLine parse(final String line, final int cursor, ParseContext context) {
|
||||
List<String> words = new LinkedList<>();
|
||||
StringBuilder current = new StringBuilder();
|
||||
@ -95,6 +144,8 @@ public class DefaultParser implements Parser {
|
||||
int rawWordCursor = -1;
|
||||
int rawWordLength = -1;
|
||||
int rawWordStart = 0;
|
||||
BracketChecker bracketChecker = new BracketChecker();
|
||||
boolean quotedWord = false;
|
||||
|
||||
for (int i = 0; (line != null) && (i < line.length()); i++) {
|
||||
// once we reach the cursor, set the
|
||||
@ -110,25 +161,22 @@ public class DefaultParser implements Parser {
|
||||
if (quoteStart < 0 && isQuoteChar(line, i)) {
|
||||
// Start a quote block
|
||||
quoteStart = i;
|
||||
} else if (quoteStart >= 0) {
|
||||
// In a quote block
|
||||
if (line.charAt(quoteStart) == line.charAt(i) && !isEscaped(line, i)) {
|
||||
// End the block; arg could be empty, but that's fine
|
||||
words.add(current.toString());
|
||||
current.setLength(0);
|
||||
quoteStart = -1;
|
||||
if (rawWordCursor >= 0 && rawWordLength < 0) {
|
||||
rawWordLength = i - rawWordStart + 1;
|
||||
}
|
||||
if (current.length()==0) {
|
||||
quotedWord = true;
|
||||
} else {
|
||||
if (!isEscapeChar(line, i)) {
|
||||
// Take the next character
|
||||
current.append(line.charAt(i));
|
||||
}
|
||||
} else if (quoteStart >= 0 && line.charAt(quoteStart) == line.charAt(i) && !isEscaped(line, i)) {
|
||||
// End quote block
|
||||
if (!quotedWord) {
|
||||
current.append(line.charAt(i));
|
||||
} else if (rawWordCursor >= 0 && rawWordLength < 0) {
|
||||
rawWordLength = i - rawWordStart + 1;
|
||||
}
|
||||
} else {
|
||||
// Not in a quote block
|
||||
if (isDelimiter(line, i)) {
|
||||
quoteStart = -1;
|
||||
quotedWord = false;
|
||||
} else if (quoteStart < 0 && isDelimiter(line, i)) {
|
||||
// Delimiter
|
||||
if (current.length() > 0) {
|
||||
words.add(current.toString());
|
||||
current.setLength(0); // reset the arg
|
||||
@ -140,6 +188,8 @@ public class DefaultParser implements Parser {
|
||||
} else {
|
||||
if (!isEscapeChar(line, i)) {
|
||||
current.append(line.charAt(i));
|
||||
if (quoteStart < 0) {
|
||||
bracketChecker.check(line, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -159,21 +209,29 @@ public class DefaultParser implements Parser {
|
||||
rawWordLength = rawWordCursor;
|
||||
}
|
||||
|
||||
if (context != ParseContext.COMPLETE) {
|
||||
if (eofOnEscapedNewLine && isEscapeChar(line, line.length() - 1)) {
|
||||
throw new EOFError(-1, -1, "Escaped new line", "newline");
|
||||
}
|
||||
if (eofOnUnclosedQuote && quoteStart >= 0 && context != ParseContext.COMPLETE) {
|
||||
if (eofOnUnclosedQuote && quoteStart >= 0) {
|
||||
throw new EOFError(-1, -1, "Missing closing quote", line.charAt(quoteStart) == '\''
|
||||
? "quote" : "dquote");
|
||||
}
|
||||
if (bracketChecker.isOpeningBracketMissing()) {
|
||||
throw new EOFError(-1, -1, "Missing opening bracket", "missing: " + bracketChecker.getMissingOpeningBracket());
|
||||
}
|
||||
if (bracketChecker.isClosingBracketMissing()) {
|
||||
throw new EOFError(-1, -1, "Missing closing brackets", "add: " + bracketChecker.getMissingClosingBrackets());
|
||||
}
|
||||
}
|
||||
|
||||
String openingQuote = quoteStart >= 0 ? line.substring(quoteStart, quoteStart + 1) : null;
|
||||
String openingQuote = quotedWord ? line.substring(quoteStart, quoteStart + 1) : null;
|
||||
return new ArgumentList(line, words, wordIndex, wordCursor, cursor, openingQuote, rawWordCursor, rawWordLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the specified character is a whitespace parameter. Check to ensure that the character is not
|
||||
* escaped by any of {@link #getQuoteChars}, and is not escaped by ant of the {@link #getEscapeChars}, and
|
||||
* escaped by any of {@link #getQuoteChars}, and is not escaped by any of the {@link #getEscapeChars}, and
|
||||
* returns true from {@link #isDelimiterChar}.
|
||||
*
|
||||
* @param buffer The complete command buffer
|
||||
@ -202,6 +260,18 @@ public class DefaultParser implements Parser {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEscapeChar(char ch) {
|
||||
if (escapeChars != null) {
|
||||
for (char e : escapeChars) {
|
||||
if (e == ch) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this character is a valid escape char (i.e. one that has not been escaped)
|
||||
*
|
||||
@ -216,14 +286,8 @@ public class DefaultParser implements Parser {
|
||||
if (pos < 0) {
|
||||
return false;
|
||||
}
|
||||
if (escapeChars != null) {
|
||||
for (char e : escapeChars) {
|
||||
if (e == buffer.charAt(pos)) {
|
||||
return !isEscaped(buffer, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
char ch = buffer.charAt(pos);
|
||||
return isEscapeChar(ch) && !isEscaped(buffer, pos);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -245,7 +309,7 @@ public class DefaultParser implements Parser {
|
||||
|
||||
/**
|
||||
* Returns true if the character at the specified position if a delimiter. This method will only be called if
|
||||
* the character is not enclosed in any of the {@link #getQuoteChars}, and is not escaped by ant of the
|
||||
* the character is not enclosed in any of the {@link #getQuoteChars}, and is not escaped by any of the
|
||||
* {@link #getEscapeChars}. To perform escaping manually, override {@link #isDelimiter} instead.
|
||||
*
|
||||
* @param buffer
|
||||
@ -280,6 +344,67 @@ public class DefaultParser implements Parser {
|
||||
return false;
|
||||
}
|
||||
|
||||
private class BracketChecker {
|
||||
private int missingOpeningBracket = -1;
|
||||
private List<Integer> nested = new ArrayList<>();
|
||||
|
||||
public BracketChecker(){}
|
||||
|
||||
public void check(final CharSequence buffer, final int pos){
|
||||
if (openingBrackets == null || pos < 0) {
|
||||
return;
|
||||
}
|
||||
int bid = bracketId(openingBrackets, buffer, pos);
|
||||
if (bid >= 0) {
|
||||
nested.add(bid);
|
||||
} else {
|
||||
bid = bracketId(closingBrackets, buffer, pos);
|
||||
if (bid >= 0) {
|
||||
if (!nested.isEmpty() && bid == nested.get(nested.size()-1)) {
|
||||
nested.remove(nested.size()-1);
|
||||
} else {
|
||||
missingOpeningBracket = bid;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isOpeningBracketMissing(){
|
||||
return missingOpeningBracket != -1;
|
||||
}
|
||||
|
||||
public String getMissingOpeningBracket(){
|
||||
if (!isOpeningBracketMissing()) {
|
||||
return null;
|
||||
}
|
||||
return Character.toString(openingBrackets[missingOpeningBracket]);
|
||||
}
|
||||
|
||||
public boolean isClosingBracketMissing(){
|
||||
return !nested.isEmpty();
|
||||
}
|
||||
|
||||
public String getMissingClosingBrackets(){
|
||||
if (!isClosingBracketMissing()) {
|
||||
return null;
|
||||
}
|
||||
StringBuilder out = new StringBuilder();
|
||||
for (int i = nested.size() - 1; i > -1; i--) {
|
||||
out.append(closingBrackets[nested.get(i)]);
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
private int bracketId(final char[] brackets, final CharSequence buffer, final int pos){
|
||||
for (int i=0; i < brackets.length; i++) {
|
||||
if (buffer.charAt(pos) == brackets[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The result of a delimited buffer.
|
||||
*
|
||||
@ -367,12 +492,28 @@ public class DefaultParser implements Parser {
|
||||
public CharSequence escape(CharSequence candidate, boolean complete) {
|
||||
StringBuilder sb = new StringBuilder(candidate);
|
||||
Predicate<Integer> needToBeEscaped;
|
||||
String quote = openingQuote;
|
||||
boolean middleQuotes = false;
|
||||
if (openingQuote==null) {
|
||||
for (int i=0; i < sb.length(); i++) {
|
||||
if (isQuoteChar(sb, i)) {
|
||||
middleQuotes = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (escapeChars != null) {
|
||||
// Completion is protected by an opening quote:
|
||||
// Delimiters (spaces) don't need to be escaped, nor do other quotes, but everything else does.
|
||||
// Also, close the quote at the end
|
||||
if (openingQuote != null) {
|
||||
needToBeEscaped = i -> isRawEscapeChar(sb.charAt(i)) || String.valueOf(sb.charAt(i)).equals(openingQuote);
|
||||
}
|
||||
// Completion is protected by middle quotes:
|
||||
// Delimiters (spaces) don't need to be escaped, nor do quotes, but everything else does.
|
||||
else if (middleQuotes) {
|
||||
needToBeEscaped = i -> isRawEscapeChar(sb.charAt(i));
|
||||
}
|
||||
// No quote protection, need to escape everything: delimiter chars (spaces), quote chars
|
||||
// and escapes themselves
|
||||
else {
|
||||
@ -383,10 +524,18 @@ public class DefaultParser implements Parser {
|
||||
sb.insert(i++, escapeChars[0]);
|
||||
}
|
||||
}
|
||||
if (openingQuote != null) {
|
||||
sb.insert(0, openingQuote);
|
||||
} else if (openingQuote == null && !middleQuotes) {
|
||||
for (int i = 0; i < sb.length(); i++) {
|
||||
if (isDelimiterChar(sb, i)) {
|
||||
quote = "'";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (quote != null) {
|
||||
sb.insert(0, quote);
|
||||
if (complete) {
|
||||
sb.append(openingQuote);
|
||||
sb.append(quote);
|
||||
}
|
||||
}
|
||||
return sb;
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader.impl;
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2018, the original author or authors.
|
||||
* Copyright (c) 2002-2019, the original author or authors.
|
||||
*
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader.impl;
|
||||
|
||||
@ -17,10 +17,13 @@ import java.time.Instant;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.function.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import jdk.internal.org.jline.keymap.BindingReader;
|
||||
@ -32,6 +35,7 @@ import jdk.internal.org.jline.terminal.*;
|
||||
import jdk.internal.org.jline.terminal.Attributes.ControlChar;
|
||||
import jdk.internal.org.jline.terminal.Terminal.Signal;
|
||||
import jdk.internal.org.jline.terminal.Terminal.SignalHandler;
|
||||
import jdk.internal.org.jline.terminal.impl.AbstractWindowsTerminal;
|
||||
import jdk.internal.org.jline.utils.AttributedString;
|
||||
import jdk.internal.org.jline.utils.AttributedStringBuilder;
|
||||
import jdk.internal.org.jline.utils.AttributedStyle;
|
||||
@ -159,8 +163,8 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
|
||||
protected final Size size = new Size();
|
||||
|
||||
protected AttributedString prompt;
|
||||
protected AttributedString rightPrompt;
|
||||
protected AttributedString prompt = AttributedString.EMPTY;
|
||||
protected AttributedString rightPrompt = AttributedString.EMPTY;
|
||||
|
||||
protected MaskingCallback maskingCallback;
|
||||
|
||||
@ -210,6 +214,10 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
protected UndoTree<Buffer> undo = new UndoTree<>(this::setBuffer);
|
||||
protected boolean isUndo;
|
||||
|
||||
/**
|
||||
* State lock
|
||||
*/
|
||||
protected final ReentrantLock lock = new ReentrantLock();
|
||||
/*
|
||||
* Current internal state of the line reader
|
||||
*/
|
||||
@ -239,6 +247,11 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
|
||||
protected int smallTerminalOffset = 0;
|
||||
|
||||
/*
|
||||
* accept-and-infer-next-history, accept-and-hold & accept-line-and-down-history
|
||||
*/
|
||||
protected boolean nextCommandFromHistory = false;
|
||||
protected int nextHistoryId = -1;
|
||||
|
||||
|
||||
public LineReaderImpl(Terminal terminal) throws IOException {
|
||||
@ -266,6 +279,7 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
builtinWidgets = builtinWidgets();
|
||||
widgets = new HashMap<>(builtinWidgets);
|
||||
bindingReader = new BindingReader(terminal.reader());
|
||||
doDisplay();
|
||||
}
|
||||
|
||||
public Terminal getTerminal() {
|
||||
@ -467,8 +481,7 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
SignalHandler previousWinchHandler = null;
|
||||
SignalHandler previousContHandler = null;
|
||||
Attributes originalAttributes = null;
|
||||
boolean dumb = Terminal.TYPE_DUMB.equals(terminal.getType())
|
||||
|| Terminal.TYPE_DUMB_COLOR.equals(terminal.getType());
|
||||
boolean dumb = isTerminalDumb();
|
||||
try {
|
||||
|
||||
this.maskingCallback = maskingCallback;
|
||||
@ -495,6 +508,17 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
if (buffer != null) {
|
||||
buf.write(buffer);
|
||||
}
|
||||
if (nextCommandFromHistory && nextHistoryId > 0) {
|
||||
if (history.size() > nextHistoryId) {
|
||||
history.moveTo(nextHistoryId);
|
||||
} else {
|
||||
history.moveTo(history.last());
|
||||
}
|
||||
buf.write(history.current());
|
||||
} else {
|
||||
nextHistoryId = -1;
|
||||
}
|
||||
nextCommandFromHistory = false;
|
||||
undo.clear();
|
||||
parsedLine = null;
|
||||
keyMap = MAIN;
|
||||
@ -503,7 +527,9 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
history.attach(this);
|
||||
}
|
||||
|
||||
synchronized (this) {
|
||||
try {
|
||||
lock.lock();
|
||||
|
||||
this.reading = true;
|
||||
|
||||
previousIntrHandler = terminal.handle(Signal.INT, signal -> readLineThread.interrupt());
|
||||
@ -511,18 +537,7 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
previousContHandler = terminal.handle(Signal.CONT, this::handleSignal);
|
||||
originalAttributes = terminal.enterRawMode();
|
||||
|
||||
// Cache terminal size for the duration of the call to readLine()
|
||||
// It will eventually be updated with WINCH signals
|
||||
size.copy(terminal.getSize());
|
||||
|
||||
display = new Display(terminal, false);
|
||||
if (size.getRows() == 0 || size.getColumns() == 0) {
|
||||
display.resize(1, Integer.MAX_VALUE);
|
||||
} else {
|
||||
display.resize(size.getRows(), size.getColumns());
|
||||
}
|
||||
if (isSet(Option.DELAY_LINE_WRAP))
|
||||
display.setDelayLineWrap(true);
|
||||
doDisplay();
|
||||
|
||||
// Move into application mode
|
||||
if (!dumb) {
|
||||
@ -547,6 +562,8 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
// Draw initial prompt
|
||||
redrawLine();
|
||||
redisplay();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
while (true) {
|
||||
@ -578,7 +595,8 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
regionActive = RegionType.NONE;
|
||||
}
|
||||
|
||||
synchronized (this) {
|
||||
try {
|
||||
lock.lock();
|
||||
// Get executable widget
|
||||
Buffer copy = buf.copy();
|
||||
Widget w = getWidget(o);
|
||||
@ -610,6 +628,8 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
if (!dumb) {
|
||||
redisplay();
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
} catch (IOError e) {
|
||||
@ -620,7 +640,9 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
}
|
||||
}
|
||||
finally {
|
||||
synchronized (this) {
|
||||
try {
|
||||
lock.lock();
|
||||
|
||||
this.reading = false;
|
||||
|
||||
cleanup();
|
||||
@ -636,18 +658,43 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
if (previousContHandler != null) {
|
||||
terminal.handle(Signal.CONT, previousContHandler);
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
startedReading.set(false);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isTerminalDumb(){
|
||||
return Terminal.TYPE_DUMB.equals(terminal.getType())
|
||||
|| Terminal.TYPE_DUMB_COLOR.equals(terminal.getType());
|
||||
}
|
||||
|
||||
private void doDisplay(){
|
||||
// Cache terminal size for the duration of the call to readLine()
|
||||
// It will eventually be updated with WINCH signals
|
||||
size.copy(terminal.getBufferSize());
|
||||
|
||||
display = new Display(terminal, false);
|
||||
if (size.getRows() == 0 || size.getColumns() == 0) {
|
||||
display.resize(1, Integer.MAX_VALUE);
|
||||
} else {
|
||||
display.resize(size.getRows(), size.getColumns());
|
||||
}
|
||||
if (isSet(Option.DELAY_LINE_WRAP))
|
||||
display.setDelayLineWrap(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void printAbove(String str) {
|
||||
public void printAbove(String str) {
|
||||
try {
|
||||
lock.lock();
|
||||
|
||||
boolean reading = this.reading;
|
||||
if (reading) {
|
||||
display.update(Collections.emptyList(), 0);
|
||||
}
|
||||
if (str.endsWith("\n")) {
|
||||
if (str.endsWith("\n") || str.endsWith("\n\033[m") || str.endsWith("\n\033[0m")) {
|
||||
terminal.writer().print(str);
|
||||
} else {
|
||||
terminal.writer().println(str);
|
||||
@ -656,6 +703,9 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
redisplay(false);
|
||||
}
|
||||
terminal.flush();
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -664,8 +714,13 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean isReading() {
|
||||
public boolean isReading() {
|
||||
try {
|
||||
lock.lock();
|
||||
return reading;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure we position the cursor on column 0 */
|
||||
@ -700,12 +755,14 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
sb.append(" ");
|
||||
sb.append(KeyMap.key(terminal, Capability.carriage_return));
|
||||
}
|
||||
print(sb.toAnsi(terminal));
|
||||
sb.print(terminal);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void callWidget(String name) {
|
||||
public void callWidget(String name) {
|
||||
try {
|
||||
lock.lock();
|
||||
if (!reading) {
|
||||
throw new IllegalStateException("Widgets can only be called during a `readLine` call");
|
||||
}
|
||||
@ -722,6 +779,9 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
} catch (Throwable t) {
|
||||
Log.debug("Error executing widget '", name, "'", t);
|
||||
}
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -760,13 +820,35 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
* @return the character, or -1 if an EOF is received.
|
||||
*/
|
||||
public int readCharacter() {
|
||||
if (lock.isHeldByCurrentThread()) {
|
||||
try {
|
||||
lock.unlock();
|
||||
return bindingReader.readCharacter();
|
||||
} finally {
|
||||
lock.lock();
|
||||
}
|
||||
} else {
|
||||
return bindingReader.readCharacter();
|
||||
}
|
||||
}
|
||||
|
||||
public int peekCharacter(long timeout) {
|
||||
return bindingReader.peekCharacter(timeout);
|
||||
}
|
||||
|
||||
protected <T> T doReadBinding(KeyMap<T> keys, KeyMap<T> local) {
|
||||
if (lock.isHeldByCurrentThread()) {
|
||||
try {
|
||||
lock.unlock();
|
||||
return bindingReader.readBinding(keys, local);
|
||||
} finally {
|
||||
lock.lock();
|
||||
}
|
||||
} else {
|
||||
return bindingReader.readBinding(keys, local);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read from the input stream and decode an operation from the key map.
|
||||
*
|
||||
@ -783,7 +865,7 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
}
|
||||
|
||||
public Binding readBinding(KeyMap<Binding> keys, KeyMap<Binding> local) {
|
||||
Binding o = bindingReader.readBinding(keys, local);
|
||||
Binding o = doReadBinding(keys, local);
|
||||
/*
|
||||
* The kill ring keeps record of whether or not the
|
||||
* previous command was a yank or a kill. We reset
|
||||
@ -926,7 +1008,7 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
if (ch != '\n') {
|
||||
sb.append(ch);
|
||||
}
|
||||
} else if (ch == '\\') {
|
||||
} else if (parser.isEscapeChar(ch)) {
|
||||
escaped = true;
|
||||
} else {
|
||||
sb.append(ch);
|
||||
@ -948,13 +1030,18 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
|
||||
protected void handleSignal(Signal signal) {
|
||||
if (signal == Signal.WINCH) {
|
||||
size.copy(terminal.getSize());
|
||||
Status status = Status.getStatus(terminal, false);
|
||||
if (status != null) {
|
||||
status.hardReset();
|
||||
}
|
||||
size.copy(terminal.getBufferSize());
|
||||
display.resize(size.getRows(), size.getColumns());
|
||||
redrawLine();
|
||||
redisplay();
|
||||
}
|
||||
else if (signal == Signal.CONT) {
|
||||
terminal.enterRawMode();
|
||||
size.copy(terminal.getSize());
|
||||
size.copy(terminal.getBufferSize());
|
||||
display.resize(size.getRows(), size.getColumns());
|
||||
terminal.puts(Capability.keypad_xmit);
|
||||
redrawLine();
|
||||
@ -1903,7 +1990,7 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
while (true) {
|
||||
post = () -> new AttributedString(searchPrompt + searchBuffer.toString() + "_");
|
||||
redisplay();
|
||||
Binding b = bindingReader.readBinding(keyMap);
|
||||
Binding b = doReadBinding(keyMap, null);
|
||||
if (b instanceof Reference) {
|
||||
String func = ((Reference) b).name();
|
||||
switch (func) {
|
||||
@ -2300,7 +2387,7 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
} else {
|
||||
viMoveMode = mode;
|
||||
mark = -1;
|
||||
Binding b = bindingReader.readBinding(getKeys(), keyMaps.get(VIOPP));
|
||||
Binding b = doReadBinding(getKeys(), keyMaps.get(VIOPP));
|
||||
if (b == null || new Reference(SEND_BREAK).equals(b)) {
|
||||
viMoveMode = ViMoveMode.NORMAL;
|
||||
mark = oldMark;
|
||||
@ -2710,6 +2797,42 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
return acceptLine();
|
||||
}
|
||||
|
||||
protected boolean acceptAndHold() {
|
||||
nextCommandFromHistory = false;
|
||||
acceptLine();
|
||||
if (!buf.toString().isEmpty()) {
|
||||
nextHistoryId = Integer.MAX_VALUE;
|
||||
nextCommandFromHistory = true;
|
||||
}
|
||||
return nextCommandFromHistory;
|
||||
}
|
||||
|
||||
protected boolean acceptLineAndDownHistory() {
|
||||
nextCommandFromHistory = false;
|
||||
acceptLine();
|
||||
if (nextHistoryId < 0) {
|
||||
nextHistoryId = history.index();
|
||||
}
|
||||
if (history.size() > nextHistoryId + 1) {
|
||||
nextHistoryId++;
|
||||
nextCommandFromHistory = true;
|
||||
}
|
||||
return nextCommandFromHistory;
|
||||
}
|
||||
|
||||
protected boolean acceptAndInferNextHistory() {
|
||||
nextCommandFromHistory = false;
|
||||
acceptLine();
|
||||
if (!buf.toString().isEmpty()) {
|
||||
nextHistoryId = searchBackwards(buf.toString(), history.last());
|
||||
if (nextHistoryId >= 0 && history.size() > nextHistoryId + 1) {
|
||||
nextHistoryId++;
|
||||
nextCommandFromHistory = true;
|
||||
}
|
||||
}
|
||||
return nextCommandFromHistory;
|
||||
}
|
||||
|
||||
protected boolean acceptLine() {
|
||||
parsedLine = null;
|
||||
if (!isSet(Option.DISABLE_EVENT_EXPANSION)) {
|
||||
@ -3343,158 +3466,181 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
|
||||
protected Map<String, Widget> builtinWidgets() {
|
||||
Map<String, Widget> widgets = new HashMap<>();
|
||||
widgets.put(ACCEPT_LINE, this::acceptLine);
|
||||
widgets.put(ARGUMENT_BASE, this::argumentBase);
|
||||
widgets.put(BACKWARD_CHAR, this::backwardChar);
|
||||
widgets.put(BACKWARD_DELETE_CHAR, this::backwardDeleteChar);
|
||||
widgets.put(BACKWARD_DELETE_WORD, this::backwardDeleteWord);
|
||||
widgets.put(BACKWARD_KILL_LINE, this::backwardKillLine);
|
||||
widgets.put(BACKWARD_KILL_WORD, this::backwardKillWord);
|
||||
widgets.put(BACKWARD_WORD, this::backwardWord);
|
||||
widgets.put(BEEP, this::beep);
|
||||
widgets.put(BEGINNING_OF_BUFFER_OR_HISTORY, this::beginningOfBufferOrHistory);
|
||||
widgets.put(BEGINNING_OF_HISTORY, this::beginningOfHistory);
|
||||
widgets.put(BEGINNING_OF_LINE, this::beginningOfLine);
|
||||
widgets.put(BEGINNING_OF_LINE_HIST, this::beginningOfLineHist);
|
||||
widgets.put(CAPITALIZE_WORD, this::capitalizeWord);
|
||||
widgets.put(CLEAR, this::clear);
|
||||
widgets.put(CLEAR_SCREEN, this::clearScreen);
|
||||
widgets.put(COMPLETE_PREFIX, this::completePrefix);
|
||||
widgets.put(COMPLETE_WORD, this::completeWord);
|
||||
widgets.put(COPY_PREV_WORD, this::copyPrevWord);
|
||||
widgets.put(COPY_REGION_AS_KILL, this::copyRegionAsKill);
|
||||
widgets.put(DELETE_CHAR, this::deleteChar);
|
||||
widgets.put(DELETE_CHAR_OR_LIST, this::deleteCharOrList);
|
||||
widgets.put(DELETE_WORD, this::deleteWord);
|
||||
widgets.put(DIGIT_ARGUMENT, this::digitArgument);
|
||||
widgets.put(DO_LOWERCASE_VERSION, this::doLowercaseVersion);
|
||||
widgets.put(DOWN_CASE_WORD, this::downCaseWord);
|
||||
widgets.put(DOWN_LINE, this::downLine);
|
||||
widgets.put(DOWN_LINE_OR_HISTORY, this::downLineOrHistory);
|
||||
widgets.put(DOWN_LINE_OR_SEARCH, this::downLineOrSearch);
|
||||
widgets.put(DOWN_HISTORY, this::downHistory);
|
||||
widgets.put(EMACS_EDITING_MODE, this::emacsEditingMode);
|
||||
widgets.put(EMACS_BACKWARD_WORD, this::emacsBackwardWord);
|
||||
widgets.put(EMACS_FORWARD_WORD, this::emacsForwardWord);
|
||||
widgets.put(END_OF_BUFFER_OR_HISTORY, this::endOfBufferOrHistory);
|
||||
widgets.put(END_OF_HISTORY, this::endOfHistory);
|
||||
widgets.put(END_OF_LINE, this::endOfLine);
|
||||
widgets.put(END_OF_LINE_HIST, this::endOfLineHist);
|
||||
widgets.put(EXCHANGE_POINT_AND_MARK, this::exchangePointAndMark);
|
||||
widgets.put(EXPAND_HISTORY, this::expandHistory);
|
||||
widgets.put(EXPAND_OR_COMPLETE, this::expandOrComplete);
|
||||
widgets.put(EXPAND_OR_COMPLETE_PREFIX, this::expandOrCompletePrefix);
|
||||
widgets.put(EXPAND_WORD, this::expandWord);
|
||||
widgets.put(FRESH_LINE, this::freshLine);
|
||||
widgets.put(FORWARD_CHAR, this::forwardChar);
|
||||
widgets.put(FORWARD_WORD, this::forwardWord);
|
||||
widgets.put(HISTORY_INCREMENTAL_SEARCH_BACKWARD, this::historyIncrementalSearchBackward);
|
||||
widgets.put(HISTORY_INCREMENTAL_SEARCH_FORWARD, this::historyIncrementalSearchForward);
|
||||
widgets.put(HISTORY_SEARCH_BACKWARD, this::historySearchBackward);
|
||||
widgets.put(HISTORY_SEARCH_FORWARD, this::historySearchForward);
|
||||
widgets.put(INSERT_CLOSE_CURLY, this::insertCloseCurly);
|
||||
widgets.put(INSERT_CLOSE_PAREN, this::insertCloseParen);
|
||||
widgets.put(INSERT_CLOSE_SQUARE, this::insertCloseSquare);
|
||||
widgets.put(INSERT_COMMENT, this::insertComment);
|
||||
widgets.put(KILL_BUFFER, this::killBuffer);
|
||||
widgets.put(KILL_LINE, this::killLine);
|
||||
widgets.put(KILL_REGION, this::killRegion);
|
||||
widgets.put(KILL_WHOLE_LINE, this::killWholeLine);
|
||||
widgets.put(KILL_WORD, this::killWord);
|
||||
widgets.put(LIST_CHOICES, this::listChoices);
|
||||
widgets.put(MENU_COMPLETE, this::menuComplete);
|
||||
widgets.put(MENU_EXPAND_OR_COMPLETE, this::menuExpandOrComplete);
|
||||
widgets.put(NEG_ARGUMENT, this::negArgument);
|
||||
widgets.put(OVERWRITE_MODE, this::overwriteMode);
|
||||
// widgets.put(QUIT, this::quit);
|
||||
widgets.put(QUOTED_INSERT, this::quotedInsert);
|
||||
widgets.put(REDISPLAY, this::redisplay);
|
||||
widgets.put(REDRAW_LINE, this::redrawLine);
|
||||
widgets.put(REDO, this::redo);
|
||||
widgets.put(SELF_INSERT, this::selfInsert);
|
||||
widgets.put(SELF_INSERT_UNMETA, this::selfInsertUnmeta);
|
||||
widgets.put(SEND_BREAK, this::sendBreak);
|
||||
widgets.put(SET_MARK_COMMAND, this::setMarkCommand);
|
||||
widgets.put(TRANSPOSE_CHARS, this::transposeChars);
|
||||
widgets.put(TRANSPOSE_WORDS, this::transposeWords);
|
||||
widgets.put(UNDEFINED_KEY, this::undefinedKey);
|
||||
widgets.put(UNIVERSAL_ARGUMENT, this::universalArgument);
|
||||
widgets.put(UNDO, this::undo);
|
||||
widgets.put(UP_CASE_WORD, this::upCaseWord);
|
||||
widgets.put(UP_HISTORY, this::upHistory);
|
||||
widgets.put(UP_LINE, this::upLine);
|
||||
widgets.put(UP_LINE_OR_HISTORY, this::upLineOrHistory);
|
||||
widgets.put(UP_LINE_OR_SEARCH, this::upLineOrSearch);
|
||||
widgets.put(VI_ADD_EOL, this::viAddEol);
|
||||
widgets.put(VI_ADD_NEXT, this::viAddNext);
|
||||
widgets.put(VI_BACKWARD_CHAR, this::viBackwardChar);
|
||||
widgets.put(VI_BACKWARD_DELETE_CHAR, this::viBackwardDeleteChar);
|
||||
widgets.put(VI_BACKWARD_BLANK_WORD, this::viBackwardBlankWord);
|
||||
widgets.put(VI_BACKWARD_BLANK_WORD_END, this::viBackwardBlankWordEnd);
|
||||
widgets.put(VI_BACKWARD_KILL_WORD, this::viBackwardKillWord);
|
||||
widgets.put(VI_BACKWARD_WORD, this::viBackwardWord);
|
||||
widgets.put(VI_BACKWARD_WORD_END, this::viBackwardWordEnd);
|
||||
widgets.put(VI_BEGINNING_OF_LINE, this::viBeginningOfLine);
|
||||
widgets.put(VI_CMD_MODE, this::viCmdMode);
|
||||
widgets.put(VI_DIGIT_OR_BEGINNING_OF_LINE, this::viDigitOrBeginningOfLine);
|
||||
widgets.put(VI_DOWN_LINE_OR_HISTORY, this::viDownLineOrHistory);
|
||||
widgets.put(VI_CHANGE, this::viChange);
|
||||
widgets.put(VI_CHANGE_EOL, this::viChangeEol);
|
||||
widgets.put(VI_CHANGE_WHOLE_LINE, this::viChangeWholeLine);
|
||||
widgets.put(VI_DELETE_CHAR, this::viDeleteChar);
|
||||
widgets.put(VI_DELETE, this::viDelete);
|
||||
widgets.put(VI_END_OF_LINE, this::viEndOfLine);
|
||||
widgets.put(VI_KILL_EOL, this::viKillEol);
|
||||
widgets.put(VI_FIRST_NON_BLANK, this::viFirstNonBlank);
|
||||
widgets.put(VI_FIND_NEXT_CHAR, this::viFindNextChar);
|
||||
widgets.put(VI_FIND_NEXT_CHAR_SKIP, this::viFindNextCharSkip);
|
||||
widgets.put(VI_FIND_PREV_CHAR, this::viFindPrevChar);
|
||||
widgets.put(VI_FIND_PREV_CHAR_SKIP, this::viFindPrevCharSkip);
|
||||
widgets.put(VI_FORWARD_BLANK_WORD, this::viForwardBlankWord);
|
||||
widgets.put(VI_FORWARD_BLANK_WORD_END, this::viForwardBlankWordEnd);
|
||||
widgets.put(VI_FORWARD_CHAR, this::viForwardChar);
|
||||
widgets.put(VI_FORWARD_WORD, this::viForwardWord);
|
||||
widgets.put(VI_FORWARD_WORD, this::viForwardWord);
|
||||
widgets.put(VI_FORWARD_WORD_END, this::viForwardWordEnd);
|
||||
widgets.put(VI_HISTORY_SEARCH_BACKWARD, this::viHistorySearchBackward);
|
||||
widgets.put(VI_HISTORY_SEARCH_FORWARD, this::viHistorySearchForward);
|
||||
widgets.put(VI_INSERT, this::viInsert);
|
||||
widgets.put(VI_INSERT_BOL, this::viInsertBol);
|
||||
widgets.put(VI_INSERT_COMMENT, this::viInsertComment);
|
||||
widgets.put(VI_JOIN, this::viJoin);
|
||||
widgets.put(VI_KILL_LINE, this::viKillWholeLine);
|
||||
widgets.put(VI_MATCH_BRACKET, this::viMatchBracket);
|
||||
widgets.put(VI_OPEN_LINE_ABOVE, this::viOpenLineAbove);
|
||||
widgets.put(VI_OPEN_LINE_BELOW, this::viOpenLineBelow);
|
||||
widgets.put(VI_PUT_AFTER, this::viPutAfter);
|
||||
widgets.put(VI_PUT_BEFORE, this::viPutBefore);
|
||||
widgets.put(VI_REPEAT_FIND, this::viRepeatFind);
|
||||
widgets.put(VI_REPEAT_SEARCH, this::viRepeatSearch);
|
||||
widgets.put(VI_REPLACE_CHARS, this::viReplaceChars);
|
||||
widgets.put(VI_REV_REPEAT_FIND, this::viRevRepeatFind);
|
||||
widgets.put(VI_REV_REPEAT_SEARCH, this::viRevRepeatSearch);
|
||||
widgets.put(VI_SWAP_CASE, this::viSwapCase);
|
||||
widgets.put(VI_UP_LINE_OR_HISTORY, this::viUpLineOrHistory);
|
||||
widgets.put(VI_YANK, this::viYankTo);
|
||||
widgets.put(VI_YANK_WHOLE_LINE, this::viYankWholeLine);
|
||||
widgets.put(VISUAL_LINE_MODE, this::visualLineMode);
|
||||
widgets.put(VISUAL_MODE, this::visualMode);
|
||||
widgets.put(WHAT_CURSOR_POSITION, this::whatCursorPosition);
|
||||
widgets.put(YANK, this::yank);
|
||||
widgets.put(YANK_POP, this::yankPop);
|
||||
widgets.put(MOUSE, this::mouse);
|
||||
widgets.put(BEGIN_PASTE, this::beginPaste);
|
||||
widgets.put(FOCUS_IN, this::focusIn);
|
||||
widgets.put(FOCUS_OUT, this::focusOut);
|
||||
addBuiltinWidget(widgets, ACCEPT_AND_INFER_NEXT_HISTORY, this::acceptAndInferNextHistory);
|
||||
addBuiltinWidget(widgets, ACCEPT_AND_HOLD, this::acceptAndHold);
|
||||
addBuiltinWidget(widgets, ACCEPT_LINE, this::acceptLine);
|
||||
addBuiltinWidget(widgets, ACCEPT_LINE_AND_DOWN_HISTORY, this::acceptLineAndDownHistory);
|
||||
addBuiltinWidget(widgets, ARGUMENT_BASE, this::argumentBase);
|
||||
addBuiltinWidget(widgets, BACKWARD_CHAR, this::backwardChar);
|
||||
addBuiltinWidget(widgets, BACKWARD_DELETE_CHAR, this::backwardDeleteChar);
|
||||
addBuiltinWidget(widgets, BACKWARD_DELETE_WORD, this::backwardDeleteWord);
|
||||
addBuiltinWidget(widgets, BACKWARD_KILL_LINE, this::backwardKillLine);
|
||||
addBuiltinWidget(widgets, BACKWARD_KILL_WORD, this::backwardKillWord);
|
||||
addBuiltinWidget(widgets, BACKWARD_WORD, this::backwardWord);
|
||||
addBuiltinWidget(widgets, BEEP, this::beep);
|
||||
addBuiltinWidget(widgets, BEGINNING_OF_BUFFER_OR_HISTORY, this::beginningOfBufferOrHistory);
|
||||
addBuiltinWidget(widgets, BEGINNING_OF_HISTORY, this::beginningOfHistory);
|
||||
addBuiltinWidget(widgets, BEGINNING_OF_LINE, this::beginningOfLine);
|
||||
addBuiltinWidget(widgets, BEGINNING_OF_LINE_HIST, this::beginningOfLineHist);
|
||||
addBuiltinWidget(widgets, CAPITALIZE_WORD, this::capitalizeWord);
|
||||
addBuiltinWidget(widgets, CLEAR, this::clear);
|
||||
addBuiltinWidget(widgets, CLEAR_SCREEN, this::clearScreen);
|
||||
addBuiltinWidget(widgets, COMPLETE_PREFIX, this::completePrefix);
|
||||
addBuiltinWidget(widgets, COMPLETE_WORD, this::completeWord);
|
||||
addBuiltinWidget(widgets, COPY_PREV_WORD, this::copyPrevWord);
|
||||
addBuiltinWidget(widgets, COPY_REGION_AS_KILL, this::copyRegionAsKill);
|
||||
addBuiltinWidget(widgets, DELETE_CHAR, this::deleteChar);
|
||||
addBuiltinWidget(widgets, DELETE_CHAR_OR_LIST, this::deleteCharOrList);
|
||||
addBuiltinWidget(widgets, DELETE_WORD, this::deleteWord);
|
||||
addBuiltinWidget(widgets, DIGIT_ARGUMENT, this::digitArgument);
|
||||
addBuiltinWidget(widgets, DO_LOWERCASE_VERSION, this::doLowercaseVersion);
|
||||
addBuiltinWidget(widgets, DOWN_CASE_WORD, this::downCaseWord);
|
||||
addBuiltinWidget(widgets, DOWN_LINE, this::downLine);
|
||||
addBuiltinWidget(widgets, DOWN_LINE_OR_HISTORY, this::downLineOrHistory);
|
||||
addBuiltinWidget(widgets, DOWN_LINE_OR_SEARCH, this::downLineOrSearch);
|
||||
addBuiltinWidget(widgets, DOWN_HISTORY, this::downHistory);
|
||||
addBuiltinWidget(widgets, EMACS_EDITING_MODE, this::emacsEditingMode);
|
||||
addBuiltinWidget(widgets, EMACS_BACKWARD_WORD, this::emacsBackwardWord);
|
||||
addBuiltinWidget(widgets, EMACS_FORWARD_WORD, this::emacsForwardWord);
|
||||
addBuiltinWidget(widgets, END_OF_BUFFER_OR_HISTORY, this::endOfBufferOrHistory);
|
||||
addBuiltinWidget(widgets, END_OF_HISTORY, this::endOfHistory);
|
||||
addBuiltinWidget(widgets, END_OF_LINE, this::endOfLine);
|
||||
addBuiltinWidget(widgets, END_OF_LINE_HIST, this::endOfLineHist);
|
||||
addBuiltinWidget(widgets, EXCHANGE_POINT_AND_MARK, this::exchangePointAndMark);
|
||||
addBuiltinWidget(widgets, EXPAND_HISTORY, this::expandHistory);
|
||||
addBuiltinWidget(widgets, EXPAND_OR_COMPLETE, this::expandOrComplete);
|
||||
addBuiltinWidget(widgets, EXPAND_OR_COMPLETE_PREFIX, this::expandOrCompletePrefix);
|
||||
addBuiltinWidget(widgets, EXPAND_WORD, this::expandWord);
|
||||
addBuiltinWidget(widgets, FRESH_LINE, this::freshLine);
|
||||
addBuiltinWidget(widgets, FORWARD_CHAR, this::forwardChar);
|
||||
addBuiltinWidget(widgets, FORWARD_WORD, this::forwardWord);
|
||||
addBuiltinWidget(widgets, HISTORY_INCREMENTAL_SEARCH_BACKWARD, this::historyIncrementalSearchBackward);
|
||||
addBuiltinWidget(widgets, HISTORY_INCREMENTAL_SEARCH_FORWARD, this::historyIncrementalSearchForward);
|
||||
addBuiltinWidget(widgets, HISTORY_SEARCH_BACKWARD, this::historySearchBackward);
|
||||
addBuiltinWidget(widgets, HISTORY_SEARCH_FORWARD, this::historySearchForward);
|
||||
addBuiltinWidget(widgets, INSERT_CLOSE_CURLY, this::insertCloseCurly);
|
||||
addBuiltinWidget(widgets, INSERT_CLOSE_PAREN, this::insertCloseParen);
|
||||
addBuiltinWidget(widgets, INSERT_CLOSE_SQUARE, this::insertCloseSquare);
|
||||
addBuiltinWidget(widgets, INSERT_COMMENT, this::insertComment);
|
||||
addBuiltinWidget(widgets, KILL_BUFFER, this::killBuffer);
|
||||
addBuiltinWidget(widgets, KILL_LINE, this::killLine);
|
||||
addBuiltinWidget(widgets, KILL_REGION, this::killRegion);
|
||||
addBuiltinWidget(widgets, KILL_WHOLE_LINE, this::killWholeLine);
|
||||
addBuiltinWidget(widgets, KILL_WORD, this::killWord);
|
||||
addBuiltinWidget(widgets, LIST_CHOICES, this::listChoices);
|
||||
addBuiltinWidget(widgets, MENU_COMPLETE, this::menuComplete);
|
||||
addBuiltinWidget(widgets, MENU_EXPAND_OR_COMPLETE, this::menuExpandOrComplete);
|
||||
addBuiltinWidget(widgets, NEG_ARGUMENT, this::negArgument);
|
||||
addBuiltinWidget(widgets, OVERWRITE_MODE, this::overwriteMode);
|
||||
// addBuiltinWidget(widgets, QUIT, this::quit);
|
||||
addBuiltinWidget(widgets, QUOTED_INSERT, this::quotedInsert);
|
||||
addBuiltinWidget(widgets, REDISPLAY, this::redisplay);
|
||||
addBuiltinWidget(widgets, REDRAW_LINE, this::redrawLine);
|
||||
addBuiltinWidget(widgets, REDO, this::redo);
|
||||
addBuiltinWidget(widgets, SELF_INSERT, this::selfInsert);
|
||||
addBuiltinWidget(widgets, SELF_INSERT_UNMETA, this::selfInsertUnmeta);
|
||||
addBuiltinWidget(widgets, SEND_BREAK, this::sendBreak);
|
||||
addBuiltinWidget(widgets, SET_MARK_COMMAND, this::setMarkCommand);
|
||||
addBuiltinWidget(widgets, TRANSPOSE_CHARS, this::transposeChars);
|
||||
addBuiltinWidget(widgets, TRANSPOSE_WORDS, this::transposeWords);
|
||||
addBuiltinWidget(widgets, UNDEFINED_KEY, this::undefinedKey);
|
||||
addBuiltinWidget(widgets, UNIVERSAL_ARGUMENT, this::universalArgument);
|
||||
addBuiltinWidget(widgets, UNDO, this::undo);
|
||||
addBuiltinWidget(widgets, UP_CASE_WORD, this::upCaseWord);
|
||||
addBuiltinWidget(widgets, UP_HISTORY, this::upHistory);
|
||||
addBuiltinWidget(widgets, UP_LINE, this::upLine);
|
||||
addBuiltinWidget(widgets, UP_LINE_OR_HISTORY, this::upLineOrHistory);
|
||||
addBuiltinWidget(widgets, UP_LINE_OR_SEARCH, this::upLineOrSearch);
|
||||
addBuiltinWidget(widgets, VI_ADD_EOL, this::viAddEol);
|
||||
addBuiltinWidget(widgets, VI_ADD_NEXT, this::viAddNext);
|
||||
addBuiltinWidget(widgets, VI_BACKWARD_CHAR, this::viBackwardChar);
|
||||
addBuiltinWidget(widgets, VI_BACKWARD_DELETE_CHAR, this::viBackwardDeleteChar);
|
||||
addBuiltinWidget(widgets, VI_BACKWARD_BLANK_WORD, this::viBackwardBlankWord);
|
||||
addBuiltinWidget(widgets, VI_BACKWARD_BLANK_WORD_END, this::viBackwardBlankWordEnd);
|
||||
addBuiltinWidget(widgets, VI_BACKWARD_KILL_WORD, this::viBackwardKillWord);
|
||||
addBuiltinWidget(widgets, VI_BACKWARD_WORD, this::viBackwardWord);
|
||||
addBuiltinWidget(widgets, VI_BACKWARD_WORD_END, this::viBackwardWordEnd);
|
||||
addBuiltinWidget(widgets, VI_BEGINNING_OF_LINE, this::viBeginningOfLine);
|
||||
addBuiltinWidget(widgets, VI_CMD_MODE, this::viCmdMode);
|
||||
addBuiltinWidget(widgets, VI_DIGIT_OR_BEGINNING_OF_LINE, this::viDigitOrBeginningOfLine);
|
||||
addBuiltinWidget(widgets, VI_DOWN_LINE_OR_HISTORY, this::viDownLineOrHistory);
|
||||
addBuiltinWidget(widgets, VI_CHANGE, this::viChange);
|
||||
addBuiltinWidget(widgets, VI_CHANGE_EOL, this::viChangeEol);
|
||||
addBuiltinWidget(widgets, VI_CHANGE_WHOLE_LINE, this::viChangeWholeLine);
|
||||
addBuiltinWidget(widgets, VI_DELETE_CHAR, this::viDeleteChar);
|
||||
addBuiltinWidget(widgets, VI_DELETE, this::viDelete);
|
||||
addBuiltinWidget(widgets, VI_END_OF_LINE, this::viEndOfLine);
|
||||
addBuiltinWidget(widgets, VI_KILL_EOL, this::viKillEol);
|
||||
addBuiltinWidget(widgets, VI_FIRST_NON_BLANK, this::viFirstNonBlank);
|
||||
addBuiltinWidget(widgets, VI_FIND_NEXT_CHAR, this::viFindNextChar);
|
||||
addBuiltinWidget(widgets, VI_FIND_NEXT_CHAR_SKIP, this::viFindNextCharSkip);
|
||||
addBuiltinWidget(widgets, VI_FIND_PREV_CHAR, this::viFindPrevChar);
|
||||
addBuiltinWidget(widgets, VI_FIND_PREV_CHAR_SKIP, this::viFindPrevCharSkip);
|
||||
addBuiltinWidget(widgets, VI_FORWARD_BLANK_WORD, this::viForwardBlankWord);
|
||||
addBuiltinWidget(widgets, VI_FORWARD_BLANK_WORD_END, this::viForwardBlankWordEnd);
|
||||
addBuiltinWidget(widgets, VI_FORWARD_CHAR, this::viForwardChar);
|
||||
addBuiltinWidget(widgets, VI_FORWARD_WORD, this::viForwardWord);
|
||||
addBuiltinWidget(widgets, VI_FORWARD_WORD, this::viForwardWord);
|
||||
addBuiltinWidget(widgets, VI_FORWARD_WORD_END, this::viForwardWordEnd);
|
||||
addBuiltinWidget(widgets, VI_HISTORY_SEARCH_BACKWARD, this::viHistorySearchBackward);
|
||||
addBuiltinWidget(widgets, VI_HISTORY_SEARCH_FORWARD, this::viHistorySearchForward);
|
||||
addBuiltinWidget(widgets, VI_INSERT, this::viInsert);
|
||||
addBuiltinWidget(widgets, VI_INSERT_BOL, this::viInsertBol);
|
||||
addBuiltinWidget(widgets, VI_INSERT_COMMENT, this::viInsertComment);
|
||||
addBuiltinWidget(widgets, VI_JOIN, this::viJoin);
|
||||
addBuiltinWidget(widgets, VI_KILL_LINE, this::viKillWholeLine);
|
||||
addBuiltinWidget(widgets, VI_MATCH_BRACKET, this::viMatchBracket);
|
||||
addBuiltinWidget(widgets, VI_OPEN_LINE_ABOVE, this::viOpenLineAbove);
|
||||
addBuiltinWidget(widgets, VI_OPEN_LINE_BELOW, this::viOpenLineBelow);
|
||||
addBuiltinWidget(widgets, VI_PUT_AFTER, this::viPutAfter);
|
||||
addBuiltinWidget(widgets, VI_PUT_BEFORE, this::viPutBefore);
|
||||
addBuiltinWidget(widgets, VI_REPEAT_FIND, this::viRepeatFind);
|
||||
addBuiltinWidget(widgets, VI_REPEAT_SEARCH, this::viRepeatSearch);
|
||||
addBuiltinWidget(widgets, VI_REPLACE_CHARS, this::viReplaceChars);
|
||||
addBuiltinWidget(widgets, VI_REV_REPEAT_FIND, this::viRevRepeatFind);
|
||||
addBuiltinWidget(widgets, VI_REV_REPEAT_SEARCH, this::viRevRepeatSearch);
|
||||
addBuiltinWidget(widgets, VI_SWAP_CASE, this::viSwapCase);
|
||||
addBuiltinWidget(widgets, VI_UP_LINE_OR_HISTORY, this::viUpLineOrHistory);
|
||||
addBuiltinWidget(widgets, VI_YANK, this::viYankTo);
|
||||
addBuiltinWidget(widgets, VI_YANK_WHOLE_LINE, this::viYankWholeLine);
|
||||
addBuiltinWidget(widgets, VISUAL_LINE_MODE, this::visualLineMode);
|
||||
addBuiltinWidget(widgets, VISUAL_MODE, this::visualMode);
|
||||
addBuiltinWidget(widgets, WHAT_CURSOR_POSITION, this::whatCursorPosition);
|
||||
addBuiltinWidget(widgets, YANK, this::yank);
|
||||
addBuiltinWidget(widgets, YANK_POP, this::yankPop);
|
||||
addBuiltinWidget(widgets, MOUSE, this::mouse);
|
||||
addBuiltinWidget(widgets, BEGIN_PASTE, this::beginPaste);
|
||||
addBuiltinWidget(widgets, FOCUS_IN, this::focusIn);
|
||||
addBuiltinWidget(widgets, FOCUS_OUT, this::focusOut);
|
||||
return widgets;
|
||||
}
|
||||
|
||||
private void addBuiltinWidget(Map<String, Widget> widgets, String name, Widget widget) {
|
||||
widgets.put(name, namedWidget(name, widget));
|
||||
}
|
||||
|
||||
private Widget namedWidget(String name, Widget widget) {
|
||||
return new Widget() {
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
@Override
|
||||
public boolean apply() {
|
||||
return widget.apply();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public boolean redisplay() {
|
||||
redisplay(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected synchronized void redisplay(boolean flush) {
|
||||
protected void redisplay(boolean flush) {
|
||||
try {
|
||||
lock.lock();
|
||||
|
||||
if (skipRedisplay) {
|
||||
skipRedisplay = false;
|
||||
return;
|
||||
@ -3515,7 +3661,7 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
sb.setLength(0);
|
||||
sb.append(prompt);
|
||||
String line = buf.upToCursor();
|
||||
if(maskingCallback != null) {
|
||||
if (maskingCallback != null) {
|
||||
line = maskingCallback.display(line);
|
||||
}
|
||||
|
||||
@ -3525,7 +3671,7 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
int w = WCWidth.wcwidth('\u2026');
|
||||
int width = size.getColumns();
|
||||
int cursor = toCursor.columnLength();
|
||||
int inc = width /2 + 1;
|
||||
int inc = width / 2 + 1;
|
||||
while (cursor <= smallTerminalOffset + w) {
|
||||
smallTerminalOffset -= inc;
|
||||
}
|
||||
@ -3576,6 +3722,8 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
}
|
||||
|
||||
int cursorPos = -1;
|
||||
int cursorNewLinesId = -1;
|
||||
int cursorColPos = -1;
|
||||
if (size.getColumns() > 0) {
|
||||
AttributedStringBuilder sb = new AttributedStringBuilder().tabs(TAB_WIDTH);
|
||||
sb.append(prompt);
|
||||
@ -3586,12 +3734,49 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
sb.append(insertSecondaryPrompts(new AttributedString(buffer), secondaryPrompts, false));
|
||||
List<AttributedString> promptLines = sb.columnSplitLength(size.getColumns(), false, display.delayLineWrap());
|
||||
if (!promptLines.isEmpty()) {
|
||||
cursorPos = size.cursorPos(promptLines.size() - 1,
|
||||
promptLines.get(promptLines.size() - 1).columnLength());
|
||||
cursorNewLinesId = promptLines.size() - 1;
|
||||
cursorColPos = promptLines.get(promptLines.size() - 1).columnLength();
|
||||
cursorPos = size.cursorPos(cursorNewLinesId, cursorColPos);
|
||||
}
|
||||
}
|
||||
|
||||
display.update(newLines, cursorPos, flush);
|
||||
List<AttributedString> newLinesToDisplay = new ArrayList<>();
|
||||
int displaySize = size.getRows() - (status != null ? status.size() : 0);
|
||||
if (newLines.size() > displaySize && !isTerminalDumb()) {
|
||||
StringBuilder sb = new StringBuilder(">....");
|
||||
// blanks are needed when displaying command completion candidate list
|
||||
for (int i = sb.toString().length(); i < size.getColumns(); i++) {
|
||||
sb.append(" ");
|
||||
}
|
||||
AttributedString partialCommandInfo = new AttributedString(sb.toString());
|
||||
int lineId = newLines.size() - displaySize + 1;
|
||||
int endId = displaySize;
|
||||
int startId = 1;
|
||||
if (lineId > cursorNewLinesId) {
|
||||
lineId = cursorNewLinesId;
|
||||
endId = displaySize - 1;
|
||||
startId = 0;
|
||||
} else {
|
||||
newLinesToDisplay.add(partialCommandInfo);
|
||||
}
|
||||
int cursorRowPos = 0;
|
||||
for (int i = startId; i < endId; i++) {
|
||||
if (cursorNewLinesId == lineId) {
|
||||
cursorRowPos = i;
|
||||
}
|
||||
newLinesToDisplay.add(newLines.get(lineId++));
|
||||
}
|
||||
if (startId == 0) {
|
||||
newLinesToDisplay.add(partialCommandInfo);
|
||||
}
|
||||
cursorPos = size.cursorPos(cursorRowPos, cursorColPos);
|
||||
} else {
|
||||
newLinesToDisplay = newLines;
|
||||
}
|
||||
display.update(newLinesToDisplay, cursorPos, flush);
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private void concat(List<AttributedString> lines, AttributedStringBuilder sb) {
|
||||
@ -4048,7 +4233,8 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
if (matching.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size.copy(terminal.getSize());
|
||||
try {
|
||||
// If we only need to display the list, do it now
|
||||
if (lst == CompletionType.List) {
|
||||
List<Candidate> possible = matching.entrySet().stream()
|
||||
@ -4155,6 +4341,9 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
doMenu(possible, line.word(), line::escape);
|
||||
}
|
||||
return true;
|
||||
} finally {
|
||||
size.copy(terminal.getBufferSize());
|
||||
}
|
||||
}
|
||||
|
||||
private CompletingParsedLine wrap(ParsedLine line) {
|
||||
@ -4534,7 +4723,7 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
if (listMax > 0 && possible.size() >= listMax
|
||||
|| lines >= size.getRows() - promptLines) {
|
||||
// prompt
|
||||
post = () -> new AttributedString(getAppName() + ": do you wish to see to see all " + possible.size()
|
||||
post = () -> new AttributedString(getAppName() + ": do you wish to see all " + possible.size()
|
||||
+ " possibilities (" + lines + " lines)?");
|
||||
redisplay(true);
|
||||
int c = readCharacter();
|
||||
@ -4586,7 +4775,7 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
}
|
||||
redisplay();
|
||||
// TODO: use a different keyMap ?
|
||||
Binding b = bindingReader.readBinding(getKeys());
|
||||
Binding b = doReadBinding(getKeys(), null);
|
||||
if (b instanceof Reference) {
|
||||
String name = ((Reference) b).name();
|
||||
if (BACKWARD_DELETE_CHAR.equals(name) || VI_BACKWARD_DELETE_CHAR.equals(name)) {
|
||||
@ -4731,7 +4920,7 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void toColumns(Object items, int width, int maxWidth, AttributedStringBuilder sb, Candidate selection, String completed, boolean rowsFirst, int[] out) {
|
||||
if (maxWidth <= 0) {
|
||||
if (maxWidth <= 0 || width <= 0) {
|
||||
return;
|
||||
}
|
||||
// This is a group
|
||||
@ -4985,9 +5174,11 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
while (end < buf.length() && buf.atChar(end) != '\n') {
|
||||
end++;
|
||||
}
|
||||
if (end < buf.length()) {
|
||||
end++;
|
||||
}
|
||||
}
|
||||
}
|
||||
String killed = buf.substring(start, end);
|
||||
buf.cursor(start);
|
||||
buf.delete(end - start);
|
||||
@ -5188,7 +5379,7 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
keyMap.bind(END_PASTE, BRACKETED_PASTE_END);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while (true) {
|
||||
Object b = bindingReader.readBinding(keyMap);
|
||||
Object b = doReadBinding(keyMap, null);
|
||||
if (b == END_PASTE) {
|
||||
break;
|
||||
}
|
||||
@ -5227,6 +5418,11 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
*/
|
||||
public boolean clearScreen() {
|
||||
if (terminal.puts(Capability.clear_screen)) {
|
||||
// ConEMU extended fonts support
|
||||
if (AbstractWindowsTerminal.TYPE_WINDOWS_CONEMU.equals(terminal.getType())
|
||||
&& !Boolean.getBoolean("org.jline.terminal.conemu.disable-activate")) {
|
||||
terminal.writer().write("\u001b[9999E");
|
||||
}
|
||||
Status status = Status.getStatus(terminal, false);
|
||||
if (status != null) {
|
||||
status.reset();
|
||||
@ -5358,6 +5554,7 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
|
||||
public KeyMap<Binding> emacs() {
|
||||
KeyMap<Binding> emacs = new KeyMap<>();
|
||||
bindKeys(emacs);
|
||||
bind(emacs, SET_MARK_COMMAND, ctrl('@'));
|
||||
bind(emacs, BEGINNING_OF_LINE, ctrl('A'));
|
||||
bind(emacs, BACKWARD_CHAR, ctrl('B'));
|
||||
@ -5372,6 +5569,7 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
bind(emacs, CLEAR_SCREEN, ctrl('L'));
|
||||
bind(emacs, ACCEPT_LINE, ctrl('M'));
|
||||
bind(emacs, DOWN_LINE_OR_HISTORY, ctrl('N'));
|
||||
bind(emacs, ACCEPT_LINE_AND_DOWN_HISTORY, ctrl('O'));
|
||||
bind(emacs, UP_LINE_OR_HISTORY, ctrl('P'));
|
||||
bind(emacs, HISTORY_INCREMENTAL_SEARCH_BACKWARD, ctrl('R'));
|
||||
bind(emacs, HISTORY_INCREMENTAL_SEARCH_FORWARD, ctrl('S'));
|
||||
@ -5415,6 +5613,7 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
bind(emacs, END_OF_HISTORY, alt('>'));
|
||||
bind(emacs, LIST_CHOICES, alt('?'));
|
||||
bind(emacs, DO_LOWERCASE_VERSION, range("^[A-^[Z"));
|
||||
bind(emacs, ACCEPT_AND_HOLD, alt('a'));
|
||||
bind(emacs, BACKWARD_WORD, alt('b'));
|
||||
bind(emacs, CAPITALIZE_WORD, alt('c'));
|
||||
bind(emacs, KILL_WORD, alt('d'));
|
||||
@ -5439,6 +5638,7 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
|
||||
public KeyMap<Binding> viInsertion() {
|
||||
KeyMap<Binding> viins = new KeyMap<>();
|
||||
bindKeys(viins);
|
||||
bind(viins, SELF_INSERT, range("^@-^_"));
|
||||
bind(viins, LIST_CHOICES, ctrl('D'));
|
||||
bind(viins, SEND_BREAK, ctrl('G'));
|
||||
@ -5638,6 +5838,14 @@ public class LineReaderImpl implements LineReader, Flushable
|
||||
return KeyMap.key(terminal, capability);
|
||||
}
|
||||
|
||||
private void bindKeys(KeyMap<Binding> emacs) {
|
||||
Widget beep = namedWidget("beep", this::beep);
|
||||
Stream.of(Capability.values())
|
||||
.filter(c -> c.name().startsWith("key_"))
|
||||
.map(this::key)
|
||||
.forEach(k -> bind(emacs, beep, k));
|
||||
}
|
||||
|
||||
private void bindArrowKeys(KeyMap<Binding> map) {
|
||||
bind(map, UP_LINE_OR_SEARCH, key(Capability.key_up));
|
||||
bind(map, DOWN_LINE_OR_SEARCH, key(Capability.key_down));
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader.impl;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader.impl;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader.impl;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader.impl.completer;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader.impl.completer;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader.impl.completer;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader.impl.completer;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader.impl.completer;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader.impl.completer;
|
||||
|
||||
@ -43,6 +43,11 @@ public class StringsCompleter implements Completer
|
||||
}
|
||||
}
|
||||
|
||||
public StringsCompleter(Candidate ... candidates) {
|
||||
assert candidates != null;
|
||||
this.candidates.addAll(Arrays.asList(candidates));
|
||||
}
|
||||
|
||||
public void complete(LineReader reader, final ParsedLine commandLine, final List<Candidate> candidates) {
|
||||
assert commandLine != null;
|
||||
assert candidates != null;
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
/**
|
||||
* JLine 3.
|
||||
|
@ -4,12 +4,13 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.reader.impl.history;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.*;
|
||||
import java.time.DateTimeException;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
|
||||
@ -36,8 +37,7 @@ public class DefaultHistory implements History {
|
||||
|
||||
private LineReader reader;
|
||||
|
||||
private int lastLoaded = 0;
|
||||
private int nbEntriesInFile = 0;
|
||||
private Map<String, HistoryFileData> historyFiles = new HashMap<>();
|
||||
private int offset = 0;
|
||||
private int index = 0;
|
||||
|
||||
@ -68,7 +68,7 @@ public class DefaultHistory implements History {
|
||||
try {
|
||||
load();
|
||||
}
|
||||
catch (IOException e) {
|
||||
catch (IllegalArgumentException | IOException e) {
|
||||
Log.warn("Failed to load history", e);
|
||||
}
|
||||
}
|
||||
@ -84,12 +84,11 @@ public class DefaultHistory implements History {
|
||||
try (BufferedReader reader = Files.newBufferedReader(path)) {
|
||||
internalClear();
|
||||
reader.lines().forEach(line -> addHistoryLine(path, line));
|
||||
lastLoaded = items.size();
|
||||
nbEntriesInFile = lastLoaded;
|
||||
setHistoryFileData(path, new HistoryFileData(items.size(), items.size()));
|
||||
maybeResize();
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
} catch (IllegalArgumentException | IOException e) {
|
||||
Log.debug("Failed to load history; clearing", e);
|
||||
internalClear();
|
||||
throw e;
|
||||
@ -97,20 +96,100 @@ public class DefaultHistory implements History {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(Path file, boolean incremental) throws IOException {
|
||||
Path path = file != null ? file : getPath();
|
||||
if (path != null) {
|
||||
try {
|
||||
if (Files.exists(path)) {
|
||||
Log.trace("Reading history from: ", path);
|
||||
try (BufferedReader reader = Files.newBufferedReader(path)) {
|
||||
reader.lines().forEach(line -> addHistoryLine(path, line, incremental));
|
||||
setHistoryFileData(path, new HistoryFileData(items.size(), items.size()));
|
||||
maybeResize();
|
||||
}
|
||||
}
|
||||
} catch (IllegalArgumentException | IOException e) {
|
||||
Log.debug("Failed to read history; clearing", e);
|
||||
internalClear();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String doHistoryFileDataKey (Path path){
|
||||
return path != null ? path.toAbsolutePath().toString() : null;
|
||||
}
|
||||
|
||||
private HistoryFileData getHistoryFileData(Path path) {
|
||||
String key = doHistoryFileDataKey(path);
|
||||
if (!historyFiles.containsKey(key)){
|
||||
historyFiles.put(key, new HistoryFileData());
|
||||
}
|
||||
return historyFiles.get(key);
|
||||
}
|
||||
|
||||
private void setHistoryFileData(Path path, HistoryFileData historyFileData) {
|
||||
historyFiles.put(doHistoryFileDataKey(path), historyFileData);
|
||||
}
|
||||
|
||||
private boolean isLineReaderHistory (Path path) throws IOException {
|
||||
Path lrp = getPath();
|
||||
if (lrp == null) {
|
||||
if (path != null) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return Files.isSameFile(lrp, path);
|
||||
}
|
||||
|
||||
private void setLastLoaded(Path path, int lastloaded){
|
||||
getHistoryFileData(path).setLastLoaded(lastloaded);
|
||||
}
|
||||
|
||||
private void setEntriesInFile(Path path, int entriesInFile){
|
||||
getHistoryFileData(path).setEntriesInFile(entriesInFile);
|
||||
}
|
||||
|
||||
private void incEntriesInFile(Path path, int amount){
|
||||
getHistoryFileData(path).incEntriesInFile(amount);
|
||||
}
|
||||
|
||||
private int getLastLoaded(Path path){
|
||||
return getHistoryFileData(path).getLastLoaded();
|
||||
}
|
||||
|
||||
private int getEntriesInFile(Path path){
|
||||
return getHistoryFileData(path).getEntriesInFile();
|
||||
}
|
||||
|
||||
protected void addHistoryLine(Path path, String line) {
|
||||
addHistoryLine(path, line, false);
|
||||
}
|
||||
|
||||
protected void addHistoryLine(Path path, String line, boolean checkDuplicates) {
|
||||
if (reader.isSet(LineReader.Option.HISTORY_TIMESTAMPED)) {
|
||||
int idx = line.indexOf(':');
|
||||
if (idx < 0) {
|
||||
throw new IllegalArgumentException("Bad history file syntax! " +
|
||||
final String badHistoryFileSyntax = "Bad history file syntax! " +
|
||||
"The history file `" + path + "` may be an older history: " +
|
||||
"please remove it or use a different history file.");
|
||||
"please remove it or use a different history file.";
|
||||
if (idx < 0) {
|
||||
throw new IllegalArgumentException(badHistoryFileSyntax);
|
||||
}
|
||||
Instant time = Instant.ofEpochMilli(Long.parseLong(line.substring(0, idx)));
|
||||
Instant time;
|
||||
try {
|
||||
time = Instant.ofEpochMilli(Long.parseLong(line.substring(0, idx)));
|
||||
} catch (DateTimeException | NumberFormatException e) {
|
||||
throw new IllegalArgumentException(badHistoryFileSyntax);
|
||||
}
|
||||
|
||||
String unescaped = unescape(line.substring(idx + 1));
|
||||
internalAdd(time, unescaped);
|
||||
internalAdd(time, unescaped, checkDuplicates);
|
||||
}
|
||||
else {
|
||||
internalAdd(Instant.now(), unescape(line));
|
||||
internalAdd(Instant.now(), unescape(line), checkDuplicates);
|
||||
}
|
||||
}
|
||||
|
||||
@ -124,29 +203,46 @@ public class DefaultHistory implements History {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(Path file, boolean incremental) throws IOException {
|
||||
Path path = file != null ? file : getPath();
|
||||
if (path != null && Files.exists(path)) {
|
||||
path.toFile().delete();
|
||||
}
|
||||
internalWrite(path, incremental ? getLastLoaded(path) : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void append(Path file, boolean incremental) throws IOException {
|
||||
internalWrite(file != null ? file : getPath(),
|
||||
incremental ? getLastLoaded(file) : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save() throws IOException {
|
||||
Path path = getPath();
|
||||
internalWrite(getPath(), getLastLoaded(getPath()));
|
||||
}
|
||||
|
||||
private void internalWrite(Path path, int from) throws IOException {
|
||||
if (path != null) {
|
||||
Log.trace("Saving history to: ", path);
|
||||
Files.createDirectories(path.toAbsolutePath().getParent());
|
||||
// Append new items to the history file
|
||||
try (BufferedWriter writer = Files.newBufferedWriter(path.toAbsolutePath(),
|
||||
StandardOpenOption.WRITE, StandardOpenOption.APPEND, StandardOpenOption.CREATE)) {
|
||||
for (Entry entry : items.subList(lastLoaded, items.size())) {
|
||||
for (Entry entry : items.subList(from, items.size())) {
|
||||
if (isPersistable(entry)) {
|
||||
writer.append(format(entry));
|
||||
}
|
||||
}
|
||||
}
|
||||
nbEntriesInFile += items.size() - lastLoaded;
|
||||
// If we are over 25% max size, trim history file
|
||||
incEntriesInFile(path, items.size() - from);
|
||||
int max = getInt(reader, LineReader.HISTORY_FILE_SIZE, DEFAULT_HISTORY_FILE_SIZE);
|
||||
if (nbEntriesInFile > max + max / 4) {
|
||||
if (getEntriesInFile(path) > max + max / 4) {
|
||||
trimHistory(path, max);
|
||||
}
|
||||
}
|
||||
lastLoaded = items.size();
|
||||
setLastLoaded(path, items.size());
|
||||
}
|
||||
|
||||
protected void trimHistory(Path path, int max) throws IOException {
|
||||
@ -172,11 +268,14 @@ public class DefaultHistory implements History {
|
||||
}
|
||||
Files.move(temp, path, StandardCopyOption.REPLACE_EXISTING);
|
||||
// Keep items in memory
|
||||
if (isLineReaderHistory(path)) {
|
||||
internalClear();
|
||||
offset = allItems.get(0).index();
|
||||
items.addAll(allItems);
|
||||
lastLoaded = items.size();
|
||||
nbEntriesInFile = items.size();
|
||||
setHistoryFileData(path, new HistoryFileData(items.size(), items.size()));
|
||||
} else {
|
||||
setEntriesInFile(path, allItems.size());
|
||||
}
|
||||
maybeResize();
|
||||
}
|
||||
|
||||
@ -194,8 +293,7 @@ public class DefaultHistory implements History {
|
||||
private void internalClear() {
|
||||
offset = 0;
|
||||
index = 0;
|
||||
lastLoaded = 0;
|
||||
nbEntriesInFile = 0;
|
||||
historyFiles = new HashMap<>();
|
||||
items.clear();
|
||||
}
|
||||
|
||||
@ -302,7 +400,18 @@ public class DefaultHistory implements History {
|
||||
}
|
||||
|
||||
protected void internalAdd(Instant time, String line) {
|
||||
internalAdd(time, line, false);
|
||||
}
|
||||
|
||||
protected void internalAdd(Instant time, String line, boolean checkDuplicates) {
|
||||
Entry entry = new EntryImpl(offset + items.size(), time, line);
|
||||
if (checkDuplicates) {
|
||||
for (Entry e: items) {
|
||||
if (e.line().trim().equals(line.trim())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
items.add(entry);
|
||||
maybeResize();
|
||||
}
|
||||
@ -310,7 +419,9 @@ public class DefaultHistory implements History {
|
||||
private void maybeResize() {
|
||||
while (size() > getInt(reader, LineReader.HISTORY_SIZE, DEFAULT_HISTORY_SIZE)) {
|
||||
items.removeFirst();
|
||||
lastLoaded--;
|
||||
for (HistoryFileData hfd: historyFiles.values()) {
|
||||
hfd.decLastLoaded();
|
||||
}
|
||||
offset++;
|
||||
}
|
||||
index = size();
|
||||
@ -503,5 +614,46 @@ public class DefaultHistory implements History {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private class HistoryFileData {
|
||||
private int lastLoaded = 0;
|
||||
private int entriesInFile = 0;
|
||||
|
||||
public HistoryFileData() {
|
||||
}
|
||||
|
||||
public HistoryFileData(int lastLoaded, int entriesInFile) {
|
||||
this.lastLoaded = lastLoaded;
|
||||
this.entriesInFile = entriesInFile;
|
||||
}
|
||||
|
||||
public int getLastLoaded() {
|
||||
return lastLoaded;
|
||||
}
|
||||
|
||||
public void setLastLoaded(int lastLoaded) {
|
||||
this.lastLoaded = lastLoaded;
|
||||
}
|
||||
|
||||
public void decLastLoaded() {
|
||||
lastLoaded = lastLoaded - 1;
|
||||
if (lastLoaded < 0) {
|
||||
lastLoaded = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public int getEntriesInFile() {
|
||||
return entriesInFile;
|
||||
}
|
||||
|
||||
public void setEntriesInFile(int entriesInFile) {
|
||||
this.entriesInFile = entriesInFile;
|
||||
}
|
||||
|
||||
public void incEntriesInFile(int amount) {
|
||||
entriesInFile = entriesInFile + amount;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
/**
|
||||
* JLine 3.
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
/**
|
||||
* JLine 3.
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.terminal;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.terminal;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.terminal;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.terminal;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.terminal;
|
||||
|
||||
@ -111,7 +111,7 @@ public interface Terminal extends Closeable, Flushable {
|
||||
*
|
||||
* @return The output stream
|
||||
*
|
||||
* @see #writer();
|
||||
* @see #writer()
|
||||
*/
|
||||
OutputStream output();
|
||||
|
||||
@ -183,6 +183,11 @@ public interface Terminal extends Closeable, Flushable {
|
||||
|
||||
void setAttributes(Attributes attr);
|
||||
|
||||
/**
|
||||
* Retrieve the size of the visible window
|
||||
* @return the visible terminal size
|
||||
* @see #getBufferSize()
|
||||
*/
|
||||
Size getSize();
|
||||
|
||||
void setSize(Size size);
|
||||
@ -195,6 +200,22 @@ public interface Terminal extends Closeable, Flushable {
|
||||
return getSize().getRows();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the size of the window buffer.
|
||||
* Some terminals can be configured to have a buffer size
|
||||
* larger than the visible window size and provide scroll bars.
|
||||
* In such cases, this method should attempt to return the size
|
||||
* of the whole buffer. The <code>getBufferSize()</code> method
|
||||
* can be used to avoid wrapping when using the terminal in a line
|
||||
* editing mode, while the {@link #getSize()} method should be
|
||||
* used when using full screen mode.
|
||||
* @return the terminal buffer size
|
||||
* @see #getSize()
|
||||
*/
|
||||
default Size getBufferSize() {
|
||||
return getSize();
|
||||
}
|
||||
|
||||
void flush();
|
||||
|
||||
//
|
||||
|
@ -1,10 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2018, the original author or authors.
|
||||
* Copyright (c) 2002-2019, the original author or authors.
|
||||
*
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.terminal;
|
||||
|
||||
@ -33,9 +33,6 @@ import jdk.internal.org.jline.terminal.spi.Pty;
|
||||
import jdk.internal.org.jline.utils.Log;
|
||||
import jdk.internal.org.jline.utils.OSUtils;
|
||||
|
||||
import static jdk.internal.org.jline.terminal.impl.AbstractWindowsTerminal.TYPE_WINDOWS;
|
||||
import static jdk.internal.org.jline.terminal.impl.AbstractWindowsTerminal.TYPE_WINDOWS_256_COLOR;
|
||||
|
||||
/**
|
||||
* Builder class to create terminals.
|
||||
*/
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.terminal.impl;
|
||||
|
||||
|
@ -1,3 +1,11 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2019, the original author or authors.
|
||||
*
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.terminal.impl;
|
||||
|
||||
import jdk.internal.org.jline.terminal.Attributes;
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.terminal.impl;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.terminal.impl;
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2018, the original author or authors.
|
||||
* Copyright (c) 2002-2019, the original author or authors.
|
||||
*
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.terminal.impl;
|
||||
|
||||
@ -21,12 +21,10 @@ import jdk.internal.org.jline.utils.ShutdownHooks;
|
||||
import jdk.internal.org.jline.utils.Signals;
|
||||
import jdk.internal.org.jline.utils.WriterOutputStream;
|
||||
|
||||
import java.io.IOError;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@ -50,6 +48,7 @@ public abstract class AbstractWindowsTerminal extends AbstractTerminal {
|
||||
|
||||
public static final String TYPE_WINDOWS = "windows";
|
||||
public static final String TYPE_WINDOWS_256_COLOR = "windows-256color";
|
||||
public static final String TYPE_WINDOWS_CONEMU = "windows-conemu";
|
||||
public static final String TYPE_WINDOWS_VTP = "windows-vtp";
|
||||
|
||||
public static final int ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004;
|
||||
@ -110,7 +109,7 @@ public abstract class AbstractWindowsTerminal extends AbstractTerminal {
|
||||
closer = this::close;
|
||||
ShutdownHooks.add(closer);
|
||||
// ConEMU extended fonts support
|
||||
if (TYPE_WINDOWS_256_COLOR.equals(getType())
|
||||
if (TYPE_WINDOWS_CONEMU.equals(getType())
|
||||
&& !Boolean.getBoolean("org.jline.terminal.conemu.disable-activate")) {
|
||||
writer.write("\u001b[9999E");
|
||||
writer.flush();
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.terminal.impl;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.terminal.impl;
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2019, the original author or authors.
|
||||
* Copyright (c) 2002-2016, the original author or authors.
|
||||
*
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.terminal.impl;
|
||||
|
||||
@ -137,15 +137,12 @@ public class ExecPty extends AbstractPty implements Pty {
|
||||
}
|
||||
String undef = System.getProperty("os.name").toLowerCase().startsWith("hp") ? "^-" : "undef";
|
||||
for (ControlChar cchar : ControlChar.values()) {
|
||||
if (attr.getControlChar(cchar) != current.getControlChar(cchar)) {
|
||||
String str = "";
|
||||
int v = attr.getControlChar(cchar);
|
||||
if (v == -1) { // Skip if ControlChar is <UNDEF>
|
||||
continue;
|
||||
}
|
||||
if (v >= 0 && v != current.getControlChar(cchar)) {
|
||||
String str = "";
|
||||
commands.add(cchar.name().toLowerCase().substring(1));
|
||||
if (cchar == ControlChar.VMIN || cchar == ControlChar.VTIME) {
|
||||
commands.add(Integer.toBinaryString(v));
|
||||
commands.add(Integer.toString(v));
|
||||
}
|
||||
else if (v == 0) {
|
||||
commands.add(undef);
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.terminal.impl;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.terminal.impl;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.terminal.impl;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.terminal.impl;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.terminal.impl;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.terminal.impl;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
/**
|
||||
* JLine 3.
|
||||
|
@ -1,3 +1,11 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2019, the original author or authors.
|
||||
*
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.terminal.spi;
|
||||
|
||||
import jdk.internal.org.jline.terminal.Attributes;
|
||||
|
@ -1,3 +1,11 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2019, the original author or authors.
|
||||
*
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.terminal.spi;
|
||||
|
||||
import jdk.internal.org.jline.terminal.Attributes;
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.terminal.spi;
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2016, the original author or authors.
|
||||
* Copyright (c) 2002-2019, the original author or authors.
|
||||
*
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.utils;
|
||||
|
||||
@ -38,6 +38,14 @@ public abstract class AttributedCharSequence implements CharSequence {
|
||||
// cache the value here as we can't afford to get it each time
|
||||
static final boolean DISABLE_ALTERNATE_CHARSET = Boolean.getBoolean(PROP_DISABLE_ALTERNATE_CHARSET);
|
||||
|
||||
public void print(Terminal terminal) {
|
||||
terminal.writer().print(toAnsi(terminal));
|
||||
}
|
||||
|
||||
public void println(Terminal terminal) {
|
||||
terminal.writer().println(toAnsi(terminal));
|
||||
}
|
||||
|
||||
public String toAnsi() {
|
||||
return toAnsi(null);
|
||||
}
|
||||
@ -54,7 +62,8 @@ public abstract class AttributedCharSequence implements CharSequence {
|
||||
if (max_colors != null) {
|
||||
colors = max_colors;
|
||||
}
|
||||
force256colors = AbstractWindowsTerminal.TYPE_WINDOWS_256_COLOR.equals(terminal.getType());
|
||||
force256colors = AbstractWindowsTerminal.TYPE_WINDOWS_256_COLOR.equals(terminal.getType())
|
||||
|| AbstractWindowsTerminal.TYPE_WINDOWS_CONEMU.equals(terminal.getType());
|
||||
if (!DISABLE_ALTERNATE_CHARSET) {
|
||||
alternateIn = Curses.tputs(terminal.getStringCapability(Capability.enter_alt_charset_mode));
|
||||
alternateOut = Curses.tputs(terminal.getStringCapability(Capability.exit_alt_charset_mode));
|
||||
@ -293,7 +302,7 @@ public abstract class AttributedCharSequence implements CharSequence {
|
||||
if (col + w > start) {
|
||||
break;
|
||||
}
|
||||
begin++;
|
||||
begin += Character.charCount(cp);
|
||||
col += w;
|
||||
}
|
||||
int end = begin;
|
||||
@ -305,7 +314,7 @@ public abstract class AttributedCharSequence implements CharSequence {
|
||||
if (col + w > stop) {
|
||||
break;
|
||||
}
|
||||
end++;
|
||||
end += Character.charCount(cp);
|
||||
col += w;
|
||||
}
|
||||
return subSequence(begin, end);
|
||||
|
@ -4,12 +4,13 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.utils;
|
||||
|
||||
import java.security.InvalidParameterException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@ -98,6 +99,10 @@ public class AttributedString extends AttributedCharSequence {
|
||||
}
|
||||
|
||||
public static AttributedString fromAnsi(String ansi, int tabs) {
|
||||
return fromAnsi(ansi, Arrays.asList(tabs));
|
||||
}
|
||||
|
||||
public static AttributedString fromAnsi(String ansi, List<Integer> tabs) {
|
||||
if (ansi == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -4,11 +4,13 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Matcher;
|
||||
@ -24,7 +26,7 @@ public class AttributedStringBuilder extends AttributedCharSequence implements A
|
||||
private char[] buffer;
|
||||
private int[] style;
|
||||
private int length;
|
||||
private int tabs = 0;
|
||||
private TabStops tabs = new TabStops(0);
|
||||
private int lastLineLength = 0;
|
||||
private AttributedStyle current = AttributedStyle.DEFAULT;
|
||||
|
||||
@ -151,7 +153,7 @@ public class AttributedStringBuilder extends AttributedCharSequence implements A
|
||||
for (int i = start; i < end; i++) {
|
||||
char c = str.charAt(i);
|
||||
int s = str.styleCodeAt(i) & ~current.getMask() | current.getStyle();
|
||||
if (tabs > 0 && c == '\t') {
|
||||
if (tabs.defined() && c == '\t') {
|
||||
insertTab(new AttributedStyle(s, 0));
|
||||
} else {
|
||||
ensureCapacity(length + 1);
|
||||
@ -332,7 +334,7 @@ public class AttributedStringBuilder extends AttributedCharSequence implements A
|
||||
// This is not a SGR code, so ignore
|
||||
ansiState = 0;
|
||||
}
|
||||
} else if (c == '\t' && tabs > 0) {
|
||||
} else if (c == '\t' && tabs.defined()) {
|
||||
insertTab(current);
|
||||
} else {
|
||||
ensureCapacity(length + 1);
|
||||
@ -350,7 +352,7 @@ public class AttributedStringBuilder extends AttributedCharSequence implements A
|
||||
}
|
||||
|
||||
protected void insertTab(AttributedStyle s) {
|
||||
int nb = tabs - lastLineLength % tabs;
|
||||
int nb = tabs.spaces(lastLineLength);
|
||||
ensureCapacity(length + nb);
|
||||
for (int i = 0; i < nb; i++) {
|
||||
buffer[length] = ' ';
|
||||
@ -373,13 +375,17 @@ public class AttributedStringBuilder extends AttributedCharSequence implements A
|
||||
* @return this
|
||||
*/
|
||||
public AttributedStringBuilder tabs(int tabsize) {
|
||||
if (length > 0) {
|
||||
throw new IllegalStateException("Cannot change tab size after appending text");
|
||||
}
|
||||
if (tabsize < 0) {
|
||||
throw new IllegalArgumentException("Tab size must be non negative");
|
||||
}
|
||||
this.tabs = tabsize;
|
||||
return tabs(Arrays.asList(tabsize));
|
||||
}
|
||||
|
||||
public AttributedStringBuilder tabs(List<Integer> tabs) {
|
||||
if (length > 0) {
|
||||
throw new IllegalStateException("Cannot change tab size after appending text");
|
||||
}
|
||||
this.tabs = new TabStops(tabs);
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -393,4 +399,60 @@ public class AttributedStringBuilder extends AttributedCharSequence implements A
|
||||
return this;
|
||||
}
|
||||
|
||||
public AttributedStringBuilder styleMatches(Pattern pattern, List<AttributedStyle> styles) {
|
||||
Matcher matcher = pattern.matcher(this);
|
||||
while (matcher.find()) {
|
||||
for (int group = 0; group < matcher.groupCount(); group++) {
|
||||
AttributedStyle s = styles.get(group);
|
||||
for (int i = matcher.start(group + 1); i < matcher.end(group + 1); i++) {
|
||||
style[i] = (style[i] & ~s.getMask()) | s.getStyle();
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
private class TabStops {
|
||||
private List<Integer> tabs = new ArrayList<>();
|
||||
private int lastStop = 0;
|
||||
private int lastSize = 0;
|
||||
|
||||
public TabStops(int tabs) {
|
||||
this.lastSize = tabs;
|
||||
}
|
||||
|
||||
public TabStops(List<Integer> tabs) {
|
||||
this.tabs = tabs;
|
||||
int p = 0;
|
||||
for (int s: tabs) {
|
||||
if (s <= p) {
|
||||
continue;
|
||||
}
|
||||
lastStop = s;
|
||||
lastSize = s - p;
|
||||
p = s;
|
||||
}
|
||||
}
|
||||
|
||||
boolean defined() {
|
||||
return lastSize > 0;
|
||||
}
|
||||
|
||||
int spaces(int lastLineLength) {
|
||||
int out = 0;
|
||||
if (lastLineLength >= lastStop) {
|
||||
out = lastSize - (lastLineLength - lastStop) % lastSize;
|
||||
} else {
|
||||
for (int s: tabs) {
|
||||
if (s > lastLineLength) {
|
||||
out = s - lastLineLength;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.utils;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.utils;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.utils;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.utils;
|
||||
|
||||
@ -74,8 +74,16 @@ public final class Curses {
|
||||
switch (ch) {
|
||||
case '\\':
|
||||
ch = str.charAt(index++);
|
||||
if (ch >= '0' && ch <= '9') {
|
||||
throw new UnsupportedOperationException(); // todo
|
||||
if (ch >= '0' && ch <= '7') {
|
||||
int val = ch - '0';
|
||||
for (int i = 0; i < 2; i++) {
|
||||
ch = str.charAt(index++);
|
||||
if (ch < '0' || ch > '7') {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
val = val * 8 + (ch - '0');
|
||||
}
|
||||
out.append((char) val);
|
||||
} else {
|
||||
switch (ch) {
|
||||
case 'e':
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.utils;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.utils;
|
||||
|
||||
@ -492,7 +492,7 @@ public class Display {
|
||||
}
|
||||
|
||||
void rawPrint(AttributedString str) {
|
||||
terminal.writer().write(str.toAnsi(terminal));
|
||||
str.print(terminal);
|
||||
}
|
||||
|
||||
public int wcwidth(String str) {
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.utils;
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2016, the original author or authors.
|
||||
* Copyright (c) 2002-2019, the original author or authors.
|
||||
*
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.utils;
|
||||
|
||||
@ -578,6 +578,8 @@ public final class InfoCmp {
|
||||
int iVal;
|
||||
if (val.startsWith("0x")) {
|
||||
iVal = Integer.parseInt(val.substring(2), 16);
|
||||
} else if (val.startsWith("0")) {
|
||||
iVal = Integer.parseInt(val.substring(1), 8);
|
||||
} else {
|
||||
iVal = Integer.parseInt(val);
|
||||
}
|
||||
@ -614,7 +616,7 @@ public final class InfoCmp {
|
||||
|
||||
static {
|
||||
for (String s : Arrays.asList("dumb", "ansi", "xterm", "xterm-256color",
|
||||
"windows", "windows-256color", "windows-vtp",
|
||||
"windows", "windows-256color", "windows-conemu", "windows-vtp",
|
||||
"screen", "screen-256color")) {
|
||||
setDefaultInfoCmp(s, () -> loadDefaultInfoCmp(s));
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.utils;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.utils;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.utils;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.utils;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.utils;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.utils;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.utils;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.utils;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.utils;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.utils;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.utils;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.utils;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.utils;
|
||||
|
||||
|
@ -4,10 +4,11 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.utils;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Objects;
|
||||
|
||||
@ -85,13 +86,16 @@ public final class Signals {
|
||||
|
||||
private static Object doRegister(String name, Object handler) throws Exception {
|
||||
Log.trace(() -> "Registering signal " + name + " with handler " + toString(handler));
|
||||
if ("QUIT".equals(name) || "INFO".equals(name) && "9".equals(System.getProperty("java.specification.version"))) {
|
||||
Class<?> signalClass = Class.forName("sun.misc.Signal");
|
||||
Constructor<?> constructor = signalClass.getConstructor(String.class);
|
||||
Object signal;
|
||||
try {
|
||||
signal = constructor.newInstance(name);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.trace(() -> "Ignoring unsupported signal " + name);
|
||||
return null;
|
||||
}
|
||||
Class<?> signalClass = Class.forName("sun.misc.Signal");
|
||||
Class<?> signalHandlerClass = Class.forName("sun.misc.SignalHandler");
|
||||
Object signal = signalClass.getConstructor(String.class).newInstance(name);
|
||||
return signalClass.getMethod("handle", signalClass, signalHandlerClass)
|
||||
.invoke(null, signal, handler);
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.utils;
|
||||
|
||||
@ -24,9 +24,11 @@ public class Status {
|
||||
protected final AbstractTerminal terminal;
|
||||
protected final boolean supported;
|
||||
protected List<AttributedString> oldLines = Collections.emptyList();
|
||||
protected List<AttributedString> linesToRestore = Collections.emptyList();
|
||||
protected int rows;
|
||||
protected int columns;
|
||||
protected boolean force;
|
||||
protected boolean suspended = false;
|
||||
|
||||
public static Status getStatus(Terminal terminal) {
|
||||
return getStatus(terminal, true);
|
||||
@ -61,15 +63,34 @@ public class Status {
|
||||
this.force = true;
|
||||
}
|
||||
|
||||
public void hardReset() {
|
||||
if (suspended) {
|
||||
return;
|
||||
}
|
||||
List<AttributedString> lines = new ArrayList<>(oldLines);
|
||||
update(null);
|
||||
update(lines);
|
||||
}
|
||||
|
||||
public void redraw() {
|
||||
if (suspended) {
|
||||
return;
|
||||
}
|
||||
update(oldLines);
|
||||
}
|
||||
|
||||
public void update(List<AttributedString> lines) {
|
||||
if (!supported) {
|
||||
return;
|
||||
}
|
||||
if (lines == null) {
|
||||
lines = Collections.emptyList();
|
||||
}
|
||||
if (!supported || (oldLines.equals(lines) && !force)) {
|
||||
if (suspended) {
|
||||
linesToRestore = new ArrayList<>(lines);
|
||||
return;
|
||||
}
|
||||
if (oldLines.equals(lines) && !force) {
|
||||
return;
|
||||
}
|
||||
int nb = lines.size() - oldLines.size();
|
||||
@ -82,10 +103,11 @@ public class Status {
|
||||
}
|
||||
}
|
||||
terminal.puts(Capability.save_cursor);
|
||||
terminal.puts(Capability.cursor_address, rows - lines.size(), 0);
|
||||
terminal.puts(Capability.clr_eos);
|
||||
for (int i = 0; i < lines.size(); i++) {
|
||||
terminal.puts(Capability.cursor_address, rows - lines.size() + i, 0);
|
||||
terminal.writer().write(lines.get(i).columnSubSequence(0, columns).toAnsi(terminal));
|
||||
lines.get(i).columnSubSequence(0, columns).print(terminal);
|
||||
}
|
||||
terminal.puts(Capability.change_scroll_region, 0, rows - 1 - lines.size());
|
||||
terminal.puts(Capability.restore_cursor);
|
||||
@ -93,4 +115,27 @@ public class Status {
|
||||
oldLines = new ArrayList<>(lines);
|
||||
force = false;
|
||||
}
|
||||
|
||||
public void suspend() {
|
||||
if (suspended) {
|
||||
return;
|
||||
}
|
||||
linesToRestore = new ArrayList<>(oldLines);
|
||||
update(null);
|
||||
suspended = true;
|
||||
}
|
||||
|
||||
public void restore() {
|
||||
if (!suspended) {
|
||||
return;
|
||||
}
|
||||
suspended = false;
|
||||
update(linesToRestore);
|
||||
linesToRestore = Collections.emptyList();
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return oldLines.size();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.utils;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.utils;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.utils;
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
# This software is distributable under the BSD license. See the terms of the
|
||||
# BSD license in the documentation provided with this software.
|
||||
#
|
||||
# http://www.opensource.org/licenses/bsd-license.php
|
||||
# https://opensource.org/licenses/BSD-3-Clause
|
||||
#
|
||||
|
||||
auto_left_margin, bw, bw
|
||||
|
@ -4,7 +4,7 @@
|
||||
# This software is distributable under the BSD license. See the terms of the
|
||||
# BSD license in the documentation provided with this software.
|
||||
#
|
||||
# http://www.opensource.org/licenses/bsd-license.php
|
||||
# https://opensource.org/licenses/BSD-3-Clause
|
||||
#
|
||||
|
||||
black
|
||||
|
@ -0,0 +1,4 @@
|
||||
dumb-color|80-column dumb tty with 256 coors,
|
||||
am,
|
||||
colors#256, cols#80,
|
||||
bel=^G, cr=^M, cud1=^J, ind=^J,
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
/**
|
||||
* JLine 3.
|
||||
|
@ -0,0 +1,27 @@
|
||||
windows-conemu|conemu windows terminal,
|
||||
am, mc5i, mir, msgr,
|
||||
colors#256, cols#80, it#8, lines#24, ncv#3, pairs#64,
|
||||
bel=^G, blink=\E[5m, bold=\E[1m, cbt=\E[Z, clear=\E[H\E[J,
|
||||
cr=^M, cub=\E[%p1%dD, cub1=\E[D, cud=\E[%p1%dB, cud1=\E[B,
|
||||
cuf=\E[%p1%dC, cuf1=\E[C, cup=\E[%i%p1%d;%p2%dH,
|
||||
cuu=\E[%p1%dA, cuu1=\E[A,
|
||||
il=\E[%p1%dL, il1=\E[L,
|
||||
dl=\E[%p1%dM, dl1=\E[M,
|
||||
ech=\E[%p1%dX,
|
||||
el=\E[K, ed=\E[2K,
|
||||
el1=\E[1K, home=\E[H, hpa=\E[%i%p1%dG,
|
||||
ind=^J,
|
||||
invis=\E[8m, kbs=^H, kcbt=\E[Z,
|
||||
kcub1=\EOD, kcud1=\EOB, kcuf1=\EOC, kcuu1=\EOA,
|
||||
khome=\E[H,
|
||||
op=\E[39;49m,
|
||||
rev=\E[7m,
|
||||
rmacs=\E[10m, rmpch=\E[10m, rmso=\E[m, rmul=\E[m,
|
||||
setab=\E[4%p1%dm, setaf=\E[3%p1%dm,
|
||||
sgr=\E[0;10%?%p1%t;7%;%?%p2%t;4%;%?%p3%t;7%;%?%p4%t;5%;%?%p6%t;1%;%?%p7%t;8%;%?%p9%t;11%;m,
|
||||
sgr0=\E[0;10m,
|
||||
smso=\E[7m,
|
||||
smul=\E[4m,
|
||||
kdch1=\E[3~, kich1=\E[2~, kend=\E[4~, knp=\E[6~, kpp=\E[5~,
|
||||
kf1=\EOP, kf2=\EOQ, kf3=\EOR, kf4=\EOS, kf5=\E[15~, kf6=\E[17~,
|
||||
kf7=\E[18~, kf8=\E[19~, kf9=\E[20~, kf10=\E[21~, kf11=\E[23~, kf12=\E[24~,
|
@ -1,4 +1,4 @@
|
||||
## JLine v3.9.0
|
||||
## JLine v3.12.1
|
||||
|
||||
### JLine License
|
||||
<pre>
|
||||
|
@ -1,3 +1,11 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2018, the original author or authors.
|
||||
*
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.terminal.impl.jna;
|
||||
|
||||
import jdk.internal.org.jline.terminal.Attributes;
|
||||
|
@ -4,7 +4,7 @@
|
||||
* This software is distributable under the BSD license. See the terms of the
|
||||
* BSD license in the documentation provided with this software.
|
||||
*
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
* https://opensource.org/licenses/BSD-3-Clause
|
||||
*/
|
||||
package jdk.internal.org.jline.terminal.impl.jna.win;
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user