Hacktoberfest 2026: die Issues, die Maintainer für den Oktober markiert haben – offen und einsteigerfreundlich. Hacktoberfest-Issues durchsuchen

fix: Wrong completion context for chained commands in zsh

Offen
#139 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Bewertung

Schwierigkeit
3/5
Geschätzter Aufwand
1-2 Tage
Anfängerfreundlichkeit
82/100
Issue-Typ
Bug
Klarheit
Klar beschrieben
Aktivitätsstatus
Aktiv
Tech-Stack
dart, zsh
Bereich
cli

Rechercherichtung

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.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

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)
Vorherrschende Sprache
Dart
Sterne
54
Forks
6
Ø Merge
24 Min.
Gemergte PRs (30 T.)
1

Entwicklungsumgebung

  • Kein Dockerfile und keine Docker-Compose-Datei
  • Hat eine Pull-Request-Vorlage
  • Kein Beitragsleitfaden

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus VeryGoodOpenSource/cli_completion

Alle Issues in VeryGoodOpenSource/cli_completion

Ähnliche Issues

Weitere Issues zu Dart

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.