Skip to content

php-cli/terminal

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

32 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Commander - MC-Style PHP Console Application

Component-based Midnight Commander-style terminal application framework.
Create fullscreen, keyboard-driven interfaces with double-buffered rendering.

Commander Screenshot


πŸš€ Why Commander?

Build terminal UIs like you build web apps - with reusable components, clean architecture, and modern PHP.

// Simple as creating a PHP file
$app = new Application($symfonyApp);
$app->run(new CommandsScreen($commandDiscovery, $commandExecutor));

No complex setup. No learning curve. Just beautiful terminal UIs.


✨ Features

  • 🎨 Multiple Color Themes - Midnight Commander, Dark, and Light themes
  • ⚑ Double-Buffered Rendering - Flicker-free display with minimal ANSI sequences
  • 🧩 Component-Based Architecture - Reusable UI components (Tables, Forms, Lists, Panels)
  • ⌨️ Full Keyboard Navigation - Function keys, arrow keys, and shortcuts
  • πŸ“¦ Built-in Features - Command Browser, File Browser, Composer Manager
  • πŸ”Œ Extensible - Easy to create custom screens and components

πŸ“‹ Requirements

  • PHP 8.3 or higher
  • Symfony Console 7.3+
  • Terminal with ANSI color support (most modern terminals)

πŸš€ Quick Start

1. Installation

Install via Composer:

composer require cli/terminal

2. Create Launch Script

Create a simple PHP file (e.g., console or ui) that launches the Commander interface:

#!/usr/bin/env php
<?php

declare(strict_types=1);

require __DIR__ . '/vendor/autoload.php';

use Butschster\Commander\Application;
use Butschster\Commander\Feature\CommandBrowser\Screen\CommandsScreen;
use Butschster\Commander\Feature\CommandBrowser\Service\CommandDiscovery;
use Butschster\Commander\Feature\CommandBrowser\Service\CommandExecutor;
use Butschster\Commander\UI\Component\Layout\MenuBar;
use Butschster\Commander\UI\Theme\ColorScheme;
use Butschster\Commander\UI\Theme\MidnightTheme;
use Symfony\Component\Console\Application as SymfonyApplication;

// 1. Create Symfony Console Application
$symfonyApp = new SymfonyApplication('My App', '1.0.0');

// You can add your Symfony commands here:
// $symfonyApp->add(new YourCustomCommand());

// 2. Choose and apply theme
ColorScheme::applyTheme(new MidnightTheme());
// Available: MidnightTheme, DarkTheme, LightTheme

// 3. Create Commander application
$app = new Application($symfonyApp);
$app->setTargetFps(30);

// 4. Setup global menu bar (optional)
$globalMenu = new MenuBar([
    'F1' => ' Help',
    'F2' => ' Commands',
    'F10' => ' Quit',
]);
$app->setGlobalMenuBar($globalMenu);

// 5. Register global shortcuts (optional)
$app->registerGlobalShortcut('F10', function () use ($app) {
    $app->stop(); // Quit application
});

// 6. Create services and initial screen
$commandDiscovery = new CommandDiscovery($symfonyApp);
$commandExecutor = new CommandExecutor($symfonyApp);
$initialScreen = new CommandsScreen($commandDiscovery, $commandExecutor);

// 7. Run the application
$app->run($initialScreen);

3. Make It Executable and Launch

chmod +x console
./console

That's it! You now have a fullscreen terminal UI with:

  • ✨ Midnight Commander-style interface
  • πŸ“‹ Command browser with search and execution
  • ⌨️ Keyboard navigation (↑↓, Enter, F10 to quit)
  • ⚑ Smooth, flicker-free rendering

Alternative: Symfony Console Command (Optional)

If you're working within a Symfony/Laravel/Spiral application, you can create a Console command instead:

Click to see Symfony Console Command example
<?php

declare(strict_types=1);

namespace App\Console;

use Butschster\Commander\Application;
use Butschster\Commander\Feature\CommandBrowser\Screen\CommandsScreen;
use Butschster\Commander\Feature\CommandBrowser\Service\CommandDiscovery;
use Butschster\Commander\Feature\CommandBrowser\Service\CommandExecutor;
use Butschster\Commander\UI\Theme\ColorScheme;
use Butschster\Commander\UI\Theme\MidnightTheme;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

