pub struct Config {Show 44 fields
pub root_dir: PathBuf,
pub explicit_hidden_dirs: Vec<PathBuf>,
pub no_symlink_mounts: bool,
pub host: IpArray,
pub port: u16,
pub static_folder: String,
pub markdown_extensions: Vec<String>,
pub theme: String,
pub index_file: String,
pub ignore_dirs: Vec<String>,
pub ignore_globs: Vec<String>,
pub watcher_ignore_dirs: Vec<String>,
pub oembed_timeout_ms: u64,
pub oembed_cache_size: usize,
pub media_cache_size: usize,
pub template_folder: Option<PathBuf>,
pub sort: Vec<SortField>,
pub build_concurrency: Option<usize>,
pub transcode: bool,
pub skip_link_checks: bool,
pub link_tracking: bool,
pub tag_sources: Vec<TagSource>,
pub relationship_tracking: bool,
pub relationship_types: Vec<RelationType>,
pub build_tag_pages: bool,
pub sidebar_style: String,
pub sidebar_max_items: usize,
pub graph_depth: usize,
pub flashcards_concentric_threshold: f64,
pub flashcards_progress_indicators: bool,
pub gui_menu_bar: MenuBarVisibility,
pub title_prefix: String,
pub title_suffix: String,
pub incomplete_markers: Vec<String>,
pub mark_incomplete: Option<bool>,
pub tasks_enabled: bool,
pub review_enabled: bool,
pub tasks_stamp_done: bool,
pub tasks_default_include: IncludeFilter,
pub tasks_ignore_globs: Vec<String>,
pub edit_enabled: bool,
pub edit_token_hash: Option<String>,
pub edit_require_token_on_loopback: bool,
pub upload_max_bytes: usize,
}Fields§
§root_dir: PathBufHidden (leading-dot) directories the user named on the command line,
as root-relative paths. Exempted from the scanner’s leading-dot rule —
see explicit_hidden_dirs for why, and crate::repo::should_ignore
for where.
serde(skip), like nothing else in this struct: it is derived at
startup from the invocation, so .mbr/config.toml and MBR_* must not
be able to name it. A repository that could set it would be declaring
which of its own hidden directories the operator’s scan walks into,
which is the config file asserting a fact about the command line.
no_symlink_mounts: boolThe operator’s kill switch for read-only symlink mounts
(crate::vault::MountPolicy): --no-symlink-mounts or
MBR_NO_SYMLINK_MOUNTS. When set, a link out of the repository is
refused exactly as before mounts existed.
serde(skip) for the reason explicit_hidden_dirs is: the switch
protects the operator from the repository, so the repository’s own
.mbr/config.toml must not be able to turn mounts back on. Skipping it
also keeps figment’s MBR_* layer from reading it (that layer cannot be
told apart from the file by the time Config is extracted), so
Config::read reads the environment variable itself
(no_symlink_mounts_from_env) and the CLI sets it afterwards. Negative
on purpose: a skipped field deserializes to false, which must mean
“mounts on” — the default.
host: IpArray§port: u16§static_folder: String§markdown_extensions: Vec<String>§theme: String§index_file: String§ignore_dirs: Vec<String>§ignore_globs: Vec<String>§watcher_ignore_dirs: Vec<String>Directories to ignore in the file watcher. These directories will not trigger live reload events when files inside them change.
oembed_timeout_ms: u64Timeout in milliseconds for fetching oembed/OpenGraph metadata from URLs. If the fetch doesn’t complete in time, falls back to a plain link. Set to 0 to disable oembed fetching entirely (uses plain links for all URLs except YouTube and Giphy which are embedded without network calls).
oembed_cache_size: usizeMaximum size in bytes for the oembed cache. The cache stores fetched page metadata to avoid redundant network requests when rendering multiple files. Set to 0 to disable caching entirely. Default: 2MB (2097152 bytes).
media_cache_size: usizeMaximum size in bytes for the media metadata cache (server/GUI mode).
Holds dynamically generated video/PDF metadata: cover images (JPEG
payloads), chapters and captions. Sized separately from
oembed_cache_size because a single cover can be hundreds of kilobytes,
so the 2 MB oembed budget evicted covers almost immediately — and
turning oembed caching off must not turn media caching off with it.
Set to 0 to disable caching entirely. Default: 64MB (67108864 bytes).
template_folder: Option<PathBuf>Optional template folder that overrides the default .mbr/ and compiled defaults. Files found here take precedence; missing files fall back to compiled defaults.
sort: Vec<SortField>Sort configuration for file listings. Supports multi-level sorting by any field. Default: sort by title (falling back to filename), ascending, string comparison.
build_concurrency: Option<usize>Build concurrency: number of files to process in parallel during static builds. None = auto-detect based on CPU cores (2x cores, capped at 32).
transcode: boolEnable dynamic video transcoding to serve lower-resolution variants (720p, 480p). Only active in server/GUI mode. Videos are transcoded on-demand as HLS segments and cached in memory. Default: false (disabled).
skip_link_checks: boolSkip internal link validation during static site builds. When true, the build will not check if internal links point to valid files. Default: false (link checking enabled).
link_tracking: boolEnable bidirectional link tracking (backlinks). When enabled, generates links.json endpoints/files for each page with inbound/outbound links. Server mode: lazy grep-based discovery on-demand with caching. Build mode: eager collection during render, inverted for inbound links. Default: true (enabled).
tag_sources: Vec<TagSource>Tag sources configuration for extracting tags from frontmatter fields. Supports dot-notation for nested fields (e.g., “taxonomy.tags”). Default: extract from “tags” field.
relationship_tracking: boolEnable typed relationship tracking (named frontmatter relationships). When enabled, per-note relationships are exposed via links.json and site.json, and rendered in the info panel. Default: true (enabled). Cheap when unused.
relationship_types: Vec<RelationType>Relation types configuration for typed note relationships. Declares symmetric / inverse-pair semantics and display labels. Default: genealogy defaults (parent↔child, spouse, sibling).
build_tag_pages: boolGenerate tag landing pages during static site builds. When enabled, creates /{source}/{value}/ pages for each tag value and /{source}/ index pages listing all tags. Default: true (enabled).
Sidebar navigation style.
- “panel”: Three-pane modal browser (default, existing mbr-browse)
- “single”: Persistent single-column sidebar (new mbr-browse-single)
Maximum items per section in sidebar navigation. Default: 100. Only applies when sidebar_style = “single”.
graph_depth: usizeDepth (hops) of the link/relationship neighborhood shown in the sidebar mini graph. Range 1-5. Default: 2.
flashcards_concentric_threshold: f64Share of a pass’s first answers that must be Good or Easy before the flashcard deck’s Concentric mode folds two more cards into the stack. Range: greater than 0, at most 1. Default: 0.7.
flashcards_progress_indicators: boolWhether flashcard notes show review-progress indicators in the reading view (a rating-coloured border on reviewed questions, a pie per heading). Default: true.
Whether the GUI window shows the native menu bar. "auto" (default)
follows the platform convention — hidden on Linux, shown on macOS and
Windows; "always" and "never" pin it.
GUI mode only, and only Linux reads it; see MenuBarVisibility for
why. On Linux, F10 toggles the bar at runtime unless this is "never".
title_prefix: StringText to prepend to all page titles (e.g., “My Site: “). Default: empty string (no prefix).
title_suffix: StringText to append to all page titles (e.g., “ | My Site“). Default: empty string (no suffix).
incomplete_markers: Vec<String>Markers that flag work as incomplete, matched anywhere in a line and
wrapped in <span class="mbr-incomplete">…</span>. A paragraph,
heading, list item, or table cell whose first text starts with one is
wrapped whole. Never matched inside code, image alt text, link
destinations or frontmatter.
Default: ["TK", "TODO", "FIXME", "XXX"].
mark_incomplete: Option<bool>Enable incomplete-block marking. None = mode default (on for
server/GUI, off for static build). CLI flags
--mark-incomplete / --no-mark-incomplete force a value.
tasks_enabled: boolEnable the task browser (POST /.mbr/tasks and the task panel).
Server/GUI only: the tasks index is built from live files, so static
builds never expose it regardless of this value. When disabled, the
endpoint returns 404 and the frontend does not offer the panel.
Default: true (enabled). CLI flag --no-tasks disables it.
review_enabled: boolEmit data-mbr-line="{1-based source line}" on block-level elements, so
a frontend feature can anchor a text selection back to file.md:LINE.
Server/GUI only: a static build, the CLI and QuickLook pass
ReviewLines::Omit unconditionally rather than reading this, because an
anchor is only meaningful against a live file. Setting it in a
.mbr/config.toml therefore has no effect on mbr -b.
Default: true (enabled). CLI flag --no-review disables it.
Deliberately absent from validate: a bool has no invalid state, and an
entry there would be a line of code asserting true || false.
tasks_stamp_done: boolMaintain the @done(YYYY-MM-DD HH:MM) annotation when a task’s status
is toggled through POST /.mbr/task: stamp it on completion, remove it
when the task is reopened or canceled.
Turn it off to have that endpoint rewrite nothing but the marker byte,
leaving any @done(...) exactly as its author wrote it. Nothing else in
mbr ever writes to a markdown file on its own.
Default: true (stamp).
tasks_default_include: IncludeFilterWhich entries the task panel’s Show filter starts on: "tasks"
(checkboxes), "markers" (TODO:-style lines), or "all".
Only the starting position — the user can change it in the ⚙ popover for
the life of that panel, and the panel widens to all by itself when the
configured default returns nothing (see mbr-tasks-panel.ts). That
fallback is why the default is the narrow "tasks" rather than "all":
a repository with no checkboxes at all still opens on its markers, and
one with both is not made to read them interleaved.
Typed as the real IncludeFilter rather than a String so serde
rejects a typo at startup, the way an out-of-range graph_depth is.
Config file and MBR_TASKS_DEFAULT_INCLUDE only; there is no CLI flag.
Default: "tasks".
tasks_ignore_globs: Vec<String>Glob patterns whose matching files are left out of the task index.
Each pattern is matched against a markdown file’s repository-relative
path, always /-separated (docs/templates/onboarding.md). A file that
matches any pattern contributes nothing to the task browser: no tasks, no
folder in the folder pane, no counts.
The use case is a folder of checklist templates, which is full of deliberately unchecked boxes that are nobody’s actual work. Rendering is untouched — those files stay readable and their checkboxes stay clickable, because in-document checkboxes exist whether or not the task browser does.
Patterns name files, not folders, so exclude a folder’s contents
(templates/**) rather than the folder (templates, which matches
nothing). Default: empty, so nothing is excluded.
Config file and MBR_TASKS_IGNORE_GLOBS only; there is no CLI flag.
edit_enabled: boolEnable the in-browser markdown editing endpoints in server/GUI mode:
/.mbr/raw + /.mbr/edit (read/save an existing file) and the
file-management endpoints /.mbr/create (new file), /.mbr/move
(move/rename with repo-wide link rewrite), and /.mbr/mkdir (new
folder).
The default depends on the mode: on in the GUI (Config::read_for_gui,
a private window on loopback), off everywhere else (Config::read:
mbr -s must be asked). A value in .mbr/config.toml or
MBR_EDIT_ENABLED wins over either default; --edit / --no-edit win
over everything. Static builds never edit, whatever this says.
edit_token_hash: Option<String>Argon2 PHC hash of the shared editing token. Required when editing is
enabled on a non-loopback host; requests must present the matching token
as Authorization: Bearer <token>. Generate with
mbr --generate-edit-token. Never sent to the frontend.
edit_require_token_on_loopback: boolRequire the editing token even for loopback callers. Off by default: loopback edits are allowed without a token (still CSRF-protected).
upload_max_bytes: usizeMaximum size in bytes for a single asset uploaded via /.mbr/upload
(the in-browser editor’s image uploader). Requests with a larger body are
rejected with 413 Payload Too Large. Default: 25 MiB (26214400 bytes).
Implementations§
Source§impl Config
impl Config
Sourcepub fn read(search_config_from: &Path) -> Result<Self, MbrError>
pub fn read(search_config_from: &Path) -> Result<Self, MbrError>
Loads configuration for the repository containing search_config_from.
Layers, lowest precedence first (figment’s merge gives the later
provider precedence):
- Compiled-in defaults (
Config::default) .mbr/config.tomlin the discovered rootMBR_*environment variables
Environment variables deliberately win over the config file: the file ships inside the markdown repository, so an operator serving a repo they did not author must be able to override it from the outside.
Sourcepub fn read_for_gui(search_config_from: &Path) -> Result<Self, MbrError>
pub fn read_for_gui(search_config_from: &Path) -> Result<Self, MbrError>
Config::read for the GUI: the same layers over
Config::gui_defaults instead of Config::default, so in-browser
editing is on unless .mbr/config.toml or MBR_EDIT_ENABLED says
otherwise.
Every GUI read must come through here — the first folder and every folder opened later in the window — or the default would depend on how the folder was opened.
The default yields to the network check Config::validate enforces:
when the configured host is not loopback and no edit_token_hash is
set, an editing default that nobody asked for is dropped (with a WARN)
rather than failing the launch. An explicit edit_enabled = true
there still fails, exactly as in Config::read.
Sourcepub fn gui_defaults() -> Self
pub fn gui_defaults() -> Self
The compiled-in defaults the GUI starts from: Config::default with
edit_enabled on. The one place the modes’ defaults differ.
Sourcepub fn read_at_root(root_dir: &Path) -> Result<Self, MbrError>
pub fn read_at_root(root_dir: &Path) -> Result<Self, MbrError>
Config::read for a repository whose root is already known: no
upward search, so no ancestor’s marker can become the root and no
ancestor’s .mbr/config.toml is ever opened.
For an embedder whose access grant is the repository — the iOS app,
where a picked folder is the whole sandbox grant and its ancestors are
outside it. Everything else (environment overrides, validation) is
exactly Config::read’s.
Sourcepub fn validate(&self) -> Result<(), ConfigError>
pub fn validate(&self) -> Result<(), ConfigError>
Validates the configuration values.
Checks that numeric configuration options are within valid bounds:
port: Must be 1-65535 (port 0 means “auto-assign”, which isn’t useful for display)sidebar_max_items: Must be > 0graph_depth: Must be between 1 and 5flashcards_concentric_threshold: Must be in (0, 1]build_concurrency: If set, must be > 0static_folder: Must stay insideroot_dir, or land under a directory at most [MAX_STATIC_FOLDER_ASCENT] levels above it (seeConfig::validate_static_folder)tasks_ignore_globs: Every pattern must compile
Note: oembed_cache_size of 0 is valid (disables caching).
Sourcepub fn editing_needs_token(&self) -> bool
pub fn editing_needs_token(&self) -> bool
Editing is on, the host is not loopback, and there is no token hash:
the combination Config::validate refuses, because the Host gate
alone cannot keep a remote caller out.
Trait Implementations§
Source§impl<'de> Deserialize<'de> for Config
impl<'de> Deserialize<'de> for Config
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Auto Trait Implementations§
impl Freeze for Config
impl RefUnwindSafe for Config
impl Send for Config
impl Sync for Config
impl Unpin for Config
impl UnsafeUnpin for Config
impl UnwindSafe for Config
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
Source§fn fg(&self, value: Color) -> Painted<&T>
fn fg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the foreground set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like red() and
green(), which have the same functionality but are
pithier.
§Example
Set foreground color to white using fg():
use yansi::{Paint, Color};
painted.fg(Color::White);Set foreground color to white using white().
use yansi::Paint;
painted.white();Source§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
Source§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
Source§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
Source§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
Source§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
Source§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
Source§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
Source§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
Source§fn bg(&self, value: Color) -> Painted<&T>
fn bg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the background set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like on_red() and
on_green(), which have the same functionality but
are pithier.
§Example
Set background color to red using fg():
use yansi::{Paint, Color};
painted.bg(Color::Red);Set background color to red using on_red().
use yansi::Paint;
painted.on_red();Source§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
Source§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
Source§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
Source§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
Source§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
Source§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
Source§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
Source§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
Source§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
Source§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
Source§fn attr(&self, value: Attribute) -> Painted<&T>
fn attr(&self, value: Attribute) -> Painted<&T>
Enables the styling Attribute value.
This method should be used rarely. Instead, prefer to use
attribute-specific builder methods like bold() and
underline(), which have the same functionality
but are pithier.
§Example
Make text bold using attr():
use yansi::{Paint, Attribute};
painted.attr(Attribute::Bold);Make text bold using using bold().
use yansi::Paint;
painted.bold();Source§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
Source§fn quirk(&self, value: Quirk) -> Painted<&T>
fn quirk(&self, value: Quirk) -> Painted<&T>
Enables the yansi Quirk value.
This method should be used rarely. Instead, prefer to use quirk-specific
builder methods like mask() and
wrap(), which have the same functionality but are
pithier.
§Example
Enable wrapping using .quirk():
use yansi::{Paint, Quirk};
painted.quirk(Quirk::Wrap);Enable wrapping using wrap().
use yansi::Paint;
painted.wrap();Source§fn clear(&self) -> Painted<&T>
👎Deprecated since 1.0.1: renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
fn clear(&self) -> Painted<&T>
renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
Source§fn whenever(&self, value: Condition) -> Painted<&T>
fn whenever(&self, value: Condition) -> Painted<&T>
Conditionally enable styling based on whether the Condition value
applies. Replaces any previous condition.
See the crate level docs for more details.
§Example
Enable styling painted only when both stdout and stderr are TTYs:
use yansi::{Paint, Condition};
painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);