Browse the docs

silk.text.glob.

Glob patterns: compile a pattern such as src/**/*.{silk,toml} and test paths against it, and inspect text for glob syntax.

When to use#

Use Pattern to select files by name, for example to filter a directory listing or a list of changed paths. To find matching files on a file system, use silk.system.glob_scan, which walks directories with this matcher.

Details#

A pattern is a list of segments separated by /:

  • * matches any characters within one segment, and ? matches one character that is not a separator.

  • ** as a whole segment matches any number of segments, including none, so a/**/b matches a/b and a/x/y/b.

  • [abc], [a-z], [!abc] and [^abc] match one character from, or not from, a set. A class can name / explicitly. POSIX named classes such as [:alpha:] are not expanded.

  • {a,b} matches one of its alternatives, which can nest. {1..9}, {01..10}, {9..1..2} and {a..g} match one value of a numeric or letter range, with padding and a step.

  • ?(a|b), *(a|b), +(a|b), @(a|b) and !(a|b) match zero or one, any number, one or more, exactly one, or none of the alternatives.

  • A leading ! inverts the result, and \ escapes the next character.

An unclosed class, brace or group, and a bare parenthesis, are literal text. The rules and the test expectations follow the picomatch package; isGlob and globParent follow is-glob and glob-parent.

Patterns and paths are text. Pattern and the inspection functions also have Bytes forms for host patterns and paths that are not UTF-8. Matching never normalizes a path.

Examples#

Test paths against one compiled pattern#

silk
import silk.text.glob { Pattern, Dots }
import silk.mem.allocator { Allocator, OutOfMemoryError }
import silk.core.effect { Effect }

effect fn check() -> i32 ! OutOfMemoryError ? &mut Allocator {
  let sources = run Pattern.make("src/**/*.{silk,toml}")
  let nested = run Pattern.matches(&sources, "src/driver/main.silk", Dots.Match)
  let other = run Pattern.matches(&sources, "docs/index.md", Dots.Match)
  let hidden = run Pattern.matches(&sources, "src/.cache/x.silk", Dots.Hide)
  if !nested.matches || other.matches || hidden.matches {
    return 1
  }
  return 0
}

effect fn exhausted(error: OutOfMemoryError) -> i32 {
  drop error
  return 2
}

pub fn main() -> i32 {
  let mut allocator = Allocator.systemAllocatorProvider()
  return run Effect.catchAll(check(), exhausted) |> Effect.provideMut<Allocator>(&mut allocator)
}

Import as glob with import silk.text.glob as glob.

Public declarations: 13.

Dots#

silk
pub enum Dots

How wildcards treat path segments that start with ..

Details#

