Hacktoberfest 2026 : les issues que les mainteneurs ont marquées pour octobre, ouvertes et accessibles aux débutants. Parcourir les issues Hacktoberfest

fix: Wrong completion context for chained commands in zsh

Ouverte
#139 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Évaluation

Difficulté
3/5
Temps estimé
1-2 jours
Accessibilité débutants
82/100
Type d'issue
Bug
Clarté
Clairement spécifiée
Activité
Active
Stack technique
dart, zsh
Domaine
cli

Piste de recherche

Start with lib/src/installer/shell_completion_configuration.dart and CompletionState.fromEnvironment, which the issue identifies as passing and reading the completion context. Check the existing completion tests and how the words passed after completion -- relate to COMP_CWORD. Done means commands after |, && or ; suggest the current command’s options, while existing bash completion still works.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

bug
Description

Thank you for this cool lib! I'm facing a minor bug when used with zsh.

In zsh, completing a command that isn't at the start of the command line (after |, && or ;) uses the wrong context. The zsh script passes COMP_LINE="$BUFFER", which is zsh's whole edit buffer, and CompletionState.fromEnvironment reads the arguments from COMP_LINE. So everything typed before the current command is treated as CLI arguments.

Steps To Reproduce

Take a CLI my_cli built on CompletionCommandRunner, with commands foo and bar that have different options, and install its completion in zsh with my_cli install-completion-files.

  1. my_cli foo | my_cli bar <TAB> suggests foo's options. The request is parsed as foo | my_cli bar '', so foo is taken as the command being completed.
  2. cd somewhere && my_cli bar <TAB> suggests nothing, so zsh falls back to file names.

Without a shell, this is the request zsh sends for step 1:

ZSH_NAME=zsh COMP_LINE='my_cli foo | my_cli bar ' COMP_POINT=24 COMP_CWORD=2 \
  my_cli completion -- my_cli bar ''

It prints foo's options.

Expected Behavior

A command after |, && or ; completes the same way as at the start of the line. Both my_cli foo | my_cli bar <TAB> and cd somewhere && my_cli bar <TAB> suggest bar's options, just like my_cli bar <TAB>. Bash already behaves this way.

Additional Context

Cause

  • The zsh template in lib/src/installer/shell_completion_configuration.dart runs COMP_CWORD="$((CURRENT-1))" COMP_LINE="$BUFFER" COMP_POINT="$CURSOR" … completion -- "${words[@]}". $BUFFER is the whole edit buffer, while $words and $CURRENT cover only the current command.
  • CompletionState.fromEnvironment takes the arguments from COMP_LINE (line.trimLeft().split(' ').skip(1)) and ignores the words passed after completion --.
  • Bash isn't affected, because bash itself limits COMP_LINE to the current command. With bash 3.2, echo x | mycmd a <TAB> sets COMP_LINE to mycmd a.

Suggested fix

Build the arguments from the words the scripts already pass after completion --, up to COMP_CWORD, instead of from COMP_LINE. Both scripts pass only the current command's words there, so this fixes zsh without changing the scripts or making users reinstall them.

Workaround

Until this is fixed, a CLI can narrow COMP_LINE itself before the request is handled, in its CompletionCommandRunner subclass:

@override
Future<int?> runCommand(ArgResults topLevelResults) {
  final command = topLevelResults.command;
  if (command?.name == HandleCompletionRequestCommand.commandName) {
    final words = command!.rest; // the words after `completion --`
    final environment = Platform.environment;
    final cword = int.tryParse(environment['COMP_CWORD'] ?? '');
    if (cword != null && cword >= 0 && cword < words.length) {
      final line = words.take(cword + 1).join(' ');
      environmentOverride = {...environment, 'COMP_LINE': line, 'COMP_POINT': '${line.length}'};
    }
  }
  return super.runCommand(topLevelResults);
}

Environment

  • cli_completion 0.6.0
  • Dart 3.13.3
  • zsh 5.9, macOS (arm64)
Langage dominant
Dart
Étoiles
54
Forks
6
Merge moyen
24 min
PR mergées (30 j)
1

Préparer son environnement

  • Aucun Dockerfile ni fichier Docker Compose
  • Propose un modèle de pull request
  • Aucun guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de VeryGoodOpenSource/cli_completion

Toutes les issues de VeryGoodOpenSource/cli_completion

Issues similaires

Plus d'issues Dart

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.