Deleting lines of the terminal using a Symfony command

Published on 2021-08-01 • Modified on 2021-08-01

In this snippet, we see how to delete lines of the terminal using a Symfony command. Symfony 5.1 has introduced a significant change that allows having complete control of the cursor in the terminal thanks to the Symfony\Component\Console\Cursor object. Before this, we could use sections that provide a clear function. We can even do it manually using custom code like the clear() function below.



// src/Command/DeleteLinesDemoCommand.php

namespace App\Command;

use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Cursor;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

    name: self::NAME,
    description: self::DESCRIPTION,
final class DeleteLinesDemoCommand extends BaseCommand
    public const string CMD = 'delete-lines-demo';

    private const string NAME = self::NAMESPACE.':'.self::CMD;
    private const string DESCRIPTION = 'Demo on how to delete lines of the terminal.';

    protected function configure(): void
        [$desc, $class] = [self::NAME, self::class];


<info>%command.full_name% -vv</info>

<info>%command.full_name% --env=prod --no-debug</info>

    protected function execute(InputInterface $input, OutputInterface $output): int
        $io = new SymfonyStyle($input, $output);
        $io->write('$output: '.get_debug_type($output));

        if ($output instanceof ConsoleOutputInterface) {
            // @codeCoverageIgnoreStart
            $section = $output->section();
            $section->write('Dummy section I will clear at next line');
            // @codeCoverageIgnoreEnd

        $io->write('delete me!');
        $cursor = new Cursor($output);
        $io->write('delete me 2!');

        $io->writeln('delete me 3!');

        $io->writeln('delete me 4!');
        $io->writeln('delete me 5!');
        $this->clear($output, 2);


        return self::SUCCESS;

     * @see ConsoleSectionOutput::popStreamContentUntilCurrentSection
    private function clear(OutputInterface $output, int $lines = 1): void
        // move cursor up n lines

        // erase to end of screen

 ≪ this.showUnitTest ? this.trans.hide_unit_test : this.trans.show_unit_test ≫  More on Stackoverflow   Read the doc  More on the web  Random snippet

  Work with me!



namespace App\Tests\Integration\Controller\Snippets;

use App\Command\BaseCommand;
use App\Command\DeleteLinesDemoCommand;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Console\Tester\CommandTester;

final class Snippet157Test extends KernelTestCase
     * @see DeleteLinesDemoCommand::execute
    public function testSnippet157(): void
        $app = new Application(self::createKernel());
        $command = $app->find(BaseCommand::NAMESPACE.':'.DeleteLinesDemoCommand::CMD);
        $commandTester = new CommandTester($command);
            'command' => $command->getName(),

        self::assertStringContainsString('delete', $commandTester->getDisplay(), 'delete');

        // 🤔 can seem weird but yes the delete string is found, it is not displayed
        // because of the ANSI output.
        // Here is the real content of the output (you must log it in a file)

delete me!delete me 2!delete me 3!

delete me 4!
delete me 5!

 [OK] Done!