#[AsCommand(name: 'app:ui', description: 'Launch Commander UI')]
final class UICommand extends Command
{
    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $symfonyApp = $this->getApplication();
        ColorScheme::applyTheme(new MidnightTheme());

        $app = new Application($symfonyApp);
        $commandDiscovery = new CommandDiscovery($symfonyApp);
        $commandExecutor = new CommandExecutor($symfonyApp);
        $screen = new CommandsScreen($commandDiscovery, $commandExecutor);

        $app->run($screen);

        return Command::SUCCESS;
    }
}

Then run: php bin/console app:ui


🎨 Available Themes

Commander comes with three built-in themes:

Midnight Commander (Default)

Classic blue theme with cyan highlights - just like the original Midnight Commander.

use Butschster\Commander\UI\Theme\MidnightTheme;
ColorScheme::applyTheme(new MidnightTheme());

Dark Theme

Modern dark theme with black background and green/cyan accents.

use Butschster\Commander\UI\Theme\DarkTheme;
ColorScheme::applyTheme(new DarkTheme());

Light Theme

Light theme with white background - perfect for well-lit environments.

use Butschster\Commander\UI\Theme\LightTheme;
ColorScheme::applyTheme(new LightTheme());

πŸ’‘ Tip: Call ColorScheme::applyTheme() before creating your Application instance.


πŸ“¦ Built-in Screens

Commander includes several ready-to-use screens that you can integrate into your application:

1. Command Browser Screen

Browse and execute all registered Symfony Console commands.

use Butschster\Commander\Feature\CommandBrowser\Screen\CommandsScreen;
use Butschster\Commander\Feature\CommandBrowser\Service\CommandDiscovery;
use Butschster\Commander\Feature\CommandBrowser\Service\CommandExecutor;

$commandDiscovery = new CommandDiscovery($symfonyApp);
$commandExecutor = new CommandExecutor($symfonyApp);
$screen = new CommandsScreen($commandDiscovery, $commandExecutor);

Features:

  • βœ… Lists all available Symfony commands
  • πŸ” Search/filter commands by name or namespace
  • πŸ“ Shows command descriptions and arguments
  • ⚑ Execute commands directly from UI
  • πŸ“Š Displays command output in real-time

Keyboard Shortcuts:

  • ↑↓ - Navigate commands
  • Enter - Execute selected command
  • Ctrl+R - Refresh command list
  • / - Search commands
  • Escape - Cancel/go back

2. File Browser Screen

Navigate and browse the filesystem with a two-panel layout.

use Butschster\Commander\Feature\FileBrowser\Screen\FileBrowserScreen;
use Butschster\Commander\Feature\FileBrowser\Service\FileSystemService;

$fileSystem = new FileSystemService();
$screen = new FileBrowserScreen(
    $fileSystem, 
    $screenManager, 
    '/path/to/start/directory'
);

Features:

  • πŸ“ Two-panel layout (list + preview)
  • πŸ“„ File/directory navigation
  • πŸ‘οΈ File preview with syntax highlighting
  • πŸ“Š Shows file sizes and modification times
  • πŸ”„ Sort by name, size, or date

Keyboard Shortcuts:

  • ↑↓ - Navigate files
  • Enter - Open directory / view file
  • Backspace - Go to parent directory
  • Tab - Switch between panels
  • F5 - Copy file
  • F6 - Move file
  • F8 - Delete file

3. Composer Manager Screen

Manage Composer packages with tabbed interface.

use Butschster\Commander\Feature\ComposerManager\Screen\ComposerManagerScreen;
use Butschster\Commander\Feature\ComposerManager\Service\ComposerService;

$composerService = new ComposerService('/path/to/project');
$screen = new ComposerManagerScreen($composerService);
$screen->setScreenManager($screenManager);

Features:

  • πŸ“¦ View installed packages
  • πŸ”„ Check for outdated packages
  • πŸ”’ Security audit
  • ⬆️ Update packages
  • βž• Install new packages
  • ❌ Remove packages

Tabs:

  1. Installed - All installed packages with version info
  2. Outdated - Packages that have newer versions available
  3. Security - Packages with known security vulnerabilities

Keyboard Shortcuts:

  • Ctrl+←/β†’ - Switch between tabs
  • ↑↓ - Navigate packages
  • Enter - View package details
  • U - Update selected package
  • D - Remove selected package
  • Tab - Switch between list and details panel

πŸ”§ Customizing Screens

All screens support customization of keyboard shortcuts and behavior:

