Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

dotnet-suggest: Don't duplicate registration entries, don't return false matches, and be more careful about casing

オープン
#2,749 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

@zjdangge がすでに取り組んでいます。

2026年10月15日 から。

  • #2859 @zjdangge による — オープン

評価

難易度
3/5
見積もり時間
1〜2日
初心者へのやさしさ
45/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
停滞
技術スタック
csharp
領域
cli

調査の方向性

dotnet-suggest の登録と FileSuggestionRegistration.FindRegistration() から始め、特に登録パスとプレフィックス検索ループを確認します。重複エントリ、最初の一致と最後の一致、偽のプレフィックス、プラットフォーム間の大文字と小文字の扱いについて、現在の動作を検証します。完了条件は、登録で重複を回避し、検索が意図したエントリのみを返して不要に継続せず、大文字と小文字の扱いが選択したプラットフォームの動作に従うことです。

索引モデルが issue の本文から書いたものです。

説明

dotnet-suggest is pretty simple in its handling of registrations.

It's just a utf-8 text file with one executable path per line that gets scanned line by line from start to end when searching, returning the last "match" found (which is also just a StartsWith match, and thus can return false positives), and which blindly appends to the file on registration, so long as the provided path exists. It also performs its search explicitly as StringComparison.OrdinalIgnoreCase.

These have a few undesirable consequences:

  1. Entries are duplicated if the same value is given to dotnet-suggest register --command-path <command-path>
  2. The search for a match continues even after a match is found.
  3. False matches can be returned, such as if there is a registration for /path/to/file and /path/to/fileThatIsNotTheOneYouWant, which will return the last of those two entries, even if it is /path/to/fileThatIsNotTheOneYouWant but it was searching for /path/to/file.
  4. The StringComparison.OrdinalIgnoreCase string comparison can result in invalid completions on case-sensitive file systems, which could lead to failure to launch the target to retrieve the completions for it, if the command line text does not match the case of the actual executable but does match the case of the entry in the list. Further, if two files differ in name only by case (which is also legal on Windows, BTW), or if you have a directory structure that looks like the following example, false matches can also occur:
/a/b    <-- This is a file named b in directory /a
/a/B/c  <-- This is a file named c in directory /a/B/

Searching for /a/b will, with the current code, return the second entry as the match, due to both the case-insensitive search and the last-one-wins match strategy.

(1) can be avoided at registration time by just making sure the entry doesn't already exist. It doesn't really matter if the registration operation is made more expensive by doing so, because registration isn't being done frequently, and isn't being done in a context where a brief delay to perform that scan is objectionable.

(2) and (3) can be resolved by returning as soon as a match is found.

It seems to me that it is most important for it to be optimized around the search case, since that is what gets invoked more frequently and in a context wherein the user expects as little delay as possible.

(4) just needs to either have an OSPlatform guard to perform case-sensitive searches on not-windows and case-insensitive searches on Windows, or else simply always perform StringComparison.Ordinal searches on all platforms.[^SensitiveSubject]

There are plenty of other pretty low-complexity ways to make it even smarter than the above simplistic suggestions, such as maintaining the list in sorted order when registering and then performing searches by binary search, and/or by using fixed-width lines to make seeking within the file possible without having to read the whole thing into memory (which would make doing a binary search even more efficient for example). But even just de-duplicating it and returning the first prefix match rather than scanning the entire file and then returning the last prefix match indiscriminately would be improvements over the current implementation, and actually result in fewer lines of code than are currently there, since that temporary string variable named completionTarget in FileSuggestionRegistration.FindRegistration() would go away entirely, along with the extra check for that variable being null that is after the loop.

[^SensitiveSubject]: Windows is case-aware and file naming is case sensitive in Windows, so this would be the most technically correct (the best kind), though of course there is the obvious argument that, since everything else about Windows is case-lenient, enforcing case-sensitivity could be confusing, due to user expectations.

主要言語
C#
スター
3.7k
フォーク
434
平均マージ
6時間 27分
マージ済み PR(30日)
2

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

dotnet/command-line-api のほかの issue

dotnet/command-line-api の issue をすべて見る

似ている issue

C# の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。