feat: Add comprehensive terminal graphics protocol support with runtime detection#1378
feat: Add comprehensive terminal graphics protocol support with runtime detection#1378gnodet merged 13 commits intojline:masterfrom
Conversation
f9bb0c9 to
1a656b6
Compare
775c6a3 to
6c6319f
Compare
This commit introduces complete support for displaying images in modern terminals
through multiple graphics protocols with intelligent runtime detection.
## Features
### Multi-Protocol Graphics Support
- **Kitty Graphics Protocol** (Priority: 90) - Modern, feature-rich protocol
- **iTerm2 Inline Images** (Priority: 70) - iTerm2's proprietary protocol
- **Sixel Graphics** (Priority: 10) - Widely supported legacy protocol
### Intelligent Runtime Detection
- **Sixel Detection**: Device Attributes query (ESC[c) - same method as lsix command
- **Kitty Detection**: Static detection for known supported terminals
- **Automatic Fallback**: Falls back to static detection if runtime detection fails
- **Performance Optimized**: Skips runtime detection for known non-supporting terminals
### Comprehensive Terminal Support
| Terminal | Sixel | Kitty | iTerm2 | Detection Method |
|----------|-------|-------|--------|------------------|
| **Kitty** | ❌ No | ✅ Yes | ❌ No | Runtime + Static |
| **Ghostty** | ❌ No | ✅ Yes | ❌ No | Static (confirmed by maintainer) |
| **iTerm2** | ✅ Yes | ✅ Yes | ✅ Yes | Static + Environment |
| **WezTerm** | ✅ Yes | ✅ Yes | ❌ No | Static + Environment |
| **xterm** | ✅ Yes | ❌ No | ❌ No | Runtime + Static |
| **foot** | ✅ Yes | ❌ No | ❌ No | Runtime + Static |
| **Konsole** | ✅ Yes | ❌ No | ❌ No | Runtime + Static |
## Implementation
### Core Classes
- **TerminalGraphicsManager** - Unified interface for graphics operations
- **SixelGraphics** - Sixel protocol implementation with runtime detection
- **KittyGraphics** - Kitty protocol implementation
- **ITerm2Graphics** - iTerm2 protocol implementation
- **TerminalGraphics** - Common interface for all protocols
### Usage Examples
```java
// Automatic protocol selection
TerminalGraphicsManager.displayImage(terminal, bufferedImage);
// With options
TerminalGraphics.ImageOptions options = new TerminalGraphics.ImageOptions()
.width(100).height(100).preserveAspectRatio(true);
TerminalGraphicsManager.displayImage(terminal, image, options);
// Force specific protocol
TerminalGraphicsManager.forceProtocol(TerminalGraphics.Protocol.KITTY);
// Check support
boolean supported = TerminalGraphicsManager.isGraphicsSupported(terminal);
Optional<TerminalGraphics> best = TerminalGraphicsManager.getBestProtocol(terminal);
```
## Key Benefits
1. **Future-Proof**: Works with unknown terminals that support protocols
2. **Accurate Detection**: Runtime queries provide definitive answers
3. **Performance**: Smart detection avoids unnecessary queries
4. **Robust**: Comprehensive error handling and fallbacks
5. **Compatible**: Maintains full backward compatibility
6. **Extensible**: Easy to add new protocols via ServiceLoader
## Documentation
- Complete JavaDoc documentation for all classes
- Usage examples in TerminalGraphicsExample
- Comprehensive terminal-graphics.md guide in website/docs/advanced/
## Testing
- Comprehensive test coverage for all protocols
- Runtime detection testing with mocked responses
- Error handling and edge case testing
- Integration testing across different scenarios
## Build Requirements
- Upgraded to JDK 24 and Maven 4.0.0-rc-4
- All builds pass with mvn clean install
- Spotless formatting applied consistently
This implementation brings JLine's graphics capabilities to modern standards
while maintaining the library's reliability and performance characteristics.
6c6319f to
1d3df80
Compare
91d89d2 to
eb6f2f2
Compare
Address PR review comments:
1. Fix Sixel detection logic: Remove endsWith('4c') check that caused
false positives with extensions like '14c', '24c', etc. Now only
checks for proper ';4;' and ';4c' patterns.
2. Remove overly broad XTerm detection: The previous logic assumed all
terminals with TERM starting with 'xterm' support Sixel, causing
many false positives. Replaced with comment explaining the issue
and relying on runtime detection for real xterm support.
3. Fix Sixel aspect ratio: Change SIXEL_INTRO from '0;1;q' (2:1 ratio)
to '9;1;q' (1:1 ratio) for correct pixel aspect ratio. Updated
documentation comments to reflect the correct parameter meanings.
These changes make Sixel detection more accurate and reliable by
eliminating false positives and ensuring proper image rendering.
eb6f2f2 to
3921cd4
Compare
|
augment review |
|
Sorry, Augment does not have access to the org this pull request's branch is from. |
|
augment review |
|
Sorry, Augment does not have access to the org this pull request's branch is from. |
Changes: - Add Kitty graphics timeout constants (GRAPHICS_KITTY_TIMEOUT, GRAPHICS_KITTY_SUBSEQUENT_TIMEOUT) in TerminalBuilder for consistency with Sixel timeout constants - Make forcedProtocol volatile in TerminalGraphicsManager for thread-safety - Make sixelSupportOverride volatile in SixelGraphics for thread-safety - Add explicit null check in convertToSixel() with clear error message - Clarify Sixel INTRO parameter documentation (aspect ratio and background color handling)
|
augment review |
🤖 Augment PR SummarySummary: Introduces a new terminal-graphics abstraction to let JLine display raster images in supporting terminals, with protocol selection and basic capability detection. Changes:
Technical Notes: Protocol support is primarily inferred via environment/terminal type heuristics, with Sixel optionally using a short runtime query/response to reduce false positives and avoid hangs. 🤖 Was this summary useful? React with 👍 or 👎 |
- Fix base64 encoding in ITerm2Graphics to use UTF-8 explicitly - Fix test assertion to handle ServiceLoader-loaded protocols - Update documentation to use correct system property prefix - Fix example documentation to match actual command-line arguments - Clarify Kitty detection method in documentation - Fix Sixel detection to prioritize terminal type over environment variables
- Changed module-info.java to use 'requires static transitive java.desktop' instead of 'requires transitive java.desktop' - This allows JLine to work in headless environments without java.desktop - Added runtime checks in TerminalGraphicsManager to detect java.desktop availability - Graphics features gracefully fail with informative error messages when java.desktop is not available - Added isJavaDesktopAvailable() method to check availability at runtime - All tests pass with java.desktop present
- Changed AVAILABLE_PROTOCOLS from ArrayList to CopyOnWriteArrayList for thread-safety - Made registerProtocol() synchronized and added automatic re-sorting after registration - This ensures that dynamically registered protocols maintain priority ordering - Added comprehensive test to verify priority ordering is maintained - Addresses review comment: jline#1378 (comment)
- getBestProtocol() now checks isSupported() even when forcedProtocol is set - This prevents routing to protocols that the terminal doesn't actually support - Updated testProtocolForcing to reflect the new behavior - Added testForcedProtocolChecksIsSupported to verify the fix - Addresses review comment: jline#1378 (comment)
|
augment review |
| } else { | ||
| // Otherwise, try to display a sample image from resources | ||
| try { | ||
| InputStream is = TerminalGraphicsExample.class.getResourceAsStream("/images/jline-logo.png"); |
| * @throws IOException if an I/O error occurs | ||
| */ | ||
| public static void displayImageStatic(Terminal terminal, File file) throws IOException { | ||
| BufferedImage image = ImageIO.read(file); |
There was a problem hiding this comment.
ImageIO.read(...) can return null for unknown/unsupported image formats; passing null into displayImageStatic turns this into a NullPointerException rather than a clear read/format failure.
Severity: medium
Other Locations
terminal/src/main/java/org/jline/terminal/impl/SixelGraphics.java:280terminal/src/main/java/org/jline/terminal/impl/SixelGraphics.java:619terminal/src/main/java/org/jline/terminal/impl/SixelGraphics.java:626
🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.
- Fix toLowerCase to use Locale.ROOT in DoubleSizeCharacters.java - Add null checks after ImageIO.read() calls in SixelGraphics.java - Fix registerProtocol to dedupe by Protocol enum instead of instance - Remove undocumented debug property from documentation - Update test to verify deduplication behavior Addresses review comments: - jline#1378 (comment) (already fixed) - jline#1378 (comment) (already fixed) - Sixel detection endsWith bug (already fixed) - Sixel aspect ratio (already fixed) - toLowerCase locale issue - ImageIO.read null checks - registerProtocol deduplication - Debug property documentation
- Changed all references from 'SixelExample' to 'TerminalGraphicsExample' in the Javadoc - Addresses review comment: jline#1378 (comment)
- Added examples showing how to use './mvx demo' with '--' separator - Kept direct java invocation examples for reference - Makes it clear that '--' is needed to pass arguments through mvx
- Added terminal-graphics.md to sidebar navigation under Advanced Features - Added JLine 4.x version notice at the top of the document - Added Requirements section explaining java.desktop dependency - Clarified that this is a new feature in JLine 4.x, not available in 3.x
🎨 Terminal Graphics Protocol Support
This PR adds comprehensive support for terminal graphics protocols with intelligent runtime detection, making JLine capable of displaying images in modern terminals.
🚀 Major Features
1. Multi-Protocol Graphics Support
2. Intelligent Runtime Detection
ESC[c) - same method aslsixcommand3. Comprehensive Terminal Support
🔧 Implementation Details
Core Classes
TerminalGraphicsManager- Unified interface for graphics operationsSixelGraphics- Sixel protocol implementation with runtime detectionKittyGraphics- Kitty protocol implementationITerm2Graphics- iTerm2 protocol implementationTerminalGraphics- Common interface for all protocolsRuntime Detection Logic
Usage Examples
📚 Documentation
website/docs/advanced/terminal-graphics.mdTerminalGraphicsExamplewith practical examplesSIXEL_GRAPHICS.mdfrom root (moved to proper website docs)🔧 Build & Development
Upgraded Build Tools
mvn clean installpasses successfullySingle Clean Commit
🧪 Testing
Comprehensive Test Coverage
SixelGraphicsTest.java- Sixel protocol testingTerminalGraphicsTest.java- Manager and integration testingDoubleSizeCharactersTest.java- Character rendering testing🎯 Key Benefits
🔍 Testing
🐛 Fixes
🔄 Backward Compatibility
This PR maintains full backward compatibility. All existing functionality continues to work unchanged, with graphics support being purely additive.
Ready for review! This implementation brings JLine's graphics capabilities to modern standards with a clean, single commit and comprehensive documentation. 🚀✨