<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Tarek</title>
    <description>The latest articles on DEV Community by Tarek (@najem).</description>
    <link>https://dev.to/najem</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3915981%2F63467278-3e16-435a-a34d-f21be70c5a9a.png</url>
      <title>DEV Community: Tarek</title>
      <link>https://dev.to/najem</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/najem"/>
    <language>en</language>
    <item>
      <title>Jeninnet.FileQuery</title>
      <dc:creator>Tarek</dc:creator>
      <pubDate>Wed, 03 Jun 2026 06:22:43 +0000</pubDate>
      <link>https://dev.to/najem/jeninnetfilequery-460l</link>
      <guid>https://dev.to/najem/jeninnetfilequery-460l</guid>
      <description>&lt;h1&gt;
  
  
  Building a Deterministic File Query Engine for .NET
&lt;/h1&gt;

&lt;h2&gt;
  
  
  How Jeninnet.FileQuery Combines GitIgnore, Glob, and Regex Into a Predictable High-Performance Query Engine
&lt;/h2&gt;

&lt;p&gt;Building a Deterministic File Query Engine for .NET&lt;br&gt;
Technical Whitepaper&lt;br&gt;
Version 1.0&lt;br&gt;
Author: Tarek Najem&lt;br&gt;
GitHub: &lt;a href="https://github.com/TarekNajem04/Jeninnet.FileQuery" rel="noopener noreferrer"&gt;https://github.com/TarekNajem04/Jeninnet.FileQuery&lt;/a&gt;&lt;br&gt;
NuGet: &lt;a href="https://www.nuget.org/packages/Jeninnet.FileQuery" rel="noopener noreferrer"&gt;https://www.nuget.org/packages/Jeninnet.FileQuery&lt;/a&gt;&lt;br&gt;
License: MIT&lt;/p&gt;


&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
Jeninnet.FileQuery

&lt;ul&gt;
&lt;li&gt;Table of Contents&lt;/li&gt;
&lt;li&gt;1. Introduction&lt;/li&gt;
&lt;li&gt;2. The Problem With Traditional File Matching&lt;/li&gt;
&lt;li&gt;2.1 Glob-only libraries&lt;/li&gt;
&lt;li&gt;2.2 Regular expression libraries&lt;/li&gt;
&lt;li&gt;2.3 GitIgnore-inspired libraries&lt;/li&gt;
&lt;li&gt;3. Deterministic Rule Evaluation&lt;/li&gt;
&lt;li&gt;4. The Pattern Language&lt;/li&gt;
&lt;li&gt;4.1 GitIgnore Patterns&lt;/li&gt;
&lt;li&gt;4.2 Glob Patterns&lt;/li&gt;
&lt;li&gt;4.3 Regular Expression Patterns&lt;/li&gt;
&lt;li&gt;4.4 POSIX Character Classes&lt;/li&gt;
&lt;li&gt;5. Architecture&lt;/li&gt;
&lt;li&gt;5.1 Separation of Concerns&lt;/li&gt;
&lt;li&gt;5.2 The Compilation Pipeline&lt;/li&gt;
&lt;li&gt;5.3 The HybridPathMatcher&lt;/li&gt;
&lt;li&gt;5.4 Traversal&lt;/li&gt;
&lt;li&gt;5.5 Path Normalization&lt;/li&gt;
&lt;li&gt;6. Performance&lt;/li&gt;
&lt;li&gt;6.1 Zero-Allocation Hot Path&lt;/li&gt;
&lt;li&gt;6.2 Benchmark Results&lt;/li&gt;
&lt;li&gt;6.3 Compilation Pipeline Allocations&lt;/li&gt;
&lt;li&gt;7. Getting Started&lt;/li&gt;
&lt;li&gt;7.1 Installation&lt;/li&gt;
&lt;li&gt;7.2 Basic Usage&lt;/li&gt;
&lt;li&gt;7.3 Pattern-Based Filtering&lt;/li&gt;
&lt;li&gt;7.4 Hybrid Pattern Mixing&lt;/li&gt;
&lt;li&gt;7.5 Async Enumeration&lt;/li&gt;
&lt;li&gt;7.6 Dependency Injection&lt;/li&gt;
&lt;li&gt;7.7 Command-Line Integration&lt;/li&gt;
&lt;li&gt;8. Package Reference&lt;/li&gt;
&lt;li&gt;Supported Targets&lt;/li&gt;
&lt;li&gt;9. Design Goals and Non-Goals&lt;/li&gt;
&lt;li&gt;Goals&lt;/li&gt;
&lt;li&gt;Non-Goals&lt;/li&gt;
&lt;li&gt;10. Conclusion&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  1. Introduction
&lt;/h2&gt;

