@@ -28,8 +28,11 @@ import org.apache.groovy.groovysh.jline.GroovySystemRegistry
28
28
import org.apache.groovy.groovysh.util.DocFinder
29
29
import org.codehaus.groovy.tools.shell.util.MessageSource
30
30
import org.jline.builtins.ClasspathResourceUtil
31
+ import org.jline.builtins.Completers
31
32
import org.jline.builtins.ConfigurationPath
32
33
import org.jline.builtins.Options
34
+ import org.jline.builtins.PosixCommands
35
+ import org.jline.builtins.PosixCommandsRegistry
33
36
import org.jline.builtins.SyntaxHighlighter
34
37
import org.jline.console.CommandInput
35
38
import org.jline.console.CommandMethods
@@ -41,6 +44,7 @@ import org.jline.console.impl.JlineCommandRegistry
41
44
import org.jline.console.impl.SystemHighlighter
42
45
import org.jline.keymap.KeyMap
43
46
import org.jline.reader.Binding
47
+ import org.jline.reader.Completer
44
48
import org.jline.reader.EndOfFileException
45
49
import org.jline.reader.LineReader
46
50
import org.jline.reader.LineReader.Option
@@ -49,6 +53,8 @@ import org.jline.reader.Reference
49
53
import org.jline.reader.UserInterruptException
50
54
import org.jline.reader.impl.DefaultParser
51
55
import org.jline.reader.impl.DefaultParser.Bracket
56
+ import org.jline.reader.impl.completer.ArgumentCompleter
57
+ import org.jline.reader.impl.completer.NullCompleter
52
58
import org.jline.terminal.Size
53
59
import org.jline.terminal.Terminal
54
60
import org.jline.terminal.Terminal.Signal
@@ -79,17 +85,37 @@ class Main {
79
85
protected static class ExtraConsoleCommands extends JlineCommandRegistry implements CommandRegistry {
80
86
private LineReader reader
81
87
private final Supplier<Path > workDir
88
+ private final Map<String , Object > variables
89
+ private PosixCommandsRegistry posix
82
90
83
- ExtraConsoleCommands (Supplier<Path > workDir ) {
91
+ ExtraConsoleCommands (Supplier<Path > workDir , Map< String , Object > variables ) {
84
92
super ()
85
93
this . workDir = workDir
94
+ this . variables = variables
86
95
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),
87
99
' /clear' : new CommandMethods ((Function ) this ::clear, this ::defaultCompleter),
88
100
' /echo' : new CommandMethods ((Function ) this ::echo, this ::defaultCompleter),
89
101
" /!" : new CommandMethods ((Function ) this ::shell, this ::defaultCompleter)
90
102
])
91
103
}
92
104
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
+
93
119
@Override
94
120
String name () {
95
121
' Console Commands'
@@ -100,7 +126,73 @@ class Main {
100
126
}
101
127
102
128
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
+ }
104
196
}
105
197
106
198
private void clear (CommandInput input ) {
@@ -249,7 +341,7 @@ class Main {
249
341
CommandRegistry builtins = new GroovyBuiltins (scriptEngine, workDir, configPath, (String fun) ->
250
342
new ConsoleEngine.WidgetCreator (consoleEngine, fun)
251
343
)
252
- def extra = new ExtraConsoleCommands (workDir)
344
+ def extra = new ExtraConsoleCommands (workDir, scriptEngine . variables )
253
345
254
346
// Command line highlighter
255
347
scriptEngine. put(GroovyEngine . NANORC_VALUE , rootURL. toString())
@@ -275,7 +367,7 @@ class Main {
275
367
if (! OSUtils . IS_WINDOWS ) {
276
368
setSpecificHighlighter(" /!" , SyntaxHighlighter . build(jnanorc, " SH-REPL" ))
277
369
}
278
- addFileHighlight(' /nano' , ' /less' , ' /slurp' , ' /load' , ' /save' )
370
+ addFileHighlight(' /nano' , ' /less' , ' /slurp' , ' /load' , ' /save' , ' /head ' , ' /tail ' , ' /ls ' )
279
371
addFileHighlight(' /classloader' , null , [' -a' , ' --add' ])
280
372
addExternalHighlighterRefresh(printer ::refresh)
281
373
addExternalHighlighterRefresh(scriptEngine ::refresh)
@@ -302,6 +394,7 @@ class Main {
302
394
}
303
395
304
396
[consoleEngine, builtins, extra]* . setLineReader(reader)
397
+ extra. init()
305
398
306
399
// widgets and console initialization
307
400
new TailTipWidgets (reader, systemRegistry ::commandDescription, 5 , TipType . COMPLETER )
0 commit comments