dscode-terminal
Terminal manager and PTY lifecycle management for DSCode.
This crate provides a portable PTY-backed terminal manager that can be used
independently of any UI framework. Event forwarding is abstracted behind the
TerminalEventSender trait, so you can integrate with any event system.
Install
Features
- Profile management -- register, unregister, and list shell profiles with custom arguments, environment variables, and working directories.
- PTY lifecycle -- spawn, resize, write to, and close terminal instances
backed by
portable-pty. - Pluggable event forwarding -- implement
TerminalEventSenderto route PTY output and close events to any consumer (Tauri frontend, web socket, log file, etc.). - Tauri integration -- optional
TauriEventSenderbehind thetaurifeature flag for drop-in use with Tauri applications. - Graceful shutdown --
close_all()andDropimplementations ensure PTY resources and reader threads are cleaned up properly. - Thread-safe -- all state is guarded by
std::sync::Mutex; reader threads communicate viaArc<dyn TerminalEventSender>andAtomicBoolshutdown signals.
State Machine
Each TerminalInstance follows a strict lifecycle:
Created ──────► Running ──────► ShuttingDown ──────► Closed
│ ▲
│ (process exit, │
│ read error) │
└────────────────────────────────────┘
Transitions:
Created->Running(start signal sent viastart_reading())Running->ShuttingDown(shutdown flag set byclose_terminal())Running->Closed(PTY process exits, reader thread detects EOF)ShuttingDown->Closed(reader thread sees shutdown flag, exits loop)
Concurrency:
- PTY I/O uses
std::sync::Mutex(not tokio) because PTY operations are synchronous. The reader thread runs on a dedicated OS thread (not a tokio task).ShutdownSignalusesAtomicBoolfor lock-free cross-thread signaling. State transitions are synchronized throughTerminalManager'sterminalsmutex.
Feature Flags
| Feature | Default | Description |
|---|---|---|
tauri |
off | Enables TauriEventSender, which forwards events through the Tauri event system |
Usage
Basic terminal creation
use ;
// Implement the trait for your event system
;
let manager = new;
// Create a terminal with default shell
let id = manager.create_terminal?;
// Or use the options builder
let options = TerminalOptions ;
let id = manager.create_terminal_with_options?;
// Start reading PTY output
manager.start_reading?;
// Write to the terminal
manager.write_to_terminal?;
// Resize
manager.resize_terminal?;
// Close a single terminal
manager.close_terminal?;
// Close all terminals (also called automatically on Drop)
manager.close_all;
Using profiles
let profile = TerminalProfile ;
manager.register_profile?;
let options = TerminalOptions ;
let id = manager.create_terminal_with_options?;
Tauri integration
Enable the tauri feature and use TauriEventSender:
[]
= { = "0.1.0", = ["tauri"] }
use ;
let sender = new;
let manager = new;
TauriEventSender emits the following events:
| Event name | Payload |
|---|---|
terminal-data:{terminal_id} |
{ "data": "..." } |
terminal-closed |
terminal_id |
API Surface
Types
| Type | Description |
|---|---|
TerminalManager |
Main entry point. Manages profiles and terminal instances. |
TerminalInfo |
Metadata about a running terminal (id, name, shell, cwd). |
TerminalInstance |
Internal PTY state (writer, reader handle, shutdown signal). |
TerminalOptions |
Configuration for creating a new terminal. |
TerminalProfile |
Saved shell configuration with id, shell path, args, env, cwd. |
TerminalState |
Lifecycle state enum: Created, Running, ShuttingDown, Closed. |
TerminalEventSender |
Trait for receiving PTY output and close events. |
TauriEventSender |
Tauri-backed implementation of TerminalEventSender (feature: tauri). |
TerminalError |
Error type for terminal operations. |
TerminalManager Methods
| Method | Description |
|---|---|
new(event_sender) |
Create a manager with a custom event sender. |
register_profile(profile) |
Register a shell profile. |
unregister_profile(id) |
Remove a shell profile. |
get_profile(id) |
Look up a profile by id. |
list_profiles() |
List all registered profiles. |
create_terminal(name, shell, cwd) |
Create a terminal with simple options. |
create_terminal_with_options(opts) |
Create a terminal with full TerminalOptions. |
start_reading(id) |
Signal the reader thread to start forwarding output. |
write_to_terminal(id, data) |
Write data to the terminal's stdin. |
resize_terminal(id, cols, rows) |
Resize the terminal's PTY. |
close_terminal(id) |
Close a single terminal and clean up resources. |
close_all() |
Close all terminals. Called automatically on Drop. |
list_terminals() |
List TerminalInfo for all active terminals. |
Related Crates
dscode-session-- UsesTerminalManageras part of the IDE session.dscode-extension-host-- Extension host that may create terminals via the session.
Full API Docs
https://docs.rs/dscode-terminal
License
MIT