&lt;p&gt;Every non-trivial software system eventually encounters the same deceptively simple task: finding files.&lt;br&gt;
Build systems search for source files. Backup tools scan directories to determine what has changed.&lt;br&gt;
Code analyzers walk entire repositories. Log processors filter terabytes of archived data.&lt;/p&gt;

&lt;p&gt;At first glance, file discovery appears trivial. Operating systems provide directory enumeration APIs, and many environments include globbing utilities.&lt;br&gt;
But once a project grows, developers discover deeper issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pattern languages behave inconsistently.&lt;/li&gt;
&lt;li&gt;Traversal becomes expensive at scale.&lt;/li&gt;
&lt;li&gt;Rule ordering is unclear.&lt;/li&gt;
&lt;li&gt;Pattern syntaxes cannot easily coexist.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These challenges led to the creation of Jeninnet.FileQuery, a library that treats file discovery as a first-class architectural problem.&lt;/p&gt;


&lt;h2&gt;
  
  
  2. The Problem With Traditional File Matching
&lt;/h2&gt;

&lt;p&gt;Most libraries approach file matching from one of three directions.&lt;/p&gt;
&lt;h3&gt;
  
  
  2.1 Glob-only libraries
&lt;/h3&gt;

&lt;p&gt;Glob patterns are simple and familiar.&lt;br&gt;
However, limitations appear when rule sets grow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No rule ordering&lt;/li&gt;
&lt;li&gt;No negation&lt;/li&gt;
&lt;li&gt;No mixing with regex&lt;/li&gt;
&lt;li&gt;No hierarchical semantics&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  2.2 Regular expression libraries
&lt;/h3&gt;

&lt;p&gt;Regex is expressive but not suited for hierarchical filesystem rules.&lt;br&gt;
Patterns become unreadable and difficult to maintain.&lt;/p&gt;
&lt;h3&gt;
  
  
  2.3 GitIgnore-inspired libraries
&lt;/h3&gt;

&lt;p&gt;GitIgnore introduces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rule ordering&lt;/li&gt;
&lt;li&gt;Negation&lt;/li&gt;
&lt;li&gt;Directory-aware semantics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But these libraries rarely allow mixing GitIgnore, Glob, and Regex in the same rule set.&lt;/p&gt;

&lt;p&gt;The deeper issue is not syntax but evaluation order.&lt;br&gt;
Ambiguities lead to unpredictable results.&lt;/p&gt;


&lt;h2&gt;
  
  
  3. Deterministic Rule Evaluation
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Jeninnet.FileQuery&lt;/strong&gt; adopts a simple and explicit rule model:&lt;/p&gt;

&lt;p&gt;Patterns are evaluated sequentially, and the last matching rule determines the final result.&lt;/p&gt;

&lt;p&gt;Example rule set:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;**           # Exclude everything
!*.log       # Include all .log files
data.log     # Exclude this specific file again
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Evaluation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rule 1: exclude all files&lt;/li&gt;
&lt;li&gt;Rule 2: include files ending in .log&lt;/li&gt;
&lt;li&gt;Rule 3: exclude data.log specifically&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Final result:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;data.log is excluded&lt;/li&gt;
&lt;li&gt;all other .log files are included&lt;/li&gt;
&lt;li&gt;all other files remain excluded&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This deterministic model eliminates ambiguity and ensures predictable behavior.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. The Pattern Language
&lt;/h2&gt;