Example: Custom Global Shortcuts

$app = new Application($symfonyApp);
$screenManager = $app->getScreenManager();

// F2: Switch to Command Browser
$app->registerGlobalShortcut('F2', function ($sm) use ($commandDiscovery, $commandExecutor) {
    $screen = new CommandsScreen($commandDiscovery, $commandExecutor);
    $sm->pushScreen($screen);
});

// F3: Switch to File Browser
$app->registerGlobalShortcut('F3', function ($sm) use ($fileSystem) {
    $screen = new FileBrowserScreen($fileSystem, $sm, getcwd());
    $sm->pushScreen($screen);
});

// F5: Switch to Composer Manager
$app->registerGlobalShortcut('F5', function ($sm) use ($composerService) {
    $screen = new ComposerManagerScreen($composerService);
    $screen->setScreenManager($sm);
    $sm->pushScreen($screen);
});

// F10: Quit
$app->registerGlobalShortcut('F10', function () use ($app) {
    $app->stop();
});

Example: Custom Menu Bar

$globalMenu = new MenuBar([
    'F1' => ' Help',
    'F2' => ' Commands', 
    'F3' => ' Files',
    'F5' => ' Composer',
    'F9' => ' Settings',
    'F10' => ' Quit',
]);
$app->setGlobalMenuBar($globalMenu);

Example: Combining Multiple Screens

// Start with command browser
$welcomeScreen = new CommandsScreen($commandDiscovery, $commandExecutor);

// User can navigate to other screens via shortcuts
$app->registerGlobalShortcut('F3', function ($sm) {
    // Pop all screens and push file browser
    $sm->popUntil(fn($screen) => $screen instanceof FileBrowserScreen);
    
    if (!($sm->getCurrentScreen() instanceof FileBrowserScreen)) {
        $screen = new FileBrowserScreen($fileSystem, $sm, getcwd());
        $sm->pushScreen($screen);
    }
});

$app->run($welcomeScreen);

πŸ“š Creating Custom Screens

Want to create your own screen? Check out these guides:

Quick Example:

use Butschster\Commander\UI\Screen\ScreenInterface;
use Butschster\Commander\Infrastructure\Terminal\Renderer;

final class MyCustomScreen implements ScreenInterface
{
    public function render(Renderer $renderer): void
    {
        $size = $renderer->getSize();
        // Render your content...
    }
    
    public function handleInput(string $key): bool
    {
        // Handle keyboard input...
        return true;
    }
    
    public function getTitle(): string
    {
        return 'My Custom Screen';
    }
    
    // ... implement other required methods
}

🧩 Available Components

Commander provides rich set of UI components:

Display Components

  • ListComponent - Scrollable list with selection
  • TableComponent - Multi-column table with sorting
  • TextDisplay - Scrollable text viewer with word wrap

Input Components

  • FormComponent - Form container with validation
  • TextField - Text input field
  • CheckboxField - Checkbox/toggle
  • ArrayField - Comma-separated array input

Layout Components

  • Panel - Container with border and title
  • Modal - Overlay dialog (info/error/warning/confirm)
  • MenuBar - Top menu bar
  • StatusBar - Bottom status bar with shortcuts
  • TabContainer - Tabbed interface
  • GridLayout - Column-based layout

🎯 Real-World Example

Here's a complete example showing all features together (see the included console file):

#!/usr/bin/env php
<?php

declare(strict_types=1);

require __DIR__ . '/vendor/autoload.php';

use Butschster\Commander\Application;
use Butschster\Commander\Feature\CommandBrowser\Screen\CommandsScreen;
use Butschster\Commander\Feature\CommandBrowser\Service\CommandDiscovery;
use Butschster\Commander\Feature\CommandBrowser\Service\CommandExecutor;
use Butschster\Commander\Feature\ComposerManager\Screen\ComposerManagerScreen;
use Butschster\Commander\Feature\ComposerManager\Service\ComposerService;
use Butschster\Commander\Feature\FileBrowser\Screen\FileBrowserScreen;
use Butschster\Commander\Feature\FileBrowser\Service\FileSystemService;
use Butschster\Commander\UI\Component\Layout\MenuBar;
use Butschster\Commander\UI\Theme\ColorScheme;
use Butschster\Commander\UI\Theme\MidnightTheme;
use Symfony\Component\Console\Application as SymfonyApplication;

