Skip to content

Commit f25df32

Browse files
committed
Added documentation to describe suggestions and ghost text support
1 parent a640fd2 commit f25df32

File tree

5 files changed

+177
-1
lines changed

5 files changed

+177
-1
lines changed

content/docs/aesh/_index.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ That's it! Æsh automatically:
6565
### User Experience
6666
- **Tab completion** - Built-in completers for files, booleans, and enums
6767
- **Custom completers** - Add domain-specific completions
68+
- **[Ghost text suggestions](ghost-text-suggestions)** - Inline suggestions for commands, subcommands, and options as you type
6869
- **Auto-generated help** - `--help` automatically generated from your metadata
6970
- **Input validation** - Built-in and custom validators for options and arguments
7071
- **Error messages** - Clear, helpful error messages for users
@@ -73,6 +74,7 @@ That's it! Æsh automatically:
7374
- **Validators** - Ensure option values meet your requirements
7475
- **Converters** - Convert string input to custom types
7576
- **Completers** - Provide tab completion suggestions
77+
- **Suggestion providers** - Inline ghost text suggestions
7678
- **Activators** - Conditionally enable/disable options
7779
- **Renderers** - Customize help output format
7880
- **Custom parsers** - Override default parsing behavior

content/docs/aesh/completers.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ weight: 8
77

88
Completers provide tab-completion suggestions for options and arguments.
99

10+
{{< callout type="info" >}}
11+
Looking for inline ghost text suggestions instead of tab completion? See [Ghost Text Suggestions](../ghost-text-suggestions) for automatic command, subcommand, and option suggestions as you type.
12+
{{< /callout >}}
13+
1014
## OptionCompleter Interface
1115

