.docname {Listing files}
.include {docs}

The **`.listfiles {path} {directories?} {recursive?} {pattern?} {fullpath?} {sortby?} {order?}`** .docslink {quarkdown-stdlib/com.quarkdown.stdlib.module.Data/listfiles.html} function returns an [iterable](iterable.qd) of entries from a directory.

By default, the result is an *unordered* collection of absolute paths to the immediate children of the directory at `path`. The path is interpreted relative to the main source file's location, or as an absolute path. Use a slash (`/`) as the path separator, regardless of the operating system.

> For the following examples, assume the following directory structure:
> 
> .filetree
>   - assets
>     - folder
>       - file1.txt
>       - file2.txt
>       - file3.md
>       - subfolder
>         - nested-file1.txt
>         - nested-file2.txt
>         - nested-file3.md

.examplemirror
    .listfiles {assets/folder} fullpath:{no}

The result is an iterable value, that can be passed to [`.foreach`](loops.qd).

.examplemirror
    .foreach {.listfiles {assets/folder} fullpath:{no}}
        name:
        **File:** .name

## Full paths

By default, each entry is returned as its absolute path:

.examplemirror
    .listfiles {assets/folder}

This can be used in combination with [file data](file-data.qd) functions to read file content:

.examplemirror
    .foreach {.listfiles {assets/folder} directories:{no}}
        path:
        Content of .path::filename::codespan is .path::read::codespan

## Recursive traversal

Setting `recursive:{yes}` walks every nested subdirectory and returns all descendants, not just the immediate children.

.examplemirror
    .listfiles {assets/folder} recursive:{yes} fullpath:{no}

The root directory itself is never included in the result.

## Filtering by name

Passing a `pattern` keeps only entries whose **bare file name** matches the given regular expression. The pattern always applies to the file name alone (never to a directory path), regardless of `fullpath` or `recursive`.

.examplemirror
    .listfiles {assets/folder} pattern:{.*\.txt} recursive:{yes} fullpath:{no}

## Excluding directories

Set `directories:{no}` to keep only files in the result, omitting subdirectories from the output:

.examplemirror
    .listfiles {assets/folder} directories:{no}

## Sorting

By default, the order of the result is unspecified, and the returned iterable is unordered. Picking a sort criterion via `sortby` switches the result to an ordered iterable:

| Value          | Effect                                                                  |
|----------------|-------------------------------------------------------------------------|
| `none`         | No sorting; the result is an unordered collection (default).            |
| `name`         | Sort by file name, using a human-friendly alphanumeric comparator.      |
| `lastmodified` | Sort by the file's last-modified timestamp.                             |

The `order` parameter then chooses the direction:

- `ascending` (default): smallest first (A-Z, oldest first).
- `descending`: largest first (Z-A, newest first).

.examplemirror
    .listfiles {assets/folder} sortby:{name} order:{descending} fullpath:{no}

## Bulk inclusion of sources

Because the result is iterable, it composes naturally with [`.includeall`](including-other-quarkdown-files.qd):

.example
    This loads every file under `chapters/` in alphabetical order:

    ```markdown
    .listfiles {chapters} sortby:{name}::includeall
    ```

## Permissions

`.listfiles` follows the same permission model as the other file-reading functions:

- Listing under the project directory requires the `project-read` [permission](cli-compiler.qd#available-permissions) (granted by default).
- Listing outside the project directory requires `global-read` (opt-in).