// Create Symfony Console Application
$symfonyApp = new SymfonyApplication('My Console Application', '1.0.0');

// Apply theme
ColorScheme::applyTheme(new MidnightTheme());

// Create and configure Commander application
$app = new Application($symfonyApp);
$app->setTargetFps(30);
$screenManager = $app->getScreenManager();

// Create services
$commandDiscovery = new CommandDiscovery($symfonyApp);
$commandExecutor = new CommandExecutor($symfonyApp);
$fileSystem = new FileSystemService();

// Setup global menu bar
$globalMenu = new MenuBar([
    'F1' => ' Help',
    'F2' => ' Commands',
    'F3' => ' Files',
    'F5' => ' Composer',
    'F10' => ' Quit',
]);
$app->setGlobalMenuBar($globalMenu);

// Register global shortcuts for screen switching
$app->registerGlobalShortcut('F2', function ($sm) use ($commandDiscovery, $commandExecutor) {
    // Switch to command browser
    $sm->popUntil(fn($screen) => $screen instanceof CommandsScreen);
    if (!($sm->getCurrentScreen() instanceof CommandsScreen)) {
        $sm->pushScreen(new CommandsScreen($commandDiscovery, $commandExecutor));
    }
});

$app->registerGlobalShortcut('F3', function ($sm) use ($fileSystem) {
    // Switch to file browser
    $sm->popUntil(fn($screen) => $screen instanceof FileBrowserScreen);
    if (!($sm->getCurrentScreen() instanceof FileBrowserScreen)) {
        $sm->pushScreen(new FileBrowserScreen($fileSystem, $sm, getcwd()));
    }
});

$app->registerGlobalShortcut('F5', function ($sm) {
    // Switch to composer manager
    $sm->popUntil(fn($screen) => $screen instanceof ComposerManagerScreen);
    if (!($sm->getCurrentScreen() instanceof ComposerManagerScreen)) {
        $composerService = new ComposerService(getcwd());
        $screen = new ComposerManagerScreen($composerService);
        $screen->setScreenManager($sm);
        $sm->pushScreen($screen);
    }
});

$app->registerGlobalShortcut('F10', function () use ($app) {
    $app->stop();
});

// Start with command browser screen
$welcomeScreen = new CommandsScreen($commandDiscovery, $commandExecutor);
$app->run($welcomeScreen);

This example demonstrates:

  • βœ… All three built-in screens (Commands, Files, Composer)
  • βœ… Global menu bar with function key shortcuts
  • βœ… Screen switching via F2, F3, F5
  • βœ… Proper screen stack management
  • βœ… Service initialization
  • βœ… Theme application

πŸŽ“ Architecture Overview

Project Structure

src/
β”œβ”€β”€ Application.php                      # Main application entry point
β”œβ”€β”€ Feature/                             # Feature modules
β”‚   β”œβ”€β”€ CommandBrowser/                  # Command browser feature
β”‚   β”œβ”€β”€ FileBrowser/                     # File browser feature
β”‚   └── ComposerManager/                 # Composer manager feature
β”œβ”€β”€ Infrastructure/                      # Core infrastructure
β”‚   └── Terminal/
β”‚       β”œβ”€β”€ KeyboardHandler.php         # Keyboard input processing
β”‚       β”œβ”€β”€ Renderer.php                # Double-buffered rendering
β”‚       └── TerminalManager.php         # Terminal control
└── UI/                                  # UI framework
    β”œβ”€β”€ Component/                       # Reusable components
    β”œβ”€β”€ Screen/                          # Screen management
    └── Theme/                           # Color themes

Key Concepts

  1. Screens - Full-screen views (like pages in a web app)
  2. Components - Reusable UI elements (tables, forms, panels)
  3. Double Buffering - Prevents flickering by rendering off-screen first
  4. Event System - Components communicate via callbacks
  5. Theme System - Customizable color schemes

🌟 Use Cases

Commander is perfect for:

  • DevOps Tools - Server management, deployment dashboards
  • CLI Dashboards - System monitoring, log viewers
  • Development Tools - Code generators, project scaffolders
  • Admin Panels - Database managers, configuration editors
  • Interactive Wizards - Multi-step installation processes
  • File Managers - Custom file browsers with preview
  • Package Managers - Dependency management UIs

🀝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.


πŸ“„ License

MIT License. See LICENSE file for details.


πŸ™ Acknowledgments

Inspired by Midnight Commander - the legendary file manager.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Languages