8000 [Console] Support quotes un bash completion · symfony/symfony@55aa9b7 · GitHub
[go: up one dir, main page]

Skip to content

Commit 55aa9b7

Browse files
committed
[Console] Support quotes un bash completion
1 parent e4202a0 commit 55aa9b7

File tree

6 files changed

+29
-11
lines changed

6 files changed

+29
-11
lines changed

src/Symfony/Component/Console/Command/CompleteCommand.php

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Symfony\Component\Console\Completion\CompletionInput;
1515
use Symfony\Component\Console\Completion\CompletionSuggestions;
1616
use Symfony\Component\Console\Completion\Output\BashCompletionOutput;
17+
use Symfony\Component\Console\Completion\Output\CompletionOutputInterface;
1718
use Symfony\Component\Console\Exception\CommandNotFoundException;
1819
use Symfony\Component\Console\Exception\ExceptionInterface;
1920
use Symfony\Component\Console\Input\InputInterface;
@@ -121,6 +122,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
121122
}
122123
}
123124

125+
/** @var CompletionOutputInterface $completionOutput */
124126
$completionOutput = new $completionOutput();
125127

126128
$this->log('<info>Suggestions:</>');
@@ -132,7 +134,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
132134
$this->log(' <comment>No suggestions were provided</>');
133135
}
134136

135-
$completionOutput->write($suggestions, $output);
137+
$completionOutput->write($suggestions, $completionInput, $output);
136138
} catch (\Throwable $e) {
137139
$this->log([
138140
'<error>Error!</error>',
@@ -156,10 +158,7 @@ private function createCompletionInput(InputInterface $input): CompletionInput
156158
throw new \RuntimeException('The "--current" option must be set and it must be an integer.');
157159
}
158160

159-
$completionInput = CompletionInput::fromTokens(array_map(
160-
function (string $i): string { return trim($i, "'"); },
161-
$input->getOption('input')
162-
), (int) $currentIndex);
161+
$completionInput = CompletionInput::fromTokens($input->getOption('input'), (int) $currentIndex);
163162

164163
try {
165164
$completionInput->bind($this->getApplication()->getDefinition());

src/Symfony/Component/Console/Completion/CompletionInput.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ public function bind(InputDefinition $definition): void
109109
// complete argument value
110110
$this->completionType = self::TYPE_ARGUMENT_VALUE;
111111

112+
// shell cannot interpret quotes
113+
$trimQuotes = function ($value): string {
114+
return trim($value, '\'"');
115+
};
112116
$arguments = $this->getArguments();
113117
foreach ($arguments as $argumentName => $argumentValue) {
114118
if (null === $argumentValue) {
@@ -117,8 +121,10 @@ public function bind(InputDefinition $definition): void
117121

118122
$this->completionName = $argumentName;
119123
if (\is_array($argumentValue)) {
124+
$this->setArgument($argumentName, array_map($trimQuotes, $argumentValue));
120125
$this->completionValue = $argumentValue ? $argumentValue[array_key_last($argumentValue)] : null;
121126
} else {
127+
$this->setArgument($argumentName, $trimQuotes($argumentValue));
122128
$this->completionValue = $argumentValue;
123129
}
124130
}

src/Symfony/Component/Console/Completion/Output/BashCompletionOutput.php

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\Console\Completion\Output;
1313

14+
use Symfony\Component\Console\Completion\CompletionInput;
1415
use Symfony\Component\Console\Completion\CompletionSuggestions;
1516
use Symfony\Component\Console\Output\OutputInterface;
1617

@@ -19,16 +20,27 @@
1920
*/
2021
class BashCompletionOutput implements CompletionOutputInterface
2122
{
22-
public function write(CompletionSuggestions< 6D40 /span> $suggestions, OutputInterface $output): void
23+
public function write(CompletionSuggestions $suggestions, CompletionInput $input, OutputInterface $output): void
2324
{
2425
$options = [];
2526
foreach ($suggestions->getOptionSuggestions() as $option) {
2627
$options[] = '--'.$option->getName();
2728
}
2829
$output->write(implode(' ', $options));
2930

30-
$values = array_map(function ($value) {
31-
return str_replace('\\', '\\\\\\\\', $value);
31+
// add quotes to the suggestion if current value starts with a quote
32+
$completionValue = $input->getCompletionValue();
33+
$quote = in_array($completionValue[0] ?? null, ['"', '\''], true) ? $completionValue[0] : null;
34+
35+
$values = array_map(function ($value) use ($completionValue, $quote) {
36+
if (null !== $quote) {
37+
$value = $quote . $value . $quote;
38+
} elseif (str_contains($value, '\\')) {
39+
// without quote, more escaping is necessary
40+
$value = str_replace('\\', '\\\\', $value);
41+
}
42+
43+
return escapeshellarg($value);
3244
}, $suggestions->getValueSuggestions());
3345

3446
$output->writeln(implode(' ', $values));

src/Symfony/Component/Console/Completion/Output/CompletionOutputInterface.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\Console\Completion\Output;
1313

14+
use Symfony\Component\Console\Completion\CompletionInput;
1415
use Symfony\Component\Console\Completion\CompletionSuggestions;
1516
use Symfony\Component\Console\Output\OutputInterface;
1617

@@ -21,5 +22,5 @@
2122
*/
2223
interface CompletionOutputInterface
2324
{
24-
public function write(CompletionSuggestions $suggestions, OutputInterface $output): void;
25+
public function write(CompletionSuggestions $suggestions, CompletionInput $input, OutputInterface $output): void;
2526
}

src/Symfony/Component/Console/Resources/completion.bash

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ _sf_{{ COMMAND_NAME }}() {
1616

1717
local completecmd=("$sf_cmd" "_complete" "-sbash" "-c$cword" "-S{{ VERSION }}")
1818
for w in ${words[@]}; do
19-
completecmd+=($(printf -- '-i%b' "$w"))
19+
completecmd+=($(printf -- "-i%b" "$w"))
2020
done
2121

2222
local sfcomplete

src/Symfony/Component/Console/Tests/Completion/CompletionInputTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* file that was distributed with this source code.
1010
*/
1111

12-
namespace Symfony\Component\Console\Tests\Command;
12+
namespace Symfony\Component\Console\Tests\Completion;
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\Console\Completion\CompletionInput;

0 commit comments

Comments
 (0)
0