CompletionCommand.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. <?php
  2. namespace Stecman\Component\Symfony\Console\BashCompletion;
  3. use Symfony\Component\Console\Command\Command as SymfonyCommand;
  4. use Symfony\Component\Console\Input\InputDefinition;
  5. use Symfony\Component\Console\Input\InputInterface;
  6. use Symfony\Component\Console\Input\InputOption;
  7. use Symfony\Component\Console\Output\OutputInterface;
  8. class CompletionCommand extends SymfonyCommand
  9. {
  10. /**
  11. * @var CompletionHandler
  12. */
  13. protected $handler;
  14. protected function configure()
  15. {
  16. $this
  17. ->setName('_completion')
  18. ->setDefinition($this->createDefinition())
  19. ->setDescription('BASH completion hook.')
  20. ->setHelp(<<<END
  21. To enable BASH completion, run:
  22. <comment>eval `[program] _completion -g`</comment>.
  23. Or for an alias:
  24. <comment>eval `[program] _completion -g -p [alias]`</comment>.
  25. END
  26. );
  27. }
  28. /**
  29. * {@inheritdoc}
  30. */
  31. public function getNativeDefinition()
  32. {
  33. return $this->createDefinition();
  34. }
  35. protected function execute(InputInterface $input, OutputInterface $output)
  36. {
  37. $this->handler = new CompletionHandler($this->getApplication());
  38. $handler = $this->handler;
  39. if ($input->getOption('generate-hook')) {
  40. global $argv;
  41. $program = $argv[0];
  42. $factory = new HookFactory();
  43. $alias = $input->getOption('program');
  44. $multiple = (bool)$input->getOption('multiple');
  45. // When completing for multiple apps having absolute path in the alias doesn't make sense.
  46. if (!$alias && $multiple) {
  47. $alias = basename($program);
  48. }
  49. $hook = $factory->generateHook(
  50. $input->getOption('shell-type') ?: $this->getShellType(),
  51. $program,
  52. $alias,
  53. $multiple
  54. );
  55. $output->write($hook, true);
  56. } else {
  57. $handler->setContext(new EnvironmentCompletionContext());
  58. $output->write($this->runCompletion(), true);
  59. }
  60. }
  61. /**
  62. * Run the completion handler and return a filtered list of results
  63. *
  64. * @deprecated - This will be removed in 1.0.0 in favour of CompletionCommand::configureCompletion
  65. *
  66. * @return string[]
  67. */
  68. protected function runCompletion()
  69. {
  70. $this->configureCompletion($this->handler);
  71. return $this->handler->runCompletion();
  72. }
  73. /**
  74. * Configure the CompletionHandler instance before it is run
  75. *
  76. * @param CompletionHandler $handler
  77. */
  78. protected function configureCompletion(CompletionHandler $handler)
  79. {
  80. // Override this method to configure custom value completions
  81. }
  82. /**
  83. * Determine the shell type for use with HookFactory
  84. *
  85. * @return string
  86. */
  87. protected function getShellType()
  88. {
  89. if (!getenv('SHELL')) {
  90. throw new \RuntimeException('Could not read SHELL environment variable. Please specify your shell type using the --shell-type option.');
  91. }
  92. return basename(getenv('SHELL'));
  93. }
  94. protected function createDefinition()
  95. {
  96. return new InputDefinition(array(
  97. new InputOption(
  98. 'generate-hook',
  99. 'g',
  100. InputOption::VALUE_NONE,
  101. 'Generate BASH code that sets up completion for this application.'
  102. ),
  103. new InputOption(
  104. 'program',
  105. 'p',
  106. InputOption::VALUE_REQUIRED,
  107. "Program name that should trigger completion\n<comment>(defaults to the absolute application path)</comment>."
  108. ),
  109. new InputOption(
  110. 'multiple',
  111. 'm',
  112. InputOption::VALUE_NONE,
  113. "Generated hook can be used for multiple applications."
  114. ),
  115. new InputOption(
  116. 'shell-type',
  117. null,
  118. InputOption::VALUE_OPTIONAL,
  119. 'Set the shell type (zsh or bash). Otherwise this is determined automatically.'
  120. ),
  121. ));
  122. }
  123. }