summaryrefslogtreecommitdiffstats
path: root/vendor/gipfl/cli/src/TtyMode.php
blob: 8b9c88478df076b94b353e416e0906fc30be32b2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
<?php

namespace gipfl\Cli;

use function escapeshellarg;
use function register_shutdown_function;
use function rtrim;
use function shell_exec;

class TtyMode
{
    protected $originalMode;

    public function enableCanonicalMode()
    {
        $this->enableFeature('icanon');

        return $this;
    }

    public function disableCanonicalMode()
    {
        $this->disableFeature('icanon');

        return $this;
    }

    public function enableFeature(...$feature)
    {
        $this->preserve();
        $cmd = 'stty ';
        foreach ($feature as $f) {
            $cmd .= escapeshellarg($f);
        }

        shell_exec($cmd);
    }

    public function disableFeature(...$feature)
    {
        $this->preserve();
        $cmd = 'stty';
        foreach ($feature as $f) {
            $cmd .= ' -' . escapeshellarg($f);
        }

        shell_exec($cmd);
    }

    public function getCurrentMode()
    {
        return rtrim(shell_exec('stty -g'), PHP_EOL);
    }

    /**
     * Helper allowing to call stty only once for the mose used flags, icanon and echo
     * @param bool $echo
     * @return $this
     */
    public function setPreferredMode($echo = true)
    {
        $this->preserve();
        if ($echo) {
            $this->disableFeature('icanon');
        } else {
            $this->disableFeature('icanon', 'echo');
        }

        return $this;
    }

    /**
     * @internal
     */
    public function preserve($force = false)
    {
        if ($force || $this->originalMode === null) {
            $this->originalMode = $this->getCurrentMode();
            register_shutdown_function([$this, 'restore']);
        }

        return $this;
    }

    /**
     * @internal
     */
    public function restore()
    {
        if ($this->originalMode) {
            shell_exec('stty ' . escapeshellarg($this->originalMode));
            $this->originalMode = null;
        }
    }
}