1216
```java
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
---
2+
date: '2026-02-26T10:00:00+01:00'
3+
draft: false
4+
title: 'Ghost Text Suggestions'
5+
weight: 9
6+
---
7+
8+
Ghost text suggestions display inline, dimmed text ahead of the cursor as you type, showing what Æsh predicts you want to enter. Unlike [tab completion](completers), which requires pressing Tab, ghost text appears automatically and can be accepted by pressing the right arrow key.
9+
10+
## How It Works
11+
12+
As you type, ghost text suggestions appear automatically:
13+
14+
```
15+
myapp> ca|che ← "che" appears dimmed after cursor
16+
myapp> connect --ho|st= ← "st=" appears dimmed after cursor
17+
myapp> git co|mmit ← "mmit" appears dimmed after cursor
18+
```
19+
20+
- **Right arrow** accepts the suggestion
21+
- **Keep typing** to narrow or dismiss the suggestion
22+
- Only shown when there is exactly one unambiguous match
23+
24+
## CommandSuggestionProvider
25+
26+
`CommandSuggestionProvider` uses the command registry to suggest command names, subcommand names, and option names as you type. It implements the `SuggestionProvider` interface from Æsh Readline.
27+
28+
### What It Suggests
29+
30+
| Context | Example Input | Suggestion |
31+
|---------|--------------|------------|
32+
| Command names | `ca` | `che` (from `cache`) |
33+
| Subcommand names | `git co` | `mmit` (from `commit`) |
34+
| Option names | `connect --ho` | `st=` (from `--host`) |
35+
36+
Suggestions are only shown when there is a single unambiguous match. If the input `c` could match both `cache` and `connect`, no suggestion is shown.
37+
38+
For options that accept a value, the suggestion appends `=` after the option name. Boolean options (flags) do not get the trailing `=`.
39+
40+
### Setup
41+
42+
Create a `CommandSuggestionProvider` from your command registry and attach it to the console:
43+
44+
```java
45+
import org.aesh.command.impl.completer.CommandSuggestionProvider;
46+
import org.aesh.console.ReadlineConsole;
47+
48+
ReadlineConsole console = new ReadlineConsole(settings);
49+
50+
// Create suggestion provider from the console's registry
51+
CommandSuggestionProvider<?> provider =
52+
new CommandSuggestionProvider<>(console.getCommandRegistry());
53+
54+
console.setSuggestionProvider(provider);
55+
console.start();
56+
```
57+
58+
### With AeshConsoleRunner
59+
60+
If you use `AeshConsoleRunner`, you can access the underlying `ReadlineConsole` to set up suggestions:
61+
62+
```java
63+
ReadlineConsole console = new ReadlineConsole(settings);
64+
console.setPrompt(new Prompt("myapp> "));
65+
console.setSuggestionProvider(
66+
new CommandSuggestionProvider<>(console.getCommandRegistry()));
67+
console.start();
68+
```
69+
70+
## CompositeSuggestionProvider
71+
72+
You can combine multiple suggestion sources using `CompositeSuggestionProvider`. The first provider that returns a non-null suggestion wins. This lets you layer history-based suggestions with command-based suggestions:
73+
74+
```java
75+
import org.aesh.readline.CompositeSuggestionProvider;
76+
import org.aesh.readline.SuggestionProvider;
77+
78+
// History-based suggestions (checked first)
79+
SuggestionProvider historyProvider = buffer -> {
80+
// Return matching history entry suffix, or null
81+
return findHistoryMatch(buffer);
82+
};
83+
84+
// Command registry suggestions (fallback)
85+
CommandSuggestionProvider<?> commandProvider =
86+
new CommandSuggestionProvider<>(console.getCommandRegistry());
87+
88+
// Combine: history takes priority, falls back to commands
89+
CompositeSuggestionProvider composite =
90+
new CompositeSuggestionProvider(historyProvider, commandProvider);
91+
92+
console.setSuggestionProvider(composite);
93+
```
94+
95+
## Custom SuggestionProvider
96+
97+
You can implement the `SuggestionProvider` interface directly for custom suggestion logic:
98+
99+
```java
100+
import org.aesh.readline.SuggestionProvider;
101+
102+
SuggestionProvider myProvider = buffer -> {
103+
// Return the suffix to append as ghost text, or null for no suggestion
104+
if (buffer.startsWith("hel")) {
105+
return "lo";
106+
}
107+
return null;
108+
};
109+
110+
console.setSuggestionProvider(myProvider);
111+
```
112+
113+
The `suggest` method receives the current input buffer and returns the text to display after the cursor as ghost text. Return `null` when there is no suggestion.
114+
115+
## Ghost Text vs Tab Completion
116+
117+
| Feature | Ghost Text | Tab Completion |
118+
|---------|-----------|----------------|
119+
| **Trigger** | Automatic as you type | Press Tab |
120+
| **Display** | Inline dimmed text | List below prompt |
121+
| **Matches** | Single unambiguous only | Shows all matches |
122+
| **Accept** | Right arrow | Tab / Enter |
123+
| **Scope** | Commands, subcommands, options | Options, arguments, custom values |
124+
125+
Both features complement each other. Ghost text gives fast inline suggestions for unambiguous matches, while tab completion helps explore all available options when there are multiple possibilities.

content/docs/readline/_index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Think of it this way: Æsh is built **on top of** Æsh Readline. Æsh provides t
3434
- **Line Editing** - Undo/redo support with customizable key bindings
3535
- **History Management** - Search, persistence, and navigation
3636
- **Tab Completion** - Extensible completion system
37+
- **Ghost Text Suggestions** - Inline suggestion display via `SuggestionProvider`
3738
- **Input Masking** - Password and sensitive input handling
3839
- **Paste Buffer** - Copy/paste operations
3940
- **Edit Modes** - Both Emacs and Vi editing modes

content/docs/readline/completion.md

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ title: 'Completion'
55
weight: 6
66
---
77

8-
Æsh Readline supports tab completion for commands and options.
8+
Æsh Readline supports tab completion for commands and options, as well as inline ghost text suggestions via `SuggestionProvider`.
99

1010
## Completion Class
1111

@@ -181,3 +181,47 @@ Completion colored = new Completion(
181181
TerminalColor.RED
182182
);
183183
```
184+
185+
## Ghost Text Suggestions
186+
187+
In addition to tab completion, Æsh Readline supports inline ghost text suggestions that appear automatically as the user types. Ghost text is rendered as dimmed text after the cursor and can be accepted with the right arrow key.
188+
189+
### SuggestionProvider Interface
190+
191+
```java
192+
import org.aesh.readline.SuggestionProvider;
193+
194+
SuggestionProvider provider = buffer -> {
195+
// Return the suffix to display as ghost text, or null for no suggestion
196+
if (buffer.startsWith("hel")) {
197+
return "lo";
198+
}
199+
return null;
200+
};
201+
```
202+
203+
### Setting Up Suggestions
204+
205+
```java
206+
Readline readline = ReadlineBuilder.builder().build();
207+
readline.setSuggestionProvider(provider);
208+
```
209+
210+
### CompositeSuggestionProvider
211+
212+
Chain multiple providers together. The first provider that returns a non-null result wins:
213+
214+
```java
215+
import org.aesh.readline.CompositeSuggestionProvider;
216+
217+
CompositeSuggestionProvider composite = new CompositeSuggestionProvider(
218+
historyProvider, // checked first
219+
commandProvider // fallback
220+
);
221+
222+
readline.setSuggestionProvider(composite);
223+
```
224+
225+
{{< callout type="info" >}}
226+
If you're using the Æsh command framework, see [Ghost Text Suggestions](/docs/aesh/ghost-text-suggestions) for the built-in `CommandSuggestionProvider` that automatically suggests command names, subcommands, and options from your command registry.
227+
{{< /callout >}}

0 commit comments

Comments
 (0)