diff --git a/picocli-shell-jline2/build.gradle b/picocli-shell-jline2/build.gradle
index 1a47d618..6ba7864b 100644
--- a/picocli-shell-jline2/build.gradle
+++ b/picocli-shell-jline2/build.gradle
@@ -12,7 +12,6 @@ sourceCompatibility = 1.5
dependencies {
compile rootProject
compile "jline:jline:$jlineVersion"
- compile "org.jline:jline:$jline3Version"
testCompile "junit:junit:$junitVersion"
}
diff --git a/picocli-shell-jline3/README.md b/picocli-shell-jline3/README.md
new file mode 100644
index 00000000..97fd7d78
--- /dev/null
+++ b/picocli-shell-jline3/README.md
@@ -0,0 +1,155 @@
+

+
+
+# Picocli Shell JLine3 - build interactive shells with ease
+
+Picocli Shell JLine3 contains components and documentation for building
+interactive shell command line applications with JLine 3 and picocli.
+
+JLine and picocli complement each other very well and have little or none functional overlap.
+
+JLine provides interactive shell functionality but has no built-in command line parsing functionality.
+What it does provide is a tokenizer for splitting a single command line String into an array of command line argument Strings.
+
+Given an array of Strings, picocli can execute a command or subcommand.
+Combining these two libraries makes it easy to build powerful interactive shell applications.
+
+
+## About JLine 3
+
+[JLine 3](https://github.com/jline/jline3) is a well-known library for building interactive shell applications.
+From the JLine [web site](https://github.com/jline/jline.github.io/blob/master/index.md):
+
+> JLine is a Java library for handling console input. It is similar in functionality to [BSD editline](http://www.thrysoee.dk/editline/) and [GNU readline](http://www.gnu.org/s/readline/) but with additional features that bring it in par with [ZSH line editor](http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html).
+
+## About picocli
+Picocli is a Java command line parser with both an annotations API and a programmatic API, featuring usage help with ANSI colors, autocomplete and nested subcommands.
+
+The picocli user manual is [here](https://picocli.info), and the GitHub project is [here](https://github.com/remkop/picocli).
+
+## Command Completer
+`PicocliJLineCompleter` is a small component that generates completion candidates to allow users to
+get command line TAB auto-completion for a picocli-based application running in a JLine 2 shell.
+
+## Example
+
+```java
+package picocli.shell.jline3.example;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+
+import org.jline.reader.Completer;
+import org.jline.reader.LineReader;
+import org.jline.reader.LineReaderBuilder;
+import org.jline.reader.impl.DefaultParser;
+import org.jline.reader.impl.LineReaderImpl;
+import org.jline.terminal.TerminalBuilder;
+import org.jline.terminal.Terminal;
+import org.jline.reader.MaskingCallback;
+
+import picocli.CommandLine;
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
+import picocli.CommandLine.ParentCommand;
+import picocli.shell.jline3.PicocliJLineCompleter;
+
+/**
+ * Example that demonstrates how to build an interactive shell with JLine3 and picocli.
+ * @since 3.7
+ */
+public class Example {
+
+ /**
+ * Top-level command that just prints help.
+ */
+ @Command(name = "", description = "Example interactive shell with completion",
+ footer = {"", "Press Ctl-D to exit."},
+ subcommands = {MyCommand.class, ClearScreen.class})
+ static class CliCommands implements Runnable {
+ LineReaderImpl reader;
+ PrintWriter out;
+
+ CliCommands() {}
+
+ public void setReader(LineReader reader){
+ this.reader = (LineReaderImpl)reader;
+ out = reader.getTerminal().writer();
+ }
+
+ public void run() {
+ out.println(new CommandLine(this).getUsageMessage());
+ }
+ }
+
+ /**
+ * A command with some options to demonstrate completion.
+ */
+ @Command(name = "cmd", mixinStandardHelpOptions = true, version = "1.0",
+ description = "Command with some options to demonstrate TAB-completion" +
+ " (note that enum values also get completed)")
+ static class MyCommand implements Runnable {
+ @Option(names = {"-v", "--verbose"})
+ private boolean[] verbosity = {};
+
+ @Option(names = {"-d", "--duration"})
+ private int amount;
+
+ @Option(names = {"-u", "--timeUnit"})
+ private TimeUnit unit;
+
+ @ParentCommand CliCommands parent;
+
+ public void run() {
+ if (verbosity.length > 0) {
+ parent.out.printf("Hi there. You asked for %d %s.%n", amount, unit);
+ } else {
+ parent.out.println("hi!");
+ }
+ }
+ }
+
+ /**
+ * Command that clears the screen.
+ */
+ @Command(name = "cls", aliases = "clear", mixinStandardHelpOptions = true,
+ description = "Clears the screen", version = "1.0")
+ static class ClearScreen implements Callable {
+
+ @ParentCommand CliCommands parent;
+
+ public Void call() throws IOException {
+ parent.reader.clearScreen();
+ return null;
+ }
+ }
+
+ public static void main(String[] args) {
+ try {
+ // set up the completion
+ CliCommands commands = new CliCommands();
+ CommandLine cmd = new CommandLine(commands);
+ Terminal terminal = TerminalBuilder.builder().build();
+ LineReader reader = LineReaderBuilder.builder()
+ .terminal(terminal)
+ .completer(new PicocliJLineCompleter(cmd.getCommandSpec()))
+ .parser(new DefaultParser())
+ .build();
+ commands.setReader(reader);
+ String prompt = "prompt> ";
+ String rightPrompt = null;
+
+ // start the shell and process input until the user quits with Ctl-D
+ String line;
+ while (true) {
+ line = reader.readLine(prompt, rightPrompt, (MaskingCallback) null, null);
+ CommandLine.run(commands, line.split("\\s+"));
+ }
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+}
+```
diff --git a/picocli-shell-jline3/build.gradle b/picocli-shell-jline3/build.gradle
new file mode 100644
index 00000000..6e2c2cbf
--- /dev/null
+++ b/picocli-shell-jline3/build.gradle
@@ -0,0 +1,84 @@
+plugins {
+ id 'java'
+ id 'distribution'
+ id 'maven-publish'
+}
+
+group 'info.picocli'
+description 'Picocli Shell JLine2 - easily build interactive shell applications with JLine 2 and picocli.'
+version "$projectVersion"
+sourceCompatibility = 1.5
+
+dependencies {
+ compile rootProject
+ compile "org.jline:jline:$jline3Version"
+ testCompile "junit:junit:$junitVersion"
+}
+
+jar {
+ manifest {
+ attributes 'Specification-Title' : 'Picocli Shell JLine2',
+ 'Specification-Vendor' : 'Remko Popma',
+ 'Specification-Version' : version,
+ 'Implementation-Title' : 'Picocli Shell JLine2',
+ 'Implementation-Vendor' : 'Remko Popma',
+ 'Implementation-Version': version,
+ 'Automatic-Module-Name' : 'info.picocli.shell.jline2'
+ }
+}
+
+ext {
+ bintrayBaseUrl = 'https://api.bintray.com/maven'
+ bintrayRepository = 'picocli'
+ bintrayPackage = 'picocli-shell-jline2'
+ bintrayUsername = System.getenv('BINTRAY_USER')
+ bintrayApiKey = System.getenv('BINTRAY_KEY')
+}
+publishing {
+ publications {
+ plugin(MavenPublication) {
+ from components.java
+ artifact sourcesJar
+ artifact testJar
+ artifact testSourcesJar
+ artifact javadocJar
+ pom.withXml {
+ def root = asNode()
+ root.appendNode('packaging', 'jar')
+ root.appendNode('name', 'picocli-shell-jline2')
+ root.appendNode('description', description)
+ root.appendNode('url', 'http://picocli.info')
+ root.appendNode('inceptionYear', '2018')
+
+ def license = root.appendNode('licenses').appendNode('license')
+ license.appendNode('name', 'The Apache Software License, version 2.0')
+ license.appendNode('url', 'http://www.apache.org/licenses/LICENSE-2.0.txt')
+ license.appendNode('distribution', 'repo')
+
+ def developer = root.appendNode('developers').appendNode('developer')
+ developer.appendNode('id', 'rpopma')
+ developer.appendNode('name', 'Remko Popma')
+ developer.appendNode('email', 'rpopma@apache.org')
+
+ def scm = root.appendNode('scm')
+ scm.appendNode('connection', 'scm:git:https://github.com/remkop/picocli.git')
+ scm.appendNode('developerConnection', 'scm:git:ssh://github.com:remkop/picocli.git')
+ scm.appendNode('url', 'https://github.com/remkop/picocli/tree/master')
+ }
+ }
+ }
+ repositories {
+ maven {
+ name 'myLocal'
+ url "file://$rootDir/../repo/$bintrayUsername"
+ }
+ maven {
+ name 'Bintray'
+ url "$bintrayBaseUrl/$bintrayUsername/$bintrayRepository/$bintrayPackage"
+ credentials {
+ username = bintrayUsername
+ password = bintrayApiKey
+ }
+ }
+ }
+}
diff --git a/picocli-shell-jline2/src/main/java/picocli/shell/jline3/PicocliJLineCompleter.java b/picocli-shell-jline3/src/main/java/picocli/shell/jline3/PicocliJLineCompleter.java
similarity index 97%
rename from picocli-shell-jline2/src/main/java/picocli/shell/jline3/PicocliJLineCompleter.java
rename to picocli-shell-jline3/src/main/java/picocli/shell/jline3/PicocliJLineCompleter.java
index 6421d0fa..608f0482 100644
--- a/picocli-shell-jline2/src/main/java/picocli/shell/jline3/PicocliJLineCompleter.java
+++ b/picocli-shell-jline3/src/main/java/picocli/shell/jline3/PicocliJLineCompleter.java
@@ -1,6 +1,5 @@
package picocli.shell.jline3;
-import org.jline.reader.impl.completer.ArgumentCompleter;
import org.jline.reader.LineReader;
import org.jline.reader.Completer;
import org.jline.reader.Candidate;
diff --git a/picocli-shell-jline2/src/test/java/picocli/shell/jline3/example/Example.java b/picocli-shell-jline3/src/test/java/picocli/shell/jline3/example/Example.java
similarity index 100%
rename from picocli-shell-jline2/src/test/java/picocli/shell/jline3/example/Example.java
rename to picocli-shell-jline3/src/test/java/picocli/shell/jline3/example/Example.java
diff --git a/settings.gradle b/settings.gradle
index d92b1789..c7999ff9 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1,5 +1,6 @@
rootProject.name = 'picocli'
include 'picocli-examples'
include 'picocli-shell-jline2'
+include 'picocli-shell-jline3'
include 'picocli-codegen'