&lt;p&gt;Jeninnet.FileQuery supports three pattern dialects that can coexist in the same rule set:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitIgnore patterns&lt;/li&gt;
&lt;li&gt;Glob patterns&lt;/li&gt;
&lt;li&gt;Regular expressions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The engine automatically classifies each pattern and routes it to the correct matcher.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.1 GitIgnore Patterns
&lt;/h3&gt;

&lt;p&gt;GitIgnore patterns are the default and most expressive for hierarchical rules.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Syntax&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;**&lt;/td&gt;
&lt;td&gt;Match zero or more path segments&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;*&lt;/td&gt;
&lt;td&gt;Match any characters within one segment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;?&lt;/td&gt;
&lt;td&gt;Match exactly one character&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;!&lt;/td&gt;
&lt;td&gt;Negate the pattern&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;/pattern&lt;/td&gt;
&lt;td&gt;Anchor to root&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pattern/&lt;/td&gt;
&lt;td&gt;Directory-only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;[abc]&lt;/td&gt;
&lt;td&gt;Character set&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;[a-z]&lt;/td&gt;
&lt;td&gt;Character range&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;[!abc]&lt;/td&gt;
&lt;td&gt;Negated set&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;[[:digit:]]&lt;/td&gt;
&lt;td&gt;POSIX digit class&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;**               # exclude everything
!src/**/.cs      # include C# files under src
src/obj/**       # exclude obj
src/bin/**       # exclude bin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.2 Glob Patterns
&lt;/h3&gt;

&lt;p&gt;Glob patterns follow classical Unix rules and are always anchored.&lt;/p&gt;

&lt;p&gt;Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*.cs
**/*.cs
data/??.log
report.[0-9].txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Negation is not supported in glob patterns.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.3 Regular Expression Patterns
&lt;/h3&gt;

&lt;p&gt;Regex patterns are prefixed with &lt;code&gt;r:&lt;/code&gt; and evaluated against the full normalized path.&lt;/p&gt;

&lt;p&gt;Examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;r:^src/.*\.cs$
r:^data_\d{4}\.log$
r:^(?!.*test).*\.dll$
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.4 POSIX Character Classes
&lt;/h3&gt;

&lt;p&gt;Supported inside &lt;code&gt;[: :]&lt;/code&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Class&lt;/th&gt;
&lt;th&gt;Matches&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;[:digit:]&lt;/td&gt;
&lt;td&gt;0–9&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;[:alpha:]&lt;/td&gt;
&lt;td&gt;a–z, A–Z&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;[:alnum:]&lt;/td&gt;
&lt;td&gt;digits and letters&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;[:space:]&lt;/td&gt;
&lt;td&gt;whitespace&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;[:upper:]&lt;/td&gt;
&lt;td&gt;A–Z&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;[:lower:]&lt;/td&gt;
&lt;td&gt;a–z&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;[:xdigit:]&lt;/td&gt;
&lt;td&gt;hex digits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;[:punct:]&lt;/td&gt;
&lt;td&gt;punctuation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;**
![[:digit:]]*.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Architecture
&lt;/h2&gt;

&lt;h3&gt;
  
  
  5.1 Separation of Concerns
&lt;/h3&gt;

&lt;p&gt;The engine separates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pattern compilation&lt;/li&gt;
&lt;li&gt;Filesystem traversal&lt;/li&gt;
&lt;li&gt;Matching execution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each layer is isolated and enforced by architecture tests.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.2 The Compilation Pipeline
&lt;/h3&gt;

&lt;p&gt;Patterns pass through four phases:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Phase&lt;/th&gt;
&lt;th&gt;Responsibility&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Lexical invariant&lt;/td&gt;
&lt;td&gt;Validate raw text&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PatternScanner&lt;/td&gt;
&lt;td&gt;Tokenize into tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Structural invariants&lt;/td&gt;
&lt;td&gt;Validate token structure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Semantic invariants&lt;/td&gt;
&lt;td&gt;Apply dialect transforms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The scanner is purely lexical; semantics are applied later for clarity and testability.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.3 The HybridPathMatcher
&lt;/h3&gt;

