Skip to content

Commit b9401c3

Browse files
committed
GROOVY-8162: Update Groovysh to JLine3 (initial version of /ls, /tail, and /head)
1 parent 19f9625 commit b9401c3

File tree

1 file changed

+97
-4
lines changed
  • subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh

1 file changed

+97
-4
lines changed

subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/Main.groovy

Lines changed: 97 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,11 @@ import org.apache.groovy.groovysh.jline.GroovySystemRegistry
2828
import org.apache.groovy.groovysh.util.DocFinder
2929
import org.codehaus.groovy.tools.shell.util.MessageSource
3030
import org.jline.builtins.ClasspathResourceUtil
31+
import org.jline.builtins.Completers
3132
import org.jline.builtins.ConfigurationPath
3233
import org.jline.builtins.Options
34+
import org.jline.builtins.PosixCommands
35+
import org.jline.builtins.PosixCommandsRegistry
3336
import org.jline.builtins.SyntaxHighlighter
3437
import org.jline.console.CommandInput
3538
import org.jline.console.CommandMethods
@@ -41,6 +44,7 @@ import org.jline.console.impl.JlineCommandRegistry
4144
import org.jline.console.impl.SystemHighlighter
4245
import org.jline.keymap.KeyMap
4346
import org.jline.reader.Binding
47+
import org.jline.reader.Completer
4448
import org.jline.reader.EndOfFileException
4549
import org.jline.reader.LineReader
4650
import org.jline.reader.LineReader.Option
@@ -49,6 +53,8 @@ import org.jline.reader.Reference
4953
import org.jline.reader.UserInterruptException
5054
import org.jline.reader.impl.DefaultParser
5155
import org.jline.reader.impl.DefaultParser.Bracket
56+
import org.jline.reader.impl.completer.ArgumentCompleter
57+
import org.jline.reader.impl.completer.NullCompleter
5258
import org.jline.terminal.Size
5359
import org.jline.terminal.Terminal
5460
import org.jline.terminal.Terminal.Signal
@@ -79,17 +85,37 @@ class Main {
7985
protected static class ExtraConsoleCommands extends JlineCommandRegistry implements CommandRegistry {
8086
private LineReader reader
8187
private final Supplier<Path> workDir
88+
private final Map<String, Object> variables
89+
private PosixCommandsRegistry posix
8290

83-
ExtraConsoleCommands(Supplier<Path> workDir) {
91+
ExtraConsoleCommands(Supplier<Path> workDir, Map<String, Object> variables) {
8492
super()
8593
this.workDir = workDir
94+
this.variables = variables
8695
registerCommands([
96+
'/tail' : new CommandMethods((Function) this::tail, this::optFileCompleter),
97+
'/head' : new CommandMethods((Function) this::head, this::optFileCompleter),
98+
'/ls' : new CommandMethods((Function) this::ls, this::optFileCompleter),
8799
'/clear': new CommandMethods((Function) this::clear, this::defaultCompleter),
88100
'/echo' : new CommandMethods((Function) this::echo, this::defaultCompleter),
89101
"/!" : new CommandMethods((Function) this::shell, this::defaultCompleter)
90102
])
91103
}
92104

105+
private void init() {
106+
def terminal = reader.terminal
107+
posix = new PosixCommandsRegistry(
108+
terminal.input(),
109+
new PrintStream(terminal.output()),
110+
new PrintStream(terminal.output()),
111+
workDir.get(),
112+
terminal,
113+
variables::get)
114+
posix.register('/tail', PosixCommands::tail)
115+
posix.register('/head', PosixCommands::head)
116+
posix.register('/ls', PosixCommands::ls)
117+
}
118+
93119
@Override
94120
String name() {
95121
'Console Commands'
@@ -100,7 +126,73 @@ class Main {
100126
}
101127

102128
private Terminal terminal() {
103-
return reader.terminal
129+
return reader?.terminal
130+
}
131+
132+
private List<Completer> optFileCompleter(String command) {
133+
[new ArgumentCompleter(NullCompleter.INSTANCE, new Completers.OptionCompleter(new Completers.FilesCompleter(workDir), this::commandOptions, 1))]
134+
}
135+
136+
private void tail(CommandInput input) {
137+
def usage = new String[]{
138+
"/tail - display last lines of files",
139+
"Usage: /tail [-f] [-q] [-c # | -n #] [file ...]",
140+
" -? --help Show help",
141+
" -f --follow Do not stop at end of file",
142+
" -F --FOLLOW Follow and check for file renaming or rotation",
143+
" -n --lines=LINES Number of lines to print",
144+
" -c --bytes=BYTES Number of bytes to print",
145+
}
146+
try {
147+
parseOptions(usage, input.args())
148+
posix.execute('/tail', input.args())
149+
} catch (Exception e) {
150+
saveException(e)
151+
}
152+
}
153+
154+
private void head(CommandInput input) {
155+
def usage = new String[]{
156+
"/head - display first lines of files",
157+
"Usage: /head [-n lines | -c bytes] [file ...]",
158+
" -? --help Show help",
159+
" -n --lines=LINES Print line counts",
160+
" -c --bytes=BYTES Print byte counts"
161+
}
162+
try {
163+
parseOptions(usage, input.args())
164+
posix.execute('/head', input.args())
165+
} catch (Exception e) {
166+
saveException(e)
167+
}
168+
}
169+
170+
private void ls(CommandInput input) {
171+
def usage = new String[]{
172+
"/ls - list files",
173+
"Usage: /ls [OPTIONS] [PATTERNS...]",
174+
" -? --help show help",
175+
" -1 list one entry per line",
176+
" -C multi-column output",
177+
" --color=WHEN colorize the output, may be `always', `never' or `auto'",
178+
" -a list entries starting with .",
179+
" -F append file type indicators",
180+
" -m comma separated",
181+
" -l long listing",
182+
" -S sort by size",
183+
" -f output is not sorted",
184+
" -r reverse sort order",
185+
" -t sort by modification time",
186+
" -x sort horizontally",
187+
" -L list referenced file for links",
188+
" -h print sizes in human readable form"
189+
}
190+
try {
191+
parseOptions(usage, input.args())
192+
posix.execute('/ls', input.args())
193+
} catch (Exception e) {
194+
saveException(e)
195+
}
104196
}
105197

106198
private void clear(CommandInput input) {
@@ -249,7 +341,7 @@ class Main {
249341
CommandRegistry builtins = new GroovyBuiltins(scriptEngine, workDir, configPath, (String fun) ->
250342
new ConsoleEngine.WidgetCreator(consoleEngine, fun)
251343
)
252-
def extra = new ExtraConsoleCommands(workDir)
344+
def extra = new ExtraConsoleCommands(workDir, scriptEngine.variables)
253345

254346
// Command line highlighter
255347
scriptEngine.put(GroovyEngine.NANORC_VALUE, rootURL.toString())
@@ -275,7 +367,7 @@ class Main {
275367
if (!OSUtils.IS_WINDOWS) {
276368
setSpecificHighlighter("/!", SyntaxHighlighter.build(jnanorc, "SH-REPL"))
277369
}
278-
addFileHighlight('/nano', '/less', '/slurp', '/load', '/save')
370+
addFileHighlight('/nano', '/less', '/slurp', '/load', '/save', '/head', '/tail', '/ls')
279371
addFileHighlight('/classloader', null, ['-a', '--add'])
280372
addExternalHighlighterRefresh(printer::refresh)
281373
addExternalHighlighterRefresh(scriptEngine::refresh)
@@ -302,6 +394,7 @@ class Main {
302394
}
303395

304396
[consoleEngine, builtins, extra]*.setLineReader(reader)
397+
extra.init()
305398

306399
// widgets and console initialization
307400
new TailTipWidgets(reader, systemRegistry::commandDescription, 5, TipType.COMPLETER)

0 commit comments

Comments
 (0)