Only wildcards (*, ?, **, classes and groups) are restricted. A pattern that spells a leading . literally, such as .github/*, matches such segments in every mode.

Match#

silk
Match

Wildcards match every segment, including hidden names and . and ...

SkipTraversal#

silk
SkipTraversal

Wildcards do not match the segments . and .., but do match other hidden names.

Hide#

silk
Hide

Wildcards match no segment that starts with ., so . and .. are excluded too.

MatchResult#

silk
pub struct MatchResult

The outcome of matching one path against a pattern.

Field matches#

silk
pub matches: bool

Whether the path matches. A leading ! negation in the pattern is already applied.

Field negated#

silk
pub negated: bool

Whether the pattern starts with an odd number of !, so matches is the inverted result.

Separators#

silk
pub enum Separators

Which bytes of a candidate path separate its segments.

Slash#

silk
Slash

Only / separates segments, as on POSIX hosts.

SlashOrBackslash#

silk
SlashOrBackslash

Both / and \ separate segments, as in Windows paths. The pattern itself still uses / between segments and \ as its escape.

Implementation Copy for MatchResult#

silk
impl Copy for MatchResult

Pattern#

silk
pub struct Pattern

A compiled glob pattern that can be matched against many paths.

When to use#

Compile a pattern once with Pattern.make and match it with Pattern.matches when you test more than one path. For a single test, matches compiles and matches in one call.

Details#

A Pattern owns a copy of its source and its compiled program, so the source can be dropped after Pattern.make returns. Matching runs in time proportional to the pattern size times the path length: groups and braces are compiled into one program, never expanded into every alternative.

Implementation Pattern#

silk
impl Pattern

Associated function make#

silk
pub effect fn make(pattern: string) -> Pattern
    ! OutOfMemoryError
    ? &mut Allocator

Compiles pattern.

Details#

Every pattern compiles. An unclosed class, brace or group is matched as literal text, as is a bare parenthesis.

Errors#

  • OutOfMemoryError if the Allocator cannot supply the compiled program.

Associated function makeBytes#

silk
pub effect fn makeBytes(pattern: &[u8]) -> Pattern
    ! OutOfMemoryError
    ? &mut Allocator

Compiles the pattern pattern, given as host bytes that need not be UTF-8.

Details#

Bytes that are not UTF-8 match themselves. ? and classes consume one Unicode scalar of the candidate.

Errors#

  • OutOfMemoryError if the Allocator cannot supply the compiled program.

Method sourceBytes#

silk
pub fn sourceBytes(self: &Self) -> &[u8]

Borrows the bytes the pattern was compiled from.

Method matches#

silk
pub effect fn matches(self: &Self, path: string, dots: Dots) -> MatchResult
    ! OutOfMemoryError
    ? &mut Allocator

Matches path against the pattern, with / as the only separator.

Details#

The path is matched as written: it is not normalized, so a/./b and a/b are different paths. dots decides whether wildcards match hidden segments.

Errors#

  • OutOfMemoryError if the Allocator cannot supply the scratch rows, which are proportional to the pattern size.

Method matchesBytes#

silk
pub effect fn matchesBytes(self: &Self, path: &[u8], dots: Dots) -> MatchResult
    ! OutOfMemoryError
    ? &mut Allocator

Matches the host path path, which need not be UTF-8, with / as the only separator.

Details#

A byte that is not part of valid UTF-8 counts as one character for ? and classes.

Errors#

  • OutOfMemoryError if the Allocator cannot supply the scratch rows.

Method matchesWith#

silk
pub effect fn matchesWith(
    self: &Self,
    path: string,
    dots: Dots,
    separators: Separators,
  ) -> MatchResult
    ! OutOfMemoryError
    ? &mut Allocator

Matches path against the pattern with the segment separators separators.

When to use#

Use it with Separators.SlashOrBackslash to match Windows paths such as src\main.silk against a pattern written with /.

Errors#

  • OutOfMemoryError if the Allocator cannot supply the scratch rows.

Method matchesWithBytes#

silk
pub effect fn matchesWithBytes(
    self: &Self,
    path: &[u8],
    dots: Dots,
    separators: Separators,
  ) -> MatchResult
    ! OutOfMemoryError
    ? &mut Allocator

Matches the host path path against the pattern with the segment separators separators.

Errors#

  • OutOfMemoryError if the Allocator cannot supply the scratch rows.

matches#

silk
pub effect fn matches(pattern: string, path: string) -> MatchResult
  ! OutOfMemoryError
  ? &mut Allocator

Compiles pattern and matches path against it once, with Dots.Match and / as the only separator.

When to use#

Use it for a single test. To test many paths, compile once with Pattern.make.

Errors#

  • OutOfMemoryError if the Allocator cannot supply the compiled program or scratch rows.

isGlobBytes#

silk
pub fn isGlobBytes(text: &[u8]) -> bool

Whether the host bytes text are a glob pattern by the rules of the is-glob package, version 4.0.3. An unclosed [ or { does not count, and neither does an escaped character.

hasExtglobPrefixBytes#

silk
pub fn hasExtglobPrefixBytes(text: &[u8]) -> bool

Whether the host bytes text contain an unescaped @(, +( or !(, whether or not it is closed.

detectGlobSyntaxBytes#

silk
pub fn detectGlobSyntaxBytes(text: &[u8]) -> bool

Whether the host bytes text contain any unescaped glob syntax: *, ?, [, {, a leading ! or an extglob prefix, even when a group is never closed.

globParentBytes#

silk
pub effect fn globParentBytes(pattern: &[u8]) -> Bytes
  ! OutOfMemoryError
  ? &mut Allocator

Returns the longest leading directory of the host bytes pattern that contains no glob syntax, with escapes removed, by the rules of the glob-parent package, version 6.0.2.

Details#

A pattern with no literal directory gives .. It looks only at the bytes, never at a file system, and keeps bytes that are not glob syntax as they are, also when they are not UTF-8.

Errors#

  • OutOfMemoryError if the Allocator cannot supply the result.

isGlob#

silk
pub fn isGlob(text: string) -> bool

Whether text is a glob pattern by the rules of the is-glob package, version 4.0.3.

When to use#

Use it to decide whether a user-written path should be matched as a pattern or used as written. An unclosed [ or { does not count, and neither does an escaped character.

hasExtglobPrefix#

silk
pub fn hasExtglobPrefix(text: string) -> bool

Whether text contains an unescaped @(, +( or !(, whether or not it is closed.

detectGlobSyntax#

silk
pub fn detectGlobSyntax(text: string) -> bool

Whether text contains any unescaped glob syntax: *, ?, [, {, a leading ! or an extglob prefix, even when a group is never closed.

When to use#

Use it to find text that a glob matcher would treat differently from a literal path. It is broader than isGlob, which also requires groups to be closed.

globParent#

silk
pub effect fn globParent(pattern: string) -> String
  ! OutOfMemoryError
  ? &mut Allocator

Returns the longest leading directory of pattern that contains no glob syntax, with escapes removed, by the rules of the glob-parent package, version 6.0.2.

When to use#

Use it to find the directory a scan for pattern must start from: src/**/*.silk gives src, and a pattern with no literal directory gives ..

Details#

It looks only at the text and never at a file system. Segments are separated by /.

Errors#

  • OutOfMemoryError if the Allocator cannot supply the result.

Category: Text.

Profiles: aarch64-apple-darwin, aarch64-unknown-linux-gnu, aarch64-unknown-linux-gnu-no-libc, x86_64-unknown-linux-gnu, x86_64-unknown-linux-gnu-no-libc, wasm32-unknown-unknown, wasm32-wasip1, wasm32-wasip2, x86_64-pc-windows-msvc, wasm64-unknown-unknown.

View the source of this page