KetraTerm Swing Host
Optional host-side helpers for applications embedding SwingTerminal: search
chrome, terminal action bindings, context menus, completion adapters, and
clipboard consent. Hosts explicitly construct and install the helpers they need.
The terminal view and session retain their own rendering and input responsibilities.
Dependency
Add io.github.ketraterm:ketraterm-ui-swing-host alongside your terminal entry
point, using the BOM and repository setup. This module
exposes the Swing UI, completion API, and coroutine dependencies. Filesystem
completion and persistence are separate optional modules.
Search chrome
SwingTerminalSearchBar delegates scanning, highlights, and result navigation
to the terminal's search API. The bar includes independent match-case, whole-word,
and regex toggles with explanatory tooltips, and shows invalid-pattern errors. SwingTerminalOverlayPane places the bar over the
terminal content, so opening it does not reduce the grid's available space.
Construct Swing components on the event dispatch thread (EDT). This example wraps an existing terminal; its owner still binds and disposes the terminal.
import io.github.ketraterm.ui.swing.api.SwingTerminal
import io.github.ketraterm.ui.swing.host.SwingTerminalOverlayPane
import io.github.ketraterm.ui.swing.host.SwingTerminalSearchBar
import javax.swing.JComponent
import javax.swing.SwingUtilities
class TerminalSearchPane(terminal: SwingTerminal) : AutoCloseable {
init {
check(SwingUtilities.isEventDispatchThread())
}
private val searchBar = SwingTerminalSearchBar(terminal)
val component: JComponent =
SwingTerminalOverlayPane(terminal, searchBar.component)
fun openSearch() = searchBar.open()
override fun close() = searchBar.close()
}
Mount component in the host window and invoke openSearch from a host action.
Call close when removing the pane; it cancels search observation and clears
active highlights. Removing the bar from a displayable hierarchy also cancels
its observation. open, close, and refreshColors enqueue work when called
off the EDT; read isOpen and manipulate component on the EDT.
The bar installs no command shortcuts, including Enter, Shift+Enter, or Escape.
Hosts invoke performAction(SwingTerminalSearchAction) on the EDT and bind those
commands through their own action system. It returns false when search is closed.
setShortcutTextProvider supplies plain-text labels from those same bindings;
tooltips read the provider when requested, so a changed keymap is reflected immediately.
Return null for an unbound action. Tab focus traversal and Space activation use
normal Swing button behavior and remain available without command bindings.
For a plain Swing host, map keystrokes on
searchBar.component.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
and install corresponding AbstractActions in its actionMap, calling
searchBar.performAction(action). The standalone app owns its defaults; the
IntelliJ plugin registers IDE actions so keymap remapping and multi-stroke shortcuts
remain platform responsibilities. Keep search bindings scoped to the bar so they
do not intercept terminal or unrelated editor input.
Use SwingTerminalSearchColors.create, copy, or a builder to supply an immutable
palette through refreshColors(colors). Updating colors preserves the query and
visibility. The palette is retained across close/open cycles.
Host actions and context menus
SwingTerminalHostShortcutMap.platformDefault() supplies optional platform
bindings. It does not register Swing actions. Install the entries with
forEachShortcut, or resolve a key event with actionFor(keyCode, modifiersEx)
inside your SwingHostServices key handler. Return whether the host consumed the
event so unhandled keys continue to terminal input.
Use withShortcut and withoutShortcut to customize bindings. Shortcuts must
remain unique and use extended keyboard modifier masks.
SwingTerminalContextMenuItems.addTerminalActions appends selection, paste,
search, screen-clear, and applicable hyperlink actions to a host-owned
JPopupMenu. Pass the terminal's context-menu request and your search-opening
callback, append product-specific items, and show the menu from the host callback
on the EDT. See Swing host services
for callback configuration.
Completion bridge
SwingCompletionSuggestionProvider adapts a
TerminalCompletionEngine to the terminal's
suggestion contract. It preserves replacement ranges, source identity,
presentation fields, matched ranges, and opaque feedback tokens. The host selects
the engine and sources and supplies current profile, directory, and shell metadata.
import io.github.ketraterm.completion.api.TerminalCompletionEngine
import io.github.ketraterm.ui.swing.api.SwingTerminal
import io.github.ketraterm.ui.swing.host.SwingCompletionContext
import io.github.ketraterm.ui.swing.host.SwingCompletionSuggestionProvider
import io.github.ketraterm.ui.swing.suggestion.SwingShellSuggestionFeedbackHandler
import javax.swing.SwingUtilities
fun installCompletion(
terminal: SwingTerminal,
engine: TerminalCompletionEngine,
contextProvider: () -> SwingCompletionContext,
feedbackHandler: SwingShellSuggestionFeedbackHandler =
SwingShellSuggestionFeedbackHandler.NONE,
) {
check(SwingUtilities.isEventDispatchThread())
terminal.setShellSuggestionProvider(
SwingCompletionSuggestionProvider(
engine = engine,
contextProvider = contextProvider,
sourceLabels = mapOf("spec" to "Commands", "path" to "Files"),
feedbackHandler = feedbackHandler,
),
)
}
The terminal opens the provider on the EDT, capturing one immutable context and
feedback handler before background collection. Keep contextProvider cheap.
Direct calls to suggestions(request) capture context in the caller's thread;
the returned flow is cold and runs engine work only when collected. This adapter
does not choose a dispatcher, launch jobs, or close the engine. Collection
cancellation and engine failures propagate to the caller.
An invalid converted completion request produces one empty suggestion snapshot.
Optional sourceLabels customize display labels, including localization.
SwingCompletionFeedbackRecorder.createHandler() maps accepted and explicitly
dismissed suggestions to a host-owned learning sink. Admission rejection is
ignored. The host owns learning-store synchronization.
Configure completion on the EDT and keep engine resources alive for their owning host's lifetime. See suggestion request ownership for editing authority, request invalidation, custom presentation, and diagnostics. Use completion-host for filesystem sources and completion-persistence for optional saved learning.
Clipboard consent and dialogs
SwingClipboardReadPrompt owns cancellable consent for one terminal pane.
Construct it with a product dialog callback, or bridge
SwingMessageDialogs.showModeless. Operations and decisions belong to the EDT;
close the prompt there when disposing the pane. Denial, Escape, cancellation,
and closure cannot approve a read. A block decision lasts for the pane's lifetime.
Use one SwingClipboardReader per window. Call its suspending read on the EDT
with the requesting pane's prompt, message, and clipboard handler, after earlier
posted clipboard writes. It enforces admitted permission and reads native
clipboard data on its I/O dispatcher. Busy prompts are denied; a busy native
read is unavailable. Only one native read runs across reader instances, and a
cancelled blocking call keeps that slot until it returns. The session owns the
request deadline, permission revocation, and response serialization.
SwingClipboardPrompts builds consent text from terminal names and character
counts without placing clipboard contents in the dialog. SwingDialogRequest
holds plain text and copied choices; SwingMessageDialogs escapes message text
for Swing display. Modal and modeless presenters return an option index or
null for dismissal. Hosts still wire these helpers into their session's
clipboard services and choose write-consent policy.
Localization and host settings
Supply SwingHostMessages to search, context-menu, dialog, and clipboard helpers
to integrate a host message framework. forLocale(locale, bundle) uses JDK
resource bundles and MessageFormat, with missing keys falling back to the
bundled English catalog. The selected locale is captured; static component
labels are resolved at construction. The catalog
defines keys and arguments. Message arguments are plain text, not markup.
SwingTerminalSettingsBounds provides shared preference-control ranges for
hosts. These limits do not define the core grid or renderer's valid configuration.
For packages and dependencies, see Module.md.