From edf43a473b18f5c185475aa39d227eeb94e3ea8e Mon Sep 17 00:00:00 2001 From: Ethan Atkins Date: Mon, 3 Aug 2020 16:50:31 -0700 Subject: [PATCH] Set complete flag in completions JLine 3 automatically appends a space character to the completion candidate unless you tell it not to by setting its 'complete' parameter. This behavior is generally nice because it will automatically complete something like 'foo/testO' to 'foo/testOnly ' which allows the user to start typing the testname without having to enter space. It does, however, break scripted completions because it will complete 'scripted wat' to 'scripted watch/ ' This commit updates the custom completer to append a " " to the initial completions and check if there are any additional completions available. If so, we set the complete flag to true and jline will append a space to the input when the user presses or . Otherwise the old jline2 behavior where no spaces are ever appended is preserved. --- .../main/scala/sbt/internal/util/LineReader.scala | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/internal/util-complete/src/main/scala/sbt/internal/util/LineReader.scala b/internal/util-complete/src/main/scala/sbt/internal/util/LineReader.scala index 34526a948..52a36ca8d 100644 --- a/internal/util-complete/src/main/scala/sbt/internal/util/LineReader.scala +++ b/internal/util-complete/src/main/scala/sbt/internal/util/LineReader.scala @@ -57,11 +57,14 @@ object LineReader { * `testOnly testOnly\ com.foo.FooSpec` instead of `testOnly com.foo.FooSpec`. */ if (c.append.nonEmpty) { - if (!pl.line().endsWith(" ")) { - candidates.add(new Candidate(pl.line().split(" ").last + c.append)) - } else { - candidates.add(new Candidate(c.append)) - } + val comp = + if (!pl.line().endsWith(" ")) pl.line().split(" ").last + c.append else c.append + // tell jline to append a " " if the completion would be valid with a " " appended + // which can be the case for input tasks and some commands. We need to exclude + // the empty string and ";" which always seem to be present. + val complete = (Parser.completions(parser, comp + " ", 10).get.map(_.display) -- + Set(";", "")).nonEmpty + candidates.add(new Candidate(comp, comp, null, null, null, null, complete)) } } }