&lt;p&gt;The matcher coordinates three sub-matchers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitIgnoreInstructionMatcher&lt;/li&gt;
&lt;li&gt;GlobInstructionMatcher&lt;/li&gt;
&lt;li&gt;RegexInstructionMatcher&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Routing is precomputed, so evaluation is fast and allocation-free.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.4 Traversal
&lt;/h3&gt;

&lt;p&gt;Supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Depth-first traversal&lt;/li&gt;
&lt;li&gt;Breadth-first traversal&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Options include recursion depth, symlink policy, case sensitivity, and error handling.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.5 Path Normalization
&lt;/h3&gt;

&lt;p&gt;All paths are normalized:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Forward slashes&lt;/li&gt;
&lt;li&gt;Collapsed duplicates&lt;/li&gt;
&lt;li&gt;Preserved UNC roots&lt;/li&gt;
&lt;li&gt;Uppercased drive letters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This ensures cross-platform consistency.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Performance
&lt;/h2&gt;

&lt;p&gt;Jeninnet.FileQuery is designed for high performance, especially in large directory trees and complex rule sets.&lt;/p&gt;

&lt;h3&gt;
  
  
  6.1 Zero-Allocation Hot Path
&lt;/h3&gt;

&lt;p&gt;The engine ensures that pattern matching produces zero heap allocations in the hot path.&lt;/p&gt;

&lt;p&gt;Before optimization:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;patterns&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This caused boxing of the enumerator (~40 bytes per evaluation).&lt;/p&gt;

&lt;p&gt;After optimization:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;patterns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;patterns&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This eliminates all allocations during matching.&lt;/p&gt;

&lt;h3&gt;
  
  
  6.2 Benchmark Results
&lt;/h3&gt;

&lt;p&gt;Environment:&lt;br&gt;
Intel Core i7-8850H 2.60 GHz&lt;br&gt;
.NET 10.0.5&lt;br&gt;
Windows 11&lt;br&gt;
BenchmarkDotNet v0.15.8&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Mean&lt;/th&gt;
&lt;th&gt;Allocated&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;PatternClassifier&lt;/td&gt;
&lt;td&gt;64 ns&lt;/td&gt;
&lt;td&gt;0 B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GlobMatcher&lt;/td&gt;
&lt;td&gt;261 ns&lt;/td&gt;
&lt;td&gt;0 B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RegexMatcher&lt;/td&gt;
&lt;td&gt;85 ns&lt;/td&gt;
&lt;td&gt;0 B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitIgnoreMatcher&lt;/td&gt;
&lt;td&gt;771 ns&lt;/td&gt;
&lt;td&gt;0 B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HybridMatcher&lt;/td&gt;
&lt;td&gt;742 ns&lt;/td&gt;
&lt;td&gt;0 B&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PatternTokenizer&lt;/td&gt;
&lt;td&gt;4.85 µs&lt;/td&gt;
&lt;td&gt;~9 KB (one-time)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Traversal (QueryFiles)&lt;/td&gt;
&lt;td&gt;2.0 ms&lt;/td&gt;
&lt;td&gt;~30 KB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Most allocations come from returning actual file paths, not from the engine itself.&lt;/p&gt;
&lt;h3&gt;
  
  
  6.3 Compilation Pipeline Allocations
&lt;/h3&gt;

&lt;p&gt;When the caller specifies a PatternKind explicitly, the engine skips classification and reduces allocations by ~400–500 bytes per pattern.&lt;/p&gt;

&lt;p&gt;Sub-lists for pattern kinds are allocated lazily.&lt;br&gt;
If only GitIgnore patterns are used, no Glob or Regex lists are created.&lt;/p&gt;


&lt;h2&gt;
  
  
  7. Getting Started
&lt;/h2&gt;
&lt;h3&gt;
  
  
  7.1 Installation
&lt;/h3&gt;

&lt;p&gt;Install the core package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;dotnet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Jeninnet.FileQuery&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Optional packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;dotnet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Jeninnet.FileQuery.CommandLine&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;dotnet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Jeninnet.FileQuery.DependencyInjection&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.2 Basic Usage
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FileQueryRuntime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FileQuery&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;From&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;@"C:\repo"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.3 Pattern-Based Filtering
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FileQuery&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;From&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;@"C:\repo"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                         &lt;span class="s"&gt;"**"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="s"&gt;"!src/**/*.cs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="s"&gt;"src/obj/**"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="s"&gt;"src/bin/**"&lt;/span&gt;
                     &lt;span class="p"&gt;)&lt;/span&gt;
                     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.4 Hybrid Pattern Mixing
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FileQuery&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;From&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;@"C:\repo"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UsingHybrid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                         &lt;span class="s"&gt;"**"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="s"&gt;"!*Global*.cs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                         &lt;span class="s"&gt;"r:^src/.*Engine.*"&lt;/span&gt;
                     &lt;span class="p"&gt;)&lt;/span&gt;
                     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IgnoreCase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                     &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.5 Async Enumeration
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ExecuteAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cancellationToken&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;ProcessFileAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cancellationToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.6 Dependency Injection
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddFileQuery&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FileScanner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IFileQueryEngine&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Scan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FileQuery&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;From&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.7 Command-Line Integration
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Usage: myapp --patterns "**;!*.exe" --gitignore "bin/;obj/"&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;CommandLinePatternOptions&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;rootCmd&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;RootCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"File scanner"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;opt&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetCommandOptions&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="n"&gt;rootCmd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;opt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;rootCmd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SetAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;patterns&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PatternBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FileQuery&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;From&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;patterns&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  8. Package Reference
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Package&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Jeninnet.FileQuery&lt;/td&gt;
&lt;td&gt;Core engine. GitIgnore, Glob, Regex. Zero-allocation matching.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Jeninnet.FileQuery.CommandLine&lt;/td&gt;
&lt;td&gt;Maps System.CommandLine results to pattern options.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Jeninnet.FileQuery.DependencyInjection&lt;/td&gt;
&lt;td&gt;Registers IFileQueryEngine for DI containers.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Supported Targets
&lt;/h3&gt;

&lt;p&gt;All packages target:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;net10.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Symbol packages and Source Link are enabled.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Design Goals and Non-Goals
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Goals
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Deterministic behavior&lt;/li&gt;
&lt;li&gt;Composable pattern dialects&lt;/li&gt;
&lt;li&gt;Zero-allocation hot path&lt;/li&gt;
&lt;li&gt;Streaming traversal&lt;/li&gt;
&lt;li&gt;Cross-platform normalization&lt;/li&gt;
&lt;li&gt;Strong architectural boundaries&lt;/li&gt;
&lt;li&gt;Extensible compiler and matcher pipeline&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Non-Goals
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;File content inspection&lt;/li&gt;
&lt;li&gt;Parallel traversal (planned for v1.1)&lt;/li&gt;
&lt;li&gt;Mutable filesystem operations&lt;/li&gt;
&lt;li&gt;Pattern caching across queries (planned for v1.1)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  10. Conclusion
&lt;/h2&gt;

&lt;p&gt;File discovery becomes complex at scale.&lt;br&gt;
Jeninnet.FileQuery solves this by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Providing deterministic rule evaluation&lt;/li&gt;
&lt;li&gt;Supporting mixed pattern dialects&lt;/li&gt;
&lt;li&gt;Ensuring high performance with zero allocations&lt;/li&gt;
&lt;li&gt;Offering a clean, extensible architecture&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Try it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;dotnet&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Jeninnet.FileQuery&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GitHub: github.com/TarekNajem04/Jeninnet.FileQuery&lt;br&gt;
NuGet: nuget.org/packages/Jeninnet.FileQuery&lt;br&gt;
License: MIT&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>patternmatching</category>
      <category>gitignore</category>
      <category>filesearch</category>
    </item>
  </channel>
</rss>
