From a5686ab138225ee8214c68bda8c33fbaf2af5d26 Mon Sep 17 00:00:00 2001 From: mattirn Date: Tue, 10 Nov 2020 17:42:13 +0100 Subject: [PATCH] JLine option AUTO_MENU_LIST: candidate list is wrongly positioned, fixes #600 --- .../org/jline/reader/impl/LineReaderImpl.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/reader/src/main/java/org/jline/reader/impl/LineReaderImpl.java b/reader/src/main/java/org/jline/reader/impl/LineReaderImpl.java index 6c6bd4234..60442e382 100644 --- a/reader/src/main/java/org/jline/reader/impl/LineReaderImpl.java +++ b/reader/src/main/java/org/jline/reader/impl/LineReaderImpl.java @@ -5030,6 +5030,7 @@ protected boolean doList(List possible boolean caseInsensitive = isSet(Option.CASE_INSENSITIVE); StringBuilder sb = new StringBuilder(); + candidateStartPosition = 0; while (true) { String current = completed + sb.toString(); List cands; @@ -5045,7 +5046,9 @@ protected boolean doList(List possible .sorted(getCandidateComparator(caseInsensitive, current)) .collect(Collectors.toList()); } - candidateStartPosition = candidateStartPosition(); + if (isSet(Option.AUTO_MENU_LIST) && candidateStartPosition == 0) { + candidateStartPosition = candidateStartPosition(cands); + } post = () -> { AttributedString t = insertSecondaryPrompts(AttributedStringBuilder.append(prompt, buf.toString()), new ArrayList<>()); int pl = t.columnSplitLength(size.getColumns(), false, display.delayLineWrap()).size(); @@ -5181,7 +5184,13 @@ protected PostResult computePost(List possible, Candidate selection, private static final int MARGIN_BETWEEN_COLUMNS = 3; private static final int MENU_LIST_WIDTH = 25; - private int candidateStartPosition() { + private int candidateStartPosition(List cands) { + List values = cands.stream().map(c -> AttributedString.stripAnsi(c.displ())) + .filter(c -> !c.matches("\\w+")).collect(Collectors.toList()); + Set notDelimiters = new HashSet<>(); + values.forEach(v -> v.substring(0, v.length() - 1).chars() + .filter(c -> !Character.isDigit(c) && !Character.isAlphabetic(c)) + .forEach(c -> notDelimiters.add(Character.toString((char)c)))); int out = prompt != null ? prompt.length() : 0; String buffer = buf.substring(0, buf.cursor()); buffer = buffer.substring(buffer.lastIndexOf('\n') + 1); @@ -5199,7 +5208,8 @@ private int candidateStartPosition() { out = 0; } for (int i = buffer.length(); i > 0; i--) { - if (buffer.substring(0, i).matches(".*\\W")) { + if (buffer.substring(0, i).matches(".*\\W") + && !notDelimiters.contains(buffer.substring(i - 1, i))) { out += i; break; }