From a436aeac053d3c4d08361ad8583eaf7a5091de04 Mon Sep 17 00:00:00 2001 From: Pratik Bhujel Date: Fri, 25 Sep 2026 15:14:54 +0545 Subject: [PATCH 1/2] Use ext-terminal for dashboard dimensions --- phpstan.neon.dist | 2 ++ src/Prompt/Dashboard.php | 53 ++++++++++++++++++++++++---- stubs/ext-terminal.php | 17 +++++++++ tests/Unit/DashboardTerminalTest.php | 38 ++++++++++++++++++++ 4 files changed, 103 insertions(+), 7 deletions(-) create mode 100644 stubs/ext-terminal.php create mode 100644 tests/Unit/DashboardTerminalTest.php diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 9fdbd28..89cbf5a 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -8,4 +8,6 @@ parameters: - tests - workbench/app - workbench/routes + stubFiles: + - stubs/ext-terminal.php tmpDir: build/phpstan diff --git a/src/Prompt/Dashboard.php b/src/Prompt/Dashboard.php index 06a7391..bea0a49 100644 --- a/src/Prompt/Dashboard.php +++ b/src/Prompt/Dashboard.php @@ -14,6 +14,7 @@ use Chewie\Concerns\Loops; use Chewie\Concerns\SetsUpAndResets; use Illuminate\Support\Collection; +use Io\Terminal\Terminal as NativeTerminal; use Laravel\Prompts\Prompt; use Laravel\Prompts\Terminal; use SoloTerm\Screen\Screen; @@ -208,12 +209,45 @@ public function currentCommand(): Command */ public function getDimensions(): array { + if (($dimensions = $this->nativeDimensions()) !== null) { + return $dimensions; + } + return [ $this->terminal()->cols(), - $this->terminal()->lines() + $this->terminal()->lines(), ]; } + /** + * @return array{0: int, 1: int}|null + */ + protected function nativeDimensions(): ?array + { + if (! $this->hasNativeTerminal()) { + return null; + } + + $size = NativeTerminal::create()->getSize(); + + return $size === false + ? null + : [$size->cols, $size->rows]; + } + + protected function hasNativeTerminal(): bool + { + if (! extension_loaded('terminal') || ! class_exists(NativeTerminal::class, false)) { + return false; + } + + $version = phpversion('terminal'); + + return is_string($version) + && version_compare($version, '1.0.0', '>=') + && version_compare($version, '2.0.0', '<'); + } + public function handleResize(): false { // Debounce rapid resize events (e.g., dragging window edge) @@ -228,14 +262,19 @@ public function handleResize(): false putenv('COLUMNS'); putenv('LINES'); - $terminal = new Terminal; - $terminal->initDimensions(); + $dimensions = $this->nativeDimensions(); - // Put them back in, in case anyone else needs them. - putenv('COLUMNS=' . $terminal->cols()); - putenv('LINES=' . $terminal->lines()); + if ($dimensions === null) { + $terminal = new Terminal; + $terminal->initDimensions(); + $dimensions = [$terminal->cols(), $terminal->lines()]; + } - [$width, $height] = $this->getDimensions(); + [$width, $height] = $dimensions; + + // Put them back in, in case anyone else needs them. + putenv("COLUMNS={$width}"); + putenv("LINES={$height}"); if ($width !== $this->width || $height !== $this->height) { $this->width = $width; diff --git a/stubs/ext-terminal.php b/stubs/ext-terminal.php new file mode 100644 index 0000000..66d5a11 --- /dev/null +++ b/stubs/ext-terminal.php @@ -0,0 +1,17 @@ + + * + * @link https://aaronfrancis.com + * @link https://x.com/aarondfrancis + */ + +namespace SoloTerm\Solo\Tests\Unit; + +use PHPUnit\Framework\Attributes\Test; +use SoloTerm\Solo\Prompt\Dashboard; + +class DashboardTerminalTest extends Base +{ + #[Test] + public function it_prefers_native_terminal_dimensions_when_available(): void + { + $dashboard = new class extends Dashboard + { + public function __construct() + { + // + } + + /** + * @return array{0: int, 1: int}|null + */ + protected function nativeDimensions(): ?array + { + return [132, 43]; + } + }; + + $this->assertSame([132, 43], $dashboard->getDimensions()); + } +} From 84fc76ce834803cc96c8ae9cd2db0c83441aa9dd Mon Sep 17 00:00:00 2001 From: Pratik Bhujel Date: Fri, 25 Sep 2026 15:32:06 +0545 Subject: [PATCH 2/2] Preserve custom dashboard sizing on resize --- src/Prompt/Dashboard.php | 7 ++----- tests/Unit/DashboardTerminalTest.php | 29 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/Prompt/Dashboard.php b/src/Prompt/Dashboard.php index bea0a49..32ff975 100644 --- a/src/Prompt/Dashboard.php +++ b/src/Prompt/Dashboard.php @@ -262,15 +262,12 @@ public function handleResize(): false putenv('COLUMNS'); putenv('LINES'); - $dimensions = $this->nativeDimensions(); - - if ($dimensions === null) { + if ($this->nativeDimensions() === null) { $terminal = new Terminal; $terminal->initDimensions(); - $dimensions = [$terminal->cols(), $terminal->lines()]; } - [$width, $height] = $dimensions; + [$width, $height] = $this->getDimensions(); // Put them back in, in case anyone else needs them. putenv("COLUMNS={$width}"); diff --git a/tests/Unit/DashboardTerminalTest.php b/tests/Unit/DashboardTerminalTest.php index d581efc..7471d9a 100644 --- a/tests/Unit/DashboardTerminalTest.php +++ b/tests/Unit/DashboardTerminalTest.php @@ -35,4 +35,33 @@ protected function nativeDimensions(): ?array $this->assertSame([132, 43], $dashboard->getDimensions()); } + + #[Test] + public function resize_respects_a_get_dimensions_override(): void + { + $dashboard = new class extends Dashboard + { + public function __construct() + { + $this->width = 80; + $this->height = 24; + $this->commands = []; + } + + public function getDimensions(): array + { + return [144, 48]; + } + + protected function nativeDimensions(): ?array + { + return [132, 43]; + } + }; + + $dashboard->handleResize(); + + $this->assertSame(144, $dashboard->width); + $this->assertSame(48, $dashboard